Welcome! This tutorial was designed specifically for developers, who are completely new to MPS and prefer a guided tour through the MPS landscape. You will walk the beaten path one step at a time, following clear marks that show you where to go next. The information is structured so that you progress from simpler concepts to the more involved ones and at the end of the journey you'll understand MPS and will be able to use it effectively on your projects.
tip
Hi, my name is Václav and I've created this tutorial for you. The tutorial is a living creature that I constantly maintain and evolve to make it better serve its purpose - to help you learn how to design languages with MPS.
You can help me on that mission - if you spot a mistake, hit a road-block or become confused - let me know. I'll be very grateful, if you leave a comment or file a YouTrack issue for me. Thank you.
We admit that there are easier tasks in the world than learning MPS. Language design is a complex domain and projectional editing needs some getting used to. It helps a lot if you have prior experience with DSLs or language workbenches, but it is not necessary for understanding this tutorial. Just expect more bumps on the road. There certainly will be a lot of them - partly also because MPS has its own problems and bugs. So you are in for a tough experience that may take quite a big amount of your time.
Bear in mind that many have walked through here before and succeeded. If you persist you'll be rewarded - you'll become a language designer who can prepare custom-tailored DSLs, integrate them into projects and develop high-value software with them.
So, take on good shoes, lace them tight and start going ...
Step 1 - Why MPS
Raw time estimate - 15 minutes
Let's start with some motivation for learning MPS.
First of all, check out a two-minute overview video about MPS - Why JetBrains MPS, so you can assess whether this tool offers something that you need on your projects.
Our new VoiceMenu demo application has been created to give people coming from different domains of expertise a quick understanding of the potential of MPS. Watch this short video.
Try MPS right now! Download it from the MPS website and proceed to a hands-on course that we prepared for you. You will join a free, guided on-line tutorial that will let you instantly play with MPS, write some code, improve language definition bits and see how it all works. The focus is on you trying things out so that you can assess whether MPS is for you and what to expect from it. Minimum time is spent explaining the theory. There's always time to dive deep into MPS later, once you know it is the right tool for you. Now, head to The JetBrains MPS for the impatient and learn you some MPS.
Step 3 - MPS from the programmer's perspective
Raw time estimate - 15 minutes
tip
In step 2 you figured out the key principles of MPS and assesed its applicability to your domain. I'm happy to see you want to learn more. Now, with you motivated we can gradually introduce some theory and start turning you into an MPS language designer.
Plain reading about MPS will never teach you as much as trying it for real yourself. You might have done this already, but if not, grab MPS from the download site and install it. With MPS installed you will be able to continue on the Fast Track.
Configure the editor
We are all different. If the default settings that MPS comes with do not fit your habits, you can always change them in the Preferences (MacOs, press CtrlAlt0S) or Settings (Windows, press CtrlAlt0S, or go to the menu File -> Settings). One of the most likely settings to change is the font size in the Editor -> General section:
Be safe, wear the seatbelts
Knowing keyboard shortcuts turns good developers into great ones. As you learn MPS you will internalize various key combinations that trigger useful MPS functionalities. There's one key combination that you should remember from the very beginning, though - Ctrl0Z. Once again - Ctrl0Z. It is the Undo action. Whenever you either intentionally or by mistake do something wrong and you want do get back to functional code, turn to Ctrl0Z.
A quick ride
Since we programmers like trying things, how about taking the MPS editor for a simple test ride first? You may get the first impressions instantly, if you start MPS and open the Robot Kaja sample project. This project defines an artificial language to command a virtual robot. The robot can move within a rectangular area, drop and collect marks and check the surrounding cells for walls and marks. You write Scripts using the built-in commands as well as new commands that you create on the fly. When you run the script a simulator written in Java is started to visualize the execution of your program.
To open the project, start your fresh MPS, click the Open Sample Project button and pick robot_Kaja . The sample projects have been installed into your HOME/MPSSamples folder.
If you like the video and if you are serious about learning MPS, you may consider enrolling into the MPS Introductory Online Training. It will give you thorough guidance through numerous hands-on exercises and you will be able to discuss your progress and questions with a live trainer.
tip
Do not worry to break things while playing with the MPS samples. You can always delete the HOME/MPSSamples folder and MPS will re-create it the next time you click the Open Sample Project button. Experiment, experiment, experiment!
Step 4 - Study the fundamentals
Raw time estimate - 25 minutes
Watch this video, now! - The first run. It gives you the essential information into how MPS is organised, how it works and how users are supposed to interact with it.
If you are carefully evaluating MPS there must be many questions popping up in your head while watching videos or reading stories about MPS usages. I believe that some of these questions have already been answered in the MPS FAQ page. Check it out,
Read a gentle introductory article on MPS fundamentals by Mikhail Barash. This is definitely worth your time at this moment, since you will understand all the principles as soon as you read the article.
Stop for a minute now and skim through a short page listing the essential terms like node, Concept, AST in order to understand better the terminology used down the line.
warning
Before you proceed, please bookmark the MPS Glossary page and come back to it frequently, until you get a good command of the vocabulary that the MPS community uses.
Step 5 - Projectional editing tips and tricks
Raw time estimate - 25 minutes
Before you continue, you should probably get to know the most distinct feature of MPS - the projectional editor. Check out a video that explains all the differences between traditional textual editors and the MPS projectional editor and lists the numerous benefits of this approach.
When editing code in MPS you will run into situations when your coding habits interfere with the projectional nature of the MPS editor. I'm actually pretty confident that you have already discovered such surprises during your experiments. Code in MPS is not text, but instead it is a projection of the abstract syntax (AST). This gives several benefits to language designers and, at the same time, makes the editing experience slightly different and more-restrictive than in the commonplace text editors. This may or may not be considered to be an advantage, nevertheless, there is a learning curve to projectional editing. In general, in projectional code you more rely on the assistance of the editor. Code-completion, block selection and intention actions should become your close friends in order to become an efficient projectional coder. There's a good and a bad side to it:
good - in less than a week of programming in the MPS editor people typically get back to their full speed of coding they experienced before in text-based IDEs
bad - projectional editing is highly addictive and you may find text-based editors less compelling and less helpful than you thought they'd been before
tip
We summarized the core essential tips on how to leverage the projectional editor. Refer to the Commanding the editor page and keep it ready when making your first steps in MPS. Although you do not have to memorise all the keyboard shortcuts immediately, they will certainly make your coding more efficient once you start developing your own projects.
To begin with, try to memorize and use these five essential keyboard shortcuts:
Ctrl0Z - Undo
CtrlSpace - Code completion
AltEnter - Intentions
Ctrl0↑ - Expand code selection
Ctrl0↓ - Shrink code selection
Since we are now about to get really serious about designing languages and I will need your full commitment to learning MPS, if you still hesitate, whether to invest more of your time into exploring MPS, you may consider checking out the following materials before proceeding. If you are already convinced, just rush to the next step.
JetBrains MPS is an efficient and reliable development tool that has been adopted by software vendors on both commercial and academic projects. MPS-based DSLs have been adopted in wide range of domains, such as legislation modelling, electrical engineering, insurance industry, embedded software, medicine systems, bio-informatics and data analysis. The "The "When MPS" section of the MPS home page" lists several of the successful projects and gives a high-level overview of the technology used.
Again, this video has been borrowed from the MPS Introductory Online Training course to give you a taste of this paid course that JetBrains provides.
As you go through the video, pause frequently and look around the sample project yourself. This way you will understand a typical language structure and see the relationships between its individual parts.
At this point you should understand that language definition consists of several aspects. Some of these are mandatory, some are optional:
Structure - Defines the kinds of nodes (called Concepts) that may be used in user models. Each node in the program (model) refers to its concept. Concepts specify, which properties , children and references nodes may have. Concepts can extend other Concepts and implement ConceptInterfaces.
Constraints - Restricts the relationships between nodes as well as the allowed values for properties beyond the rules defined in Structure . Constraints typically define:
the target scope for references (a collection of allowed nodes a reference can point to)
situations, in which a node can be a child/parent/ancestor of another node
allowed values for properties
property accessor methods (getters and setters)
Behavior - Just like classes in OOP hold methods, Concepts may define methods and static methods that can be invoked on nodes in a polymorphic way. Nodes thus carry behaviour alongside their properties and relationships.
Editor - Instead of defining a parser that would translate code from an editable form (i.e. text) into the tree-like structure that a computer could manipulate, MPS offers the concept of projectional editor, which let's the user edit the AST directly. The Editor aspect enables language designers to create a UI for editing their concept concepts.
Actions - Since the MPS editor manipulates the underlying AST directly, some editing actions, such as copy-paste or replacing one node with another one translate into non-trivial AST changes. The Actions aspect holds definitions of such customised AST transformations.
Intentions - All modern IDEs assist developers with instant code manipulating action available under a handy key-shortcut (AltEnter in MPS). Language authors can define such little code transformations for their languages in the Intentions aspect.
Typesystem - Language that need to type-check their code need to provide type-system rules. The MPS type-system engine will evaluate the rules on-the-fly, calculate types for nodes and report errors, wherever the calculated type differs from the expectations. So called checking rules may additionally be defined to verify non-typesystem assertions about the model.
Dataflow - The ability to understand the flow of values and the flow of control through language constructs helps languages report issues such as unreachable code or potential null-pointer error . Language designer can leverage the Dataflow aspect to define the flow for each concept, which MPS will then use to calculate the dataflow for the whole program.
Generator - Models written in one or more languages get ultimately translated into runnable code in some target general-purpose language and platform, such as Java. Along the way models get gradually transformed so that repeatedly concepts get replaced with concepts from a lower level of abstraction until the bottom-line level is reached. The rules for translating concepts and their proper ordering is defined in the Generator aspect.
TextGen - During code generation after the Generator has reached the bottom-line AST representation, the TextGen phase kicks in and translates all nodes in the model into their textual representation and saves the resulting textual source files on disk.
Step 7 - Shapes tutorial
Raw estimate - 2 hours
note
Beware, you are entering a "Suck Zone" here. We're happy to see you here, but you need to be warned that the road gets quite steep and more bumpy as you progress through the Shapes tutorial and the following exercises. No wonder, you'll be doing real language design now and you'll be left intentionally on your own to implement parts of the languages. If things do not work out for you, relax, step back and try again. Sometimes the problem may be as small as a semicolon missing from a selection or a method placed in a wrapper class instead of an anonymous inner class. Remember, you can always ask for assistance on the forum and we'll help you get back on track.
The Shapes Tutorial gives you an opportunity to quickly create your own language. Check out the MPS entry-level Shapes Tutorial and build a language that enables non-programmers to build scenes of graphical shapes.
tip
We've collected links to useful documentation sources at the bottom of this page. Feel free to consult them whenever you need some additional information.
Step 8 - Calculator tutorial
Raw time estimate - 8 hours
Now you must be curious to find out more details about language design in MPS, right? Having given you all the fundamental information and some level of experience, the introductory tutorials should have left you in a good position to dive deeper and build a sample language all the way from the ground up. The Calculator tutorial will guide you through the process of language creation. You start with an empty project and end up with a language to build Java Swing-based visual applications. Try it out and have fun.
The Calculator tutorial in JavaScript
As an illustration that MPS is not limited to generating Java, we've prepared a similar Calculator sample project - CalculatorJS, which generates an HTML page and a JavaScript program to hold the computation. You may check it out on GitHub.
Step 9 - Managing dependencies and imported languages
Raw time estimate - 30 minutes
As you must have noticed already, MPS lets you manage dependencies between models as well as import languages. Since it is essential to understand these, read a user guide chapter on getting the dependencies right . It will teach you the distinction between dependencies and imported languages and how to set/manage them.
Step 10 - The Garage project tutorial
Raw time estimate - 5 hours
The Calculator tutorial should have left you with good overall knowledge of language design. Now it is time for a more thorough exercise. The garage project will have you create several interconnected languages, package them as reusable plugins and stack languages one above the other. To handle the complexity of this tutorial, we leverage the Cogniterra platform for online education. Enrol in the free MPS Elementary Course.
Got questions?
As with learning any new technology, you may have questions you need help with. Don’t worry, we’ve got your back! There are a few options available for getting answers to your questions:
For questions that aren’t urgent, you can use our forum.
You can get quick answers by asking your questions on the Community Slack channel. We have a great community that is always willing to help newcomers.
You can also attend the free MPS Office hours that experienced members of our community hold.
Reviewing the progress
Congratulations! By completing the above tutorials and exercises you've made a serious dent into the language design world. Your knowledge and command of MPS could now be qualified somewhere above the Advanced beginner stage of the Dreyfus model of skill acquisition. This is definitely a good time to celebrate and perhaps also to let us know about you success.
Moving up the ladder
The next stage in the Dreyfus model of skill acquisition is Competent. Once you reach that stage you'll be able to work on your own without concrete guidelines and supervision. But for this to happen, you'll need to spend more time solving various problems with MPS. If you already have an idea of a language to implement, go ahead and do it. If not, try to come up with a useful little language. You could as well try to re-implement one or more of the MPS samples and then see how closely you got. Or just pick a sample as the starting point and move it forward - add language features, implement a generator, add type-system rules, polish the editing experience - whatever feels like the right challenge for you.
Additionally, you should try these in order to become Competent in MPS and language design:
Apply for the MPS Advanced Course by JetBrains. Both online and on-site options are available. In the advanced course you will learn about:
making the editors fluent, intelligent and convenient to use
The Generator tutorial will teach you more subtle options that the MPS generator offers. You will learn about the different types of macros, generator scripts, utility models and more.
Become active in the MPS community and try to answer the forum questions of people that walk behind you on the same path to MPS mastery
After becoming Competent you should definitely continue gaining experience. The more you work with MPS and the more divert your projects are, the faster you'll be moving up on the Dreyfus model of skill acquisition scale. If you set yourself a goal to become Proficient and ultimately an Expert in MPS, you might consider trying:
Although there's not much detailed documentation to guide you at this experience level and you'll have to be self-driven most of the time, we'll always be happy to discuss, advise and cooperate with you.
Documentation sources
Here's a list of documentation sources that you may need on your path to MPS mastery
Books
Fabien Campagne wrote The MPS Language Workbench: Volume I and Volume II books, which you can purchase both electronically and as paper-back. Although the books cover an older version of MPS, most of their contents is still relevant. Get them here.
Academic papers
The publications page collects all relevant papers about MPS and the related field.
Cookbooks
The get slightly simplified practical information as well as some tips and tricks on individual aspects of language design, you may try some of the cookbooks.
Finding your way out - a brief collection of guidelines that should help you move forward when you get stuck somewhere.
User guides
A full-blown reference documentation provides exhaustive information on MPS. Check out the Language designer's User Guide.
Heavy Meta
Comprehensive tutorials and information about how to build and design your languages created by a JetBrains MPS partner. Heavy Meta TV hosts an in depth tutorial for JetBrains MPS of about 20 hours. Definitely check out the Heavy Meta tutorial.
Screencasts
Over time the MPS team has created a large collection of screen-casts covering many aspects of MPS use and language design. You may check them out all nicely sorted at the MPS screencast page or directly at the MPS channel of JetBrains TV.
Guided Trainings
The MPS team offers hands-on commercial trainings. Check out the details:
The MPS documentation page will give you all the remaining pointers to case studies, tutorials, FAQs and other pieces of MPS documentation.
Other sample projects
MPS comes with several sample projects that you may play with to get a better grasp of language development. I recommend you tried them out, perhaps in the order as they are listed below. Find out what they do and how they are implemented. They may teach you important lessons. Don't worry if you sometimes cannot figure out how a particular feature has been implemented. Most likely you will find an answer in one of the following exercises and then you can revisit the sample and the thing will just click instantly.
Here's a list of the samples that we've prepared for you:
Language extensions:
Sample Java Extensions - a collection of small handy Java enhancements, such as parallel for loop, unless statement, Money literal, decision tables and Constants definition. The sample will teach you how to extend existing general purpose languages with custom constructs.
Demonstrated features - language extension, tabular notation, scoping, build script.
Complex - defines a Java extension to work with complex numbers
Demonstrated features - language extension, runtime solutions, type-system (inference, subtyping rules), side transform contribution menu, generator.
XML Literals - allows XML literals to be used directly in Java code as first-class language elements. The language builds on top of .xml and generates into into org.jdom.* API. The user-inserted XML code may refer back to the surrounding Java context to easily parametrize.
Demonstrated features - language extension, embedding languages, constraints, type-system (inference rules), dataflow, generator.
math - provides fancy-looking math language extension to Java, which allows you to enter complex numbers, matrixes, intervals, summation, product and other common mathematical operations in a natural way.
Demonstrated features - language extension, vector and matrix notation, scoping, non-trivial runtime solution, non-trivial code generator.
Standalone languages:
Language Patterns - a set of sample languages illustrating implementations of common language patterns in MPS. It is useful for beginners to see in isolation concrete implementations of typical language constructs. This sample project is gradually being updated with new patterns.
Multiple Projections - an example of a simple state machine language that focuses on the mechanism of multiple projections per concept. The programmer, who uses the language, can on-the-fly switch between several pre-defined notations as she progressed with her state-machine definition. All the available notations are defined in the language or its extensions.
Demonstrated features - definition of multiple notations for a language.
Multi Target - illustrates how to have a single language generated into multiple different target languages.
Demonstrated features - generate both Java and XML code from a single model.
Custom Aspects - shows the ways to define custom aspects for language definition. For more information, refer to Custom language aspect cookbook.
Demonstrated features - custom aspect definition.
Cross Model Generation - illustrates how to use custom generator plans to achieve cross-model generation.
Demonstrated features - generation plans.
Component Dependencies - a minimalistic example of a language for expressing dependencies between components of a system, which provides three alternative editor notations:
Textual
Tabular
Diagrams
This language comes with an XML generator to illustrate the possibility to generate non-imperative language, such as XML.
Demonstrated features - tabular notation, graphical notation, switching between notations.
Customized Debugger - an example of hooking a languages with the Java debugger, even when the language neither extends nor generates into BaseLanguage.
Demonstrated features - debugging, debugger integration.
Mind maps - an intuitive example of defining a diagramming notation, including a set of customized graphical symbols
Demonstrated features - defining graphical notation for diagrams.
DSL book sample - an example of a state machine language (Secret Compartment language), including a state machine test language.
Demonstrated features - runtime solution, scoping, test language definition, test generation.
The Custom Test Cases - a minimalistic example of building your own tests and run them from MPS.
Demonstrated features - test generation, integration with the MPS test runners.
The Simplest Language - a minimalistic example generating a Hello world application printing out a customized message. Shows the very basics of language generation.
Demonstrated features - language definition basics, generator definition basics.
Migrations - a simple example of migration scripts to migrate two interconnected languages using both the smodel API and TransformStatement.
Demonstrated features - language migration definition, migration tests.
Lambda Calculus - a language simulating lambda calculus, with projectional editor and generation into Java
Demonstrated features - definition of a functional language, runtime solution, scoping, non-trivial type-system definition.
Agreement - an example of a business-oriented DSL
Demonstrated features - definition of a high-level language (dates, duration, money, currencies), complex runtime solution, scoping, accessory models, substitute menus, side transform menus, node factory, generator.
Expressions - a simplified expression language to allow you to play with the type system and the Type-system Trace tool. The language gives you a bare-bone expressions language with minimal editor support, but with well structured type-system rules, which can help you learn the core of how MPS calculates types. Read more in the Typesystem Debuggingdocumentation.
Demonstrated features - typesystem definition, typesystem debugging.
Fixed Length Reader - illustrates how to create a language for describing binary data formats. Comes with a stub for a hypothetical runtime library that would extract elements from binary data using the supplied data format description (called configuration).
Demonstrated features - fixed-format language definition, Java and XML generation.
HighLevel Languages - an example of defining a custom set of language definition languages on building on top of the other. Illustrates how to define your own way to codify structure and editor for a language as well as how to make language debuggable in MPS.
Demonstrated features - textgen, language extension, language debugger definition, custom generation plan.
Formula Language - a sample definition of an expression language, including editor actions and a generator.
Demonstrated features - non-trivial language definition, generator definition.
Notes Organizer - a sample DSL plugin for IntelliJ IDEA including a build script, that simulates a task/todo list. Tasks can have different priorities, states and categories, which by themselves can also be customized. The task lists can be filtered using several kinds of Swing UI components and the user can choose among several alternative visualizations of the task lists. Shows as an example of filtering node collections, alternative editors and direct incorporation of Swing components into form-like notations.
Demonstrated features - build language, building an IDEA plugin, custom swing components, advanced editing capabilities, textgen.
State Chart - an example of a state-chart definition language that generates state charts in the SCXML standard.
Demonstrated features - XML code generation, scoping, non-trivial editor definition.
Requirement Tracking - an example of a universal, language-agnostic requirement tracking language. Goals of a software project can be captured in specification documents written using the provided requirement tracking language. Mentions of relevant requirements can be inserted into code at places that implement these requirements. The mentions can be used in code that uses any MPS language. The sample features Node Attributes, non-trivial scoping and multiple switchable editors for a single concept.
Demonstrated features - multiple editors, annotating code with code-agnostic node attributes.
Attributes - a sample illustrating the transparent handling of attributes in text-gen and the generator. The two CommentAttribute node attribute concepts are passed through the generator unchanged so that their text-gen can convert them to text.
Demonstrated features - node attributes, handling of attributes in the generator.
Sample Facet - illustrates a simple make facet that intercepts the make process.
Demonstrated features - make facet.
Money - provides a simple extension for BaseLanguage that allows definition of money literals (such as 10 EUR or 25 USD) and their use in math expressions.
Demonstrated features - runtime solutions, type-system, generator.
BL References - defines two BaseLanguage extensions - a Box for values and a Date literal. Illustrates ways to create language extensions that operate with lvalue-expressions (such as unary ++ and --) and generate them into BaseLanguage. For more information, refer to Implementing generators for BaseLanguage's extensions.
Demonstrated features – constraints, type-system, generator.
Lightweight DSL - examples of usages of the jetbrains.mps.baselanguage.lightweightDSL language to build internal "lightweight" DSLs embedded into BaseLanguage classes.
Demonstrated features - lightweight DSL language.
Heating controller - a simple language providing two notations to specify heating plans for a hypothetical home heating controller. The default notation allows for textual representation, while a language extension provides an alternative tabular notation.
Demonstrated features - multiple notations, tabular notation, constraints, behavior.
Tooltip Sample - an easy to understand example of using tooltips as part of the editor definition.
Demonstrated features - editor tooltips.
Progress Indicator - a set of actions that illustrate the proper way to handle progress bars in actions, how to make actions cancellable and enable them to run in the background.
Demonstrated features - actions, the plugin solution, cancellable and background-enabled actions, progress bar reporting.
Property Persistence - a non-trivial example of stub model implementation for a custom format. Plain property files are loaded as models into MPS thanks to the implementation of custom model roots and custom models of this sample project. For more information, refer to Custom Persistence Cookbook.
Demonstrated features - custom persistence, custom stub models.
Sample XML - a greatly simplified implementation of the XML language. Serves primarily for the XML Persistence sample project.
Demonstrated features – textgen.
XML Persistence - a non-trivial example of implementing custom persistence using ModelFactories and custom model implementations. The plugin contains three solutions (a build script, a persistence implementation and a plugin descriptor). The custom persistence implementation will load/save XML documents. For more information, refer to Custom Persistence Cookbook.
Demonstrated features – custom persistence.
Samples to tutorials:
ChemMastery - the language used in the JetBrains MPS for the impatient online course. It enables writting chemical elements, compounds and equations and some checking of their validity.
Shapes - the language created as part of the introductory Shapes Tutorial.
Demonstrated features - language definition, Java generation.
Robot Kaja - the language for commanding a virtual robot used in many of the introductory screencasts. Now includes a sample Context Assistant implementation.
Demonstrated features - runtime solution, scoping, Java generation, language definition, intentions, checking rules, quick-fixes.