The basis for the MSH language was the MUMPS language. MUMPS was developed somewhere in the 1980s, as well as many other modern languages. From the very beginning, it was developed as a language for creating large information systems and working with large distributed data. In this connection, has some specificity. Programming in this language is somewhat different from programming in other languages. Despite its low prevalence, it has a fairly stable community in different parts of the world programmers who develop information systems on it. During its existence, MUMPS has changed little. Some elements of the language have lost relevance. And the language is currently somewhat archaic. I would like to have a more modern language like MUMPS. For this purpose, the MSH language was created. Some concepts of the MSH language are different or absent in the MUMPS language. This material is mainly written for the MUMS audience of programmers, but it may also be interesting for others.
Constants.
There are no constants in MUMPS. In MSH they are entered. But because of the specific nature of the language, they cannot exist as immutable variables of the program execution time. Therefore, in MSH they are entered as compile-time objects. Something like the define C language in the most simplified form. At the moment of translating the MSH language into Pi, the virtual machine code, all constants in the source text are replaced with their values. That is, they are no longer in the Pi code. Constants can be used as variable values, as an index or variable name. Command format: Constant nameConst = valConst <, nameConst = valConst>; To the right of the equal sign there can be only a constant, the expression is not allowed. The name of a constant must be unique and do not overlap with the names of variables.
Variables.
In MUMPS, variables are stored in a wooden structure, whether global or locale. The truth is that globals in MUMPS have a slight difference - a shortened syntax. There is no abbreviated syntax in MSH. Storing data in the form of a tree only allows you to unify access to data. You can write a program to process any data tree. But programs often have to work with various intermediate values and store them in a tree is not efficient. Access to the tree always entails additional costs, no matter how we optimize this access. In MSH, data can be stored both in a wooden structure and in a one-dimensional array. It is better to store intermediate data in a one-dimensional array, although you can store any data. Access to the array is much faster than to the tree. Tree to store the so-called discharged data. That is, only existing vertices are stored in the tree. For example, we have a tree [1] [5] [78]. Only these vertices will be stored in the tree. The array stores all intermediate values. For example, we created the 78th element in the $ 78 array. All elements in this array will be created up to 78. If we create a tree, an empty array is created and vice versa, if an array is created, then an empty tree is created. But this of course refers to the current implementation of MSH. The visibility of variables in MUMPS has its own characteristics. What MUMPS calls globals in other languages is an appeal to databases. But locales are analogous to variables in other languages. Well, everything is clear with globals. These are external data and they are available both from any task of this application and from other applications. They are stored as files and usually several globals in one file. In MSH in general, everything is the same except for one moment. Each global is stored in a separate file. And if more precisely then in several files of one directory. This moment is significant from a technological point of view of building an information system. And one more note. Global in MSH synchronized on appeal. This means that they can be accessed simultaneously from different tasks without additional synchronization. Now we will deal with the locales in more detail. In general, the locale in MUMPS is a global top-level variable in the sense of the C language. There is no analog to the variables from the heap in the C language, in MUMPS. But an analogue of the automatic variables of the C language is. These are locales listed (or not listed), depending on the form of the command, in the New command. The scope of such locales from the New command to the Quit block completion command. Of course, the original solution is due to the nature of MUMPS and the absence of variable declarations in it. In my opinion, the default locale's global scope is a controversial decision, although not fatal. In MUMPS where I mostly work directly with globals, there are not so many local variables and name conflicts are not frequent, although they do happen. But still it is not convenient when programming. MSH takes a different approach. New teams are not here. And the localization of variables is made by prefix. Variables with the% prefix are localized inside the job. Variables with the prefix ^ tmp are localized within the application. Variables that do not have these prefixes are localized inside the Do block. This applies equally to trees and arrays.
Objects
There are no objects in MUMPS. But the PLO has become widespread. The bulk of modern programming languages somehow supports OOP. MSH is no exception. In order for OOP to be, a language must have objects to begin with. In the general case, the description of the object consists of a declarative part and a part of the implementation. MSH does not support variable declarations, which means there will be no declarative part of the object description. There is a description of the object in MSH as part of the implementation. In MUMPS, the program code is presented in the form of program modules. Entry points in a module are subroutines and functions. A program module in MSH and taken as a description of the object (class). Module labels are the entry points of this module. Entry points in this case are public properties of get of this class. The public properties of the set of this class will be the same entry point as get modified by a specific symbol. As such, the dot symbol “.” Is selected in MSH. A property in MSH, in addition to accessing get and set, also has a Kill operation — deleting a property. In this case, the name of the properties is modified by the prefix "..". Class inheritance in MSH is multiple and implemented using the Extend command. The classes listed in this command in order are the ancestors of this class. During program execution, when a property is addressed to an object, its description is first searched for in the source module, then in the modules listed in the Extent command in the order they are followed. The module’s earlier position in the command gives it a higher priority. Protected properties are implemented using the% this system property. Objects in MSH can only be in the tree. Only primitive data types can be stored in an array. Class methods are also entry points in a class module. Objects are created using the standard% new property. For example, we have the Person class with the Age property. In the class module there are entry points “Age” and “.Age”. In variable [1,2], create an object. Set [1,2].% New = Person; Access the Age property of the Person object by writing. Set [1, 2] .Age = 50; Accessing the Age property of the Person object by reading. Set $ 1 = [1,2] .Age; The translator converts these commands to calls to subroutines. But this is not the only way to access properties. By writing, the Age property can also be accessed via the method .Do [1,2] .Age (50); in MSH, the module performs a dual role. In addition to the class module, it can also be interpreted as a program module. In this case, the entry points are referred to as subroutines. Suppose in the Person module there is an ABC tag. Then you can refer to it as a program. True, in this case the variable% this will be empty. Do Person.ABC (125, D, 25.6); This is how class methods can be organized.
Developments.
Another effective programming paradigm is events. As a rule, programming languages do not contain event handling facilities. They are usually rendered into standard libraries. In MUMPS, event handling is in its infancy and comes down to error handling. In MSH, events are included in the language. Events can be as system generated by the system. Similarly, user generated by the user using the EventTrap command. The arguments of this command are passed to the event handlers of this event. The EventCall command assigns a program to the event handler. At the time of the event, the current task will be interrupted and the program will be executed by the handler in the new Do block. It’s as if the Do command was encountered at this place with a call to this handler. This means that local variables of the program being executed in the event handler will be unavailable. The EventWait command stops the execution of the current program and waits for an event to occur. When an event occurs, the current program continues to work, and from that moment on, the arguments passed to the program become available. A new Do block is not created and therefore all local variables of this Do block are available after the EventWait command. If an event occurred before the appearance of the EventCall and EventWait commands. That event will be processed by the first meeting EventCall or EventWait command. After processing the event is deleted. The EventDelete command deletes the event along with handlers.