The purpose of SModel language is to query and modify MPS models. It allows you to investigate nodes, attributes, properties, links and many other essential qualities of your models. The language is needed to encode several different aspects of your languages - actions, refactorings, generator, to name the most prominent ones. You typically use the jetbrains.mps.lang.smodel language in combination with BaseLanguage.
Treatment of null values
SModel language treats null values in a very safe manner. It is pretty common, in OO-languages, such as Java or C#, to have a lot of checks for null values in the form of expr == null and expr != null statements scattered across the code. These are necessary to prevent null pointer exceptions. However, they at the same time increase code clutter and often make the code more difficult to read. In order to alleviate this problem, MPS treats null values in a liberal way. For example, if you ask a null node for a property, you will get back a default value for the type of the property. If you ask a null node for its children list, you will get empty list, etc. If you call a behavior method on a null node, a null value is returned, provided the return type of the invoked method is a ClassifierType or a StringType. For a PrimitiveType, the default value of that type is returned. This should make your life as a language designer easier.
A lot of the operations in the SModel language accept parameters. The parameters can be specified once you open the parameter list by entering < at the end of an operation. E.g. myNode.ancestors<concept = IfStatement, concept = ForStatement>.
The "+" symbol as a parameter to these operations means "include myself". That is, when the node, on which the operation is being invoked, matches the condition, "+" ensures that the node will also be included in the returned result - e.g. myNode.ancestors<concept = IfStatement, +> may return myNode, if it is an IfStatement.