MPS 2023.3 Help

Concept Functions

Concept functions allow language designers to leave hooks for their language users, through which the users can provide code to leverage in the generated code. For example, most of the languages that MPS offers for language design, such as EditorConstraints or Intentions, leverage Concept functions:

cf1.png

You can also discover their usages down in the Inspector window:

cf2.png

Concept functions are defined in jetbrains.mps.baselanguage and they contain BaseLanguage code, which upon generation becomes part of the generated Java code. This option can give your DSLs enormous flexibility.

Example

We'll use the Robot Kaja sample project to experiment with Concept functions. The goal is to allow the Script authors to provide a function that will customize the Trace messages, which are reported to the user through the trace command:

cf3.png
cf4.png

The user will be able to customize the trace messages through a function that receives the original message as a parameter and returns a string that should be displayed instead:

cf5.png
cf6.png

Define the concept function concept

First, a sub-concept of ConceptFunction must be created:

cf7.png
cf8.png

The behavior aspect overrides a few methods inherited from ConceptFunction:

  • getExpectedReturnType() - declares what type should be returned from the function

  • getParameterConcepts() - lists the concepts that will represent parameters to this function

  • showName() - indicates, whether the name of the function should be displayed in the editor alongside the parameter list and the return type

  • getName() - the name of the function to display in the editor. As it defaults to the concept alias, you will usually only want to override this if needing a dynamic name

Since MyFunction requires an argument to hold the original trace message value, we also need to create a concept to represent that parameter, which extends the ConceptFunctionParameter concept and specifies its type through an overridden getType() behavior method:

cf9.png
cf10.png

Add MyFunction to Script

Once defined, the MyFunction concept can be added to Script:

cf11.png
cf12.png

This will allow us to edit the function in the Script editor:

cf16.png

When you hit enter, the editor will display the signature of the concept function and you will be able to edit its body:

cf17.png

Notice that the Inspector shows the description messages for the function as well as its parameters, when you place the caret at the concept function signature.

Generator adjustment

The last step that remains is to alter the generator so that the trace message customization can happen. We first need to modify the KajaFrame class, which is a super-class for all the classes that get generated from Robot Kaja Scripts:

cf15.png

The trace() method needs to call the new customizeMessage() method in order to have the original trace message customized. The default implementation of customizeMessage() method returns the message without any alteration.

The generator template that defines how a class generated for a Script should look like, now has to generate a extra method that will override the customizeMessage() method in KajaFrame:

cf13.png

The overriding method only gets generated when the concept function exists in the Script. The generator uses the body of myFunction as a body of the generated customizeMessage() method.

cf14.png

Now the concept function for customizing trace messages should be fully functional:

cf5.png
Last modified: 07 March 2024