MPS 2019.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

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

cf2

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
cf4

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
cf6

Define the concept function concept

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

cf7

cf8

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 overriden getType() behavior method:

cf9

cf10

Add MyFunction to Script

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

cf11

cf12

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

cf16

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

cf17

Notice that the Inspector shows the description messages for the function as well as its parameters, when you place the cursor on 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

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

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

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

cf5

 

 

Last modified: 28 February 2020