MUMPS
# MUMPS

MUMPS (Massachusetts General Hospital Utility Multi-Programming System) ist ein ursprünglich auf DEC PDP-Computern entwickeltes Betriebssystem, eine Programmiersprache und ein Datenbanksystem. Es war von Beginn an eine offene Entwicklerumgebung für fast alle gängigen Computer-Plattformen. 1993 erfolgte die Namensänderung auf M durch die weltweit organisierte MUMPS Usergroup (MUG). Der Begriff MUMPS wurde 1971 bis 2003 vom Massachusetts General Hospital (MGH) als Markenname geschützt.

## Konzept und Entwicklung

MUMPS wurde 1966 auf die Initiative von Octo Barnett im Laboratory of Computer Science des Massachusetts General Hospital entwickelt. Per 1969 erfolgte der erste Produktiveinsatz im Krankenhaus ebenda. Die Entwickler und Anwender schlossen sich in Folge dann 1971 zur MUMPS Users´ Group (MUG) zusammen. Dieser Gruppe gehörten Universitätsinstitute, Anwender (vorwiegend Krankenhäuser), Softwareentwickler und „Implementoren“ (Vendors) an. 1973 gründete sich aus der MUG das MUMPS Development Committee (MDC) und startete die Entwicklung eines MUMPS Standards, der dann 1977 von der ANSI (American National Standards Institute) als MUMPS ANSI-Standard (ANSI/MDC X11.1-1977) – als zweite Programmiersprache überhaupt – veröffentlicht wurde. Ein Update der Sprachdefinition erfolgte 1984 (ANSI/MDC X11.1-1984) und 1990 (ANSI/MDC X11.1-1990, ebenso ISO, NIST Standards). 1992 wurde die Sprache MUMPS erweitert um eine Reihe von neuen, moderneren Sprachelementen zur ISO-Norm ISO/IEC 11756. 1995 wurde die Norm erneut veröffentlicht, diesmal mit einer Verknüpfung zu gks, jis90, sql (x3.135), tcp-ip, x3.64 und X-Windows. Die derzeit (Stand Januar 2023) letzte Ausgabe der Norm (ISO/IEC 11756:1999) wurde 1999 publiziert und zuletzt 2020 bestätigt. 1993 erfolgte mit einem neuen Marketingkonzept eine Änderung des Namens MUMPS auf M. Die Mumps User Groups änderten ihren Namen entsprechend in M Technology Association (MTA). In Deutschland schlossen sich Implementoren und Softwarehäuser zum M Technologie Konsortium zusammen.

Der ANSI Status ab 1977 erleichterte die Portierung der Sprache auf viele Systemumgebungen. Die Liste der Vendors umfasste von DEC (digital equipment, weltweit zweitgrößter Computerhersteller) bis zum Ein-Personen-Unternehmen. Ungewöhnlich waren Portierungen in Osteuropa und den Dritte-Welt-Staaten auf PDP-Nachbauten, z. B. DIAMS für SM-4 Minicomputer (ab 1978), DIAMS-DVK für PC (ab 1988). Ebenso machte die Implementierung von M auf Japanese VAX DSM (DEC) und 1984 die Erweiterung des Standards für non-ASCII den Weg nach Japan frei. Zu Beginn der 1990er-Jahre erlebte MUMPS bzw. M seine Hochblüte und war auf praktisch allen Betriebssystemen und Prozessoren verfügbar. Die MUG führte in ihrer Zeitschrift per 1991 insgesamt 23 MUMPS Implementoren und über hundert verschiedene Hersteller von Computersystemen an, von denen viele nicht mehr existieren. Allein für MS-DOS gab es 11 verschiedene Vendors. In einer Studie des Marktforschungsunternehmens Gartner war für 1993 ein Gesamtumsatz im M-Umfeld von $ 1,3 Milliarden errechnet worden, mit einer Prognose von $ 2 Milliarden im Jahr 1995.

Ende des 20. Jahrhunderts verlor die von einer „Usergemeinschaft“ (MUG) und einem „akademischen“ und „demokratischen“ M-Entwicklungskomitee (MDC) getragene Sprache M an Bedeutung und Reputation. In der öffentlichen Wahrnehmung des Fachpublikums, in Computerzeitschriften und in der Fachliteratur trat M nicht in Erscheinung. Relationale Datenbanken wurden u. a. durch Oracle, IBM (DB2), Berkley (Ingres), Informix, dBase und Sybase (später Microsoft) propagiert. Die technologische Überlegenheit von M ging gegenüber den Möglichkeiten der Einbindung anderer Programmiersprachen, Web-Applikationen und Datenbanken unter, erst nach 1995 gab es hier viele proprietäre Erweiterungen. Der MWAPI (Windows-M Application interface) Standard (1992) kam zu spät, um sich in der Windows, OS/2, Apple Mac oder X/Motif-Windows-Welt zu etablieren. Die Informatik-Ausbildung wandte sich anderen, moderneren Konzepten zu. Kleinere M-Applikationen konnten sich am Markt nicht etablieren, da die Hersteller von M ihre Lizenzmodelle an Institutionen und Großanwender orientierten.

Die Firma DEC geriet wie alle anderen Hersteller von Minicomputern wie IBM, Wang, Nixdorf, Data General durch die zunehmende Rechnerleistung der Personal Computer (IBM-PC) bei sinkenden Kosten unter wirtschaftlichen Druck und wurde 1998 an Compaq Computer verkauft. MUMPS Systeme (Digital Standard Mumps – DSM-11 und DSM/VMS) waren nicht zuletzt für den 30-jährigen Erfolg der DEC PDP-11 Minicomputer Serie verantwortlich.

Intersystems, gegründet 1978 und mit ISM-11 (einem DSM-11 Klone) einer der anfänglichen MUMPS-Implementoren, übernahm 1993 DTM (Datatree Mumps) und erwarb dann von DEC im Jahre 1994 die Rechte an Digital Standard MUMPS (DSM) für PDP und VAX Maschinen. Mit der Übernahme von Micronetics, dem damals weltweit zweitgrößten Anbieter von M, im Jahr 1998 waren mit Ausnahme von GT.M alle bekannteren kommerziellen M-Versionen (DSM, MSM, DTM, ISM) im Eigentum von Intersystems. GT.M (Greystone Technology M) ist seit 2004 ein strategisches Produkt im Eigentum der FIS (Fidelity National Information Services, Inc.), einem der weltweit größten Finanzdienstleister. Zeitgleich wurde von Intersystems 1997 das Produkt Caché auf den Markt gebracht und die Begriffe M und MUMPS dadurch aus dem Marketingjargon entfernt. Die Programmsprache M wurde zu Caché Object Script und die M-Datenbank zu „Caché - die postrelationale Datenbank“. Der offene M-Standard wurde zum firmeneigenen „InterSystems-Standard“ erweitert, eine MDC als Träger einer Weiterentwicklung unnötig und die weltweiten MTA (Usergruppen) lösten sich sukzessive auf.

Weitere Versuche zur Entwicklung einer Usergruppen-getragenen Plattform für M waren nicht erfolgreich. GT.M wurde 2000 für Linux und OpenVMS zur Open-Source-Software. Ein Spinoff (2017) von GT.M ist yottaDB, die ebenfalls als Open-Source-Projekt im Schwerpunkt die Anbindung von anderen Sprachen hat. MUMPS V1 ist als Github-Projekt verfügbar, u. a. auch für den Raspberry PI. M21 von ehemaligen MSM-Mitarbeitern hatte keinen kommerziellen Erfolg.

## Umfeld

Die Mumps User Groups (MUG) waren weltweit organisiert. Um die größeren zu nennen: Per 1990 gab es MUG-Nord America, MUG-Brazil, MUG-Europe, MUG-Deutschland, MUG-Japan, MUG-Netherlands, MUG-Russia (DIAMS-SOYUS), MUG-UK als eigenständige „Vereine“ deren Mitglieder (Universitäten, Implementoren, Softwarehäuser) sich im MDC engagierten. Es gab mehrere Fachzeitschriften, die von den User Groups herausgegeben wurden, unter anderem die in Europa verbreiteten MUMPS NEWS (MUG-NA), Mug-Quarterly (MUG-NA), MUG Newsletter ab 1993 in M Professional umbenannt (MTA-Europe) und M Börse von der MUG Deutschland. Daneben gab es noch vierteljährlich die DSM NEWS von DEC. Die Kundenzeitschrift von Intersystems war the M/USER später M news. Die jährlichen „MUMPS Users' Group Meetings“ dienten zum Informationsaustausch. Z. B.: MUG Wien (1987) mit 170 Teilnehmern. Das MUG-Meeting in New Orleans (USA) im Jahr 1991 hatte mehr als tausend Teilnehmer. Das MTA Meeting 1995 in Barcelona dauerte 4 Tage und hatte über 400 Konferenzteilnehmer. Eine wichtige Rolle spielte das MUMPS Development Committee (MDC) das sich aus verschiedensten Interessensgruppen (Vendors, Uni, Anwender, Entwickler) um die Sprache zusammensetze. Es traf sich mehrmals jährlich und beriet über Erweiterungen und Implementationen. Jedes Mitglied der MUG konnte Verbesserungsvorschläge machen, die dann ihre Rolle vom Vorschlag über Typ C, B, A und dann zum Standard bis zur ANS bzw. ISO durchliefen. Auch jeder Hersteller der Sprache war jeweils nur mit einer Stimme vertreten

Typisch für Anwendungen aus dieser Vor-Windows-Zeit zwischen 1970 und 2000 sind textorientierte Benutzeroberflächen auf einem Text-Bildschirm, Teletype oder einem PC mit Terminalemulationssoftware. Angebunden wurden die Geräte mit RS-232-Schnittstelle. Mit dem Aufkommen von Netzwerken in Unternehmen wurden Terminalserver und PCs mittels LAT-Protokoll (Local Area Transport – DEC proprietär), später mittels Telnet angebunden. Grafische Benutzeroberflächen entstanden mit dem Aufkommen von Windows anfänglich nur für die Entwicklerumgebung (z. B CachéStudio von Intersystems oder SERENJI Debugger von Georg James Software). Eine im ISO-Standard 1992 enthaltene Erweiterung (MWAPI) zur Entwicklung von M-Applikationen unter Windows konnte sich nicht durchsetzen. MUMPS wurde anfänglich vorwiegend für Krankenhaus-Anwendungen verwendet, die größte IT-Ausschreibung (1,02 Milliarden USD) weltweit war in den 1970er-Jahren das 700 Militärkrankenhäuser umfassende Projekt des US Department of Veterans Affairs. Zur Zeit seiner Entstehung war MUMPS den konkurrierenden Programmiersprachen in vieler Hinsicht überlegen – vor allem wegen des Multitaskings, kurzen Entwicklungszeiten (Interpretersprache) und des Gebrauchs geringer System-Ressourcen – und wurde bald auch in anderen Branchen wie z. B. Deutscher Hafen Hamburg, FIS und Logistik eingesetzt. Nicht nur Aufgrund der extremen Langlebigkeit vieler betrieblicher IT-Systeme, bei denen eine Komplettablösung nicht nur teuer, sondern auch sehr riskant ist, gibt es immer noch zahlreiche "alte" MUMPS-Systeme weltweit. Nach wie vor werden aber laufend neue Anwendungen mit M entwickelt, wobei die M-Datenbank und die Sprache M "versteckt" unter proprietären Produkten liegt. Das weltweit größte Paket an medizinischer Software ist VistA (Veterans Health Information Systems and Technology Architecture). Dies ist eine public domain MUMPS Entwicklung (DSM und Nachbauten) entstanden 1977 und verwendet M. SPAR als eines der größten österreichischen Einzelhandelsunternehmen mit über 90 000 Mitarbeitern, verwendet in Österreich und Niederlassungen in Osteuropa ein M-Warenwirtschaftssystem. Der Möbelhändler XXXL-Lutz mit insgesamt 248 Einrichtungshäuser in Europa verwendet und entwickelt seine Applikationssoftware mit M. Die Firma SHD ist eines der größeren Softwareentwickler für Möbelhäuser, das sich seit mehr als 4 Jahrzehnten mit M-Technologie beschäftigen.

## MUMPS / M als Betriebssystem und Umgebung

Wie alle älteren IT-Systeme hat auch MUMPS die Phasen vom „stand-alone System“ – MUMPS als Betriebssystem – über Dezentralisierung, Vernetzung von Systemen bis zu den heutigen heterogenen Systemwelten durchgemacht.

Die typischen stand-alone Systeme DSM-11 (DEC), ISM-11, später M/11+ (Intersystems), VISOS (Viso-Data, Wien), PSM-11 (Patterson, Gray and Associates) – alle auf DEC PDP Hardware – und MV MUMPS (Data General Maschinen) wurden auf bootfähigen, installationsbereiten Datenträgern (Band, Band-Kassetten, Disketten) ausgeliefert. Die Installation umfasste jeweils einen vollständig in MUMPS geschriebene Satz von Programmen für die System- und Datenverwaltung und diverse Tools zur Programmentwicklung.

Mit dem Aufkommen von Intel-PCs ab 1981 gab es zwei Formen der Implementierung für diese Maschinen: Die Produkte MSM-PC und MSM-386 der Firma Micronetics verwendeten einen zweistufigen Bootvorgang. Nach dem eigentlichen Boot auf PC-DOS wurde das Programm msm.exe gestartet. Damit wurde de facto ein stand-alone Micronetics Standard Mumps (MSM) mit Multiuser und Multitasking hochgefahren. DSM und MSM waren dann im laufenden Betrieb kaum zu unterscheiden, dementsprechend einfach waren Portierungen. Alle Netzwerkkarten („packet“-Treiber) und intelligente RS-232 Interface-Karten (z. B. 16-fach Arnet RS-232) wurden erst im dann laufenden MSM konfiguriert. Die Installation umfasste einen komplett in MUMPS geschriebenen Satz von Programmen für die System- und Datenverwaltung und diverse Tools zur Programmentwicklung. Ein Multiuser- und Multiprozess-System mit bis zu 256 Benutzer-Lizenzen auf einem Pentium-PC stand somit zur Verfügung (MSM-386). Alle Daten und Programme wurden in einer einzigen Datenbank-Datei (database.msm). welche meist die gesamte restliche Festplatte umfasste, abgelegt. Das darunter liegende DOS-System konnte erst nach dem Niederfahren von MSM z. B. für Sicherungsprogramme verwendet werden.

Die entsprechenden PC-Produkte von Intersystems und Datatree verwendeten einen anderen Ansatz. Globale Variablen und Programme wurden in einzelnen DOS-Dateien abgelegt und MUMPS war ein „normales“ DOS-Programm, das auf die vorhandenen Interfaces und Programme (z. B. Sidekick) zugreifen konnte. Interface-Karten waren auf die vom Kartenhersteller gelieferten Treiber angewiesen und wurden in PC-DOS eingebunden.

Mit der Verbreitung von Digital VAX Maschinen ab 1978 wurde auch für DSM/VM die heute gängige heterogene Systemstruktur (ein „nur“ Betriebssystem, ohne weitere Applikations-Funktionen) eingeführt. Die Datenbank und die DBMS Programme sind als laufende Systemprozesse realisiert. DSM als Sprach-Interpreter war eine von vielen Anwendungen. Applikationen, Entwicklungs- und Verwaltungsprogramme greifen über Interprozess-Kommunikation oder Standard Treiberkonstrukte auf die Daten zu, im Fall von MUMPS DDP (Distributed Data Processing), ODBC, OMI (Open Mumps Interconnect) und div. proprietäre Netzwerk-Protokolle.

Einzig DSM-11 auf den PDP-11-Maschinen blieb von 1970 bis 1995 immer ein bootfähiges stand-alone System. Mit dem Erscheinen der DEQNA Karten (Ethernet) war er auch einer der ersten Microcomputer, auf dessen Daten mit Ethernet zugegriffen werden konnte.

## MUMPS / M als Datenbanksystem

Die M-Datenbank gehört zur Kategorie der Hierarchischen Datenbanken und damit zur Gruppe der NoSQL-Datenbanken. Der heute bekannteste Vertreter dieses Datenbanktyps ist die Windows-Registry.

Informationstechnologisch ist M ein Datenspeicherungssystem basierend auf String-Adressierung und B*-Bäumen (balanced trees) mit Schlüsselkomprimierung. Es werden nur belegte Knoten gespeichert („sparse arrays“). Eine M – Datenbank ist grundsätzlich selbstreorganisierend und reorganisationsfrei. B*-Bäume zeichnen sich durch extreme Effizienz und Geschwindigkeit im Datenzugriff aus. Sie sind gut geeignet für Applikationen mit Online-Transaktionsverarbeitung (OLTP). Sie sind auch geeignet jedes andere Datenbanksystem, auch relationale, zu modellieren.

Die Kopplung einer prozeduralen Sprache und einem Datenbanksystem war historisch gesehen immer sehr locker und meist mit „Call-Schnittstellen“ oder später mit „embedded SQL“ möglich. Im Gegensatz dazu ist in MUMPS konzeptionell die Datenhaltung fix in die ISO „genormte“ Sprache integriert. Es stehen alle erforderlichen Sprachelemente zur Datenverarbeitung im Sprachumfang zur Verfügung.

Von der Sprachsyntax besteht keine Unterscheidung zwischen lokalen, flüchtigen Variablen (im RAM), die im laufenden „Programm“ verwendet und globalen Variablen – als Globals bezeichnet – die auf der Festplatte und für den „allgemeinen“ Zugriff permanent gespeichert werden. Die Unterscheidung, ob lokale oder globale Variable wird nur durch die Benennung gemacht: Globale Variablen haben als erstes Zeichen ein ^ (Caret, ASCII 94)

Logisch sind lokale und globale Variablen als n-dimensionale Felder möglich. Auch Arrays oder Matrix genannt. In einfachen Fall (n=0) besteht ein Datensatz aus einer Zeile: ^DAT=dies ist ein Datensatz und enthält eine Adresse.

Als einstufiges Array ^DAT(1)=erster Datensatz, ^DAT(40)=vierzigster Datensatz

Diese Arrays können n-dimensional sein und jeder Index kann aus einem beliebigen alphanumerischen String oder einer Variablen bestehen:

^D(„Franz“,„Huber“,19541101,„8020 Graz“,PLZ)=Dies ist die Adresse, ^D(„Johann“,„Mairhofer“,19591224)=Dies ist ein Datensatz mit der Adresse.

Zudem gibt es keine festen Feld- und Satzlängen wie es bei sequentiellen Dateien – klassischer RDMS – üblich ist. Ebenso sind alle Variablen in M typfrei, also vom Typ String. Dies alles bringt erhebliche Platzersparnis. Z. B. bei 5000 Patientendaten ist das Verhältnis 300 MB zu 425 KB.

Ein B*-Baum besteht oben aus einer Indexebene. Zeigeradressen verweisen jeweils auf Index-Blöcke, die eine Ebene tiefer stehen, bis zu untersten Ebene, die aus den Datenblöcken besteht und die Datenebene bildet. Alle Blöcke auf dem Speichermedium (Index- und Datenebene) sind mit Zeigeradressen horizontal und vertikal verbunden, d. h. referenzieren sich mit Blocknummern. Die Indexebenen werden mit Speicherung bereits alphanumerisch (canonical) indiziert bzw. eingeordnet. Der Lesezugriff auf die Daten erfolgt über 1 bis n Indexblöcke bis hinunter in die Datenebene. Auch große Globals haben selten mehr als 4-5 Indexebenen, die zudem noch Schlüsselkomprimierung verwenden. Das Lesen beschränkt sich auf sehr wenige Datenblöcke und Festplattenzugriffe. Nachdem die „Datenbank“ hier wahlfrei Datenbankblöcke verwendet, gibt es sowohl beim Einfügen als auch beim Löschen minimale organisatorische Arbeit für das System. Es gibt kein Re-Indizieren oder Re-Organisieren nach dem Löschen, wie bei ISAM Datenbanken notwendig.

Damit lässt sich auch eine relationale Datenbank, bestehend aus Tabellen, aufbauen.

^Daten(rownumber)=Spalte1,Trennzeichen, Spalte2,Trennzeichen, Spalte 3, Trennzeichen, usw.

^Index (Spalte2)=Rownumber

Der dazu nötige SQL-Softwareüberbau ist triviale M-Programmierung. Tatsächlich waren das erste Add-On-Produkt, das Intersystems bereits 1981 herausbrachte, das Open M/SQL und Micronetics nannte sein Produkt MSM-SQL Server. Hier hat Oracle Corp. mit Micronetics ein client/server-Gateway für M herausbracht.

M ist auch zur Programmierung mit objektorientierten Daten sehr gut geeignet und wurde entsprechend auch genutzt. Ein objektorientierter Datensatz liegt in der Natur von hierarchischen Datenbanken:

^F(Auto, Aufbau, Karosserie, Türe, Farbe)=Blau

^F(Auto, Motor, Treibstoff)=Diesel

^F(Auto, Motor, Verbrennungsmotor, Kolben, Kolbenringe, Anzahl)=2

Im neuen Sprachstandard ab 1993 wurde auch für alle M-Systeme die Transaktionsverarbeitung standardisiert. Im Kontext der Transaktionsverarbeitung bezeichnet das Akronym ACID (Atomizität, Konsistenz, Isolation und Dauerhaftigkeit) die vier Schlüsseleigenschaften einer Transaktion.

## Programmumgebung

Mit dem Anmelden am System durch die Eingabetaste (RS-232 Terminals, LAT Terminals) oder Verbindungsaufbau (Telnet, Konsolbildschirm) wird entweder eine M-Applikation (Applikationsumgebung) gestartet, definiert in einer „Tied Terminal Table“, oder nach einer Login-Prozedur wird das Interpreter-Prompt der Entwicklungsumgebung angezeigt. In dieser kann ein Befehl eingeben werden, ein Programm gestartet oder in den Speicher geladen werden, um dann z. B mit einem Editor bearbeitet zu werden.

Jede Applikation oder jede Entwicklungsumgebung wird im Kontext eines User Class Identifiers (UCI) ausgeführt. D.h. das Login, bestehend aus UCI-Name und PAC (Programer Access Code), ist verknüpft mit einem Plattenbereich für Daten (Globals) und Programmen.

Auf die Daten eines UCI kann von jedem anderen UCI aus zugegriffen werden und wenn das System netzwerkfähig ist, auch über das Netzwerk auf die UCI´s auf anderen Maschinen. Als „kleinster gemeinsamer Nenner“ wurde dafür das Data Distribution Protokoll (DDP) von DEC verwendet das bis 2000 von praktisch allen M-Implementoren realisiert wurde. Damit war bereits in den frühen 80er Jahren auch Replikation und Spiegelung der Daten auf anderen Maschinen und damit hochverfügbare Systeme möglich, die auch „automatic failover“ können.

Der erste UCI ist üblicherweise MGR benannt. Alle Programme und Globals, die in diesem UCI liegen und deren Namen mit Prozentzeichen beginnt, können in allen anderen UCI´s gestartet bzw. im Falle der Globals gelesen werden.

Wenn in diesem Zusammenhang von Partition gesprochen wird, ist damit der Speicherbereich (RAM) gemeint, den das System für ein Programm und seine lokalen Variablen zur Verfügung stellt. Eine Partition war früher in M meist nur wenige Kilobyte groß. (DSM-11 in 1990: 9 kB, MSM-NT 4.4. in 1998: 128 kB). Bei einer Interpretersprache muss der gesamte Sourcecode eines Programms in den Speicher geladen werden. Wiewohl das Programm meist mit dem Abspeichern auch in kompilierter Form (p-code oder Maschinensprache) gespeichert wird. Diese wurde beim Aufruf eines Programms im Applikationsmodus zur Verringerung der CPU-Last verwendet, da keine Neuinterpretation des Codes nötig war. M-Programme sind daher üblicherweise nicht länger als eine A4-Seite.

Der Programmstart erfolgt mit dem Befehl DO, wobei DO label ein Sprungbefehl zu einem Programm im Hauptspeicher zum label bedeutet. d. h. Sprungziel, meist erste Zeile. Ein DO ^programmname, lädt ein Programm vom Speichermedium und startet dies mit der ersten Programmzeile, während ein DO label^programmname ein Sprungziel zu einem Programm auf dem Speichermedium bedeutet.

Wie in jeder kommerziellen Software-Entwicklung hat auch jedes M-Softwarehaus Programmierrichtlinien, in der NoGo´s enthalten sind. (Z. B. Verwendung von Befehlsnamen wie GOTO als Variablennamen, Variablenschreibweise, Dokumentation etc.). Ebenso üblich ist eine eigene Programm-Bibliothek und – vor der Windows Zeit – ein hauseigener Bildschirm-Masken-Generator.

Ein weiteres Feature, das alle MUMPS-Systeme können, ist das sogenannte Journaling auf UCI-Ebene. Damit werden alle SET- und KILL-Befehle für Globals in einen Journaldaten-Block mitgeschrieben. Diese liegen meist auf einer Bandstation, einer Bandkassette oder auch über Netzwerk auf einer anderen Maschine. Damit ist die In-Time-Wiederherstellung aus einer Vollsicherung und den Journal-Bändern möglich. Technisch ist Journaling ein After Image Journaling (AIJ) (siehe Archive-Log Feature von Oracle). Mit MSM-386 implementierte Micronetics auch ein Before Image Journaling (BIJ) und nannte dieses Feature „Bullet Proof Database“.

Grundsätzlich sind die Informationen über die die Programm- und Systemumgebung in sogenannten strukturierten Systemvariablen (ssvn) abgelegt. Diese haben die Form ^$name(exp1,epx2,..). Als relativ alte Sprache konnte M lange nur den reinen ASCII 7 Bit Zeichensatz. In dem 1992 definierten Standard von M wurde eine ssvn ^$Character eingeführt mit der Hersteller Informationen über die vorhandenen Zeichensätze, Sortierung und Einordnung in Zeichenklassen geben kann. In weiterer Folge können diese Eigenschaften – wie viele Systemvariablen – auch im Programm verändert werden. Dies wurde besonders relevant für grafische Benutzeroberflächen, während Terminals hardwareseitig auf entsprechende länderspezifische ASCII Zeichensätze konfiguriert werden.

Weitere ssvn sind ^$DEVICE, ^$GLOBAL, ^$JOB, ^$LOCK, ^$ROUTINE, ^$SYSTEM sowie ssvn die in der MWAPI Erweiterung von M enthalten sind.

## Sprachsyntax von M

### Allgemeines

Im Folgenden werden die Sprachelemente von MUMPS/M entsprechend dem ANSI-Standard ANS/MDC X11.1 – 1995, in Europa umgangssprachlich auch als „die Typ-A-Erweiterung“ bezeichnet, besprochen. Der Name M wird ab 1993 optional für die Sprache MUMPS verwendet.

M ist eine Interpretersprache. Ein M-Interpreter verarbeitet den im Hauptspeicher (RAM) vorliegenden Source Code. Editieren, Testen, Debugging, Syntax Check usw. finden live am Programmcode statt. Das verkürzt die Entwicklungszeit, weil der Kreislauf Editieren, Kompilieren, Testen, Editieren einer Compilersprache entfällt. Je nach Implementierung wird mit dem Speichern des Sourcecodes als Text auch ein „p-code“ oder Assembler-Code des Programms zusätzlich erzeugt und gespeichert, was wiederum das Ausführen als Applikation beschleunigt. Die wegen Platzverbrauch früher in M verpönte Dokumentation mit Kommentaren im Source Code wurde nebenbei dadurch verbessert.

Alle M-Programme haben eine hohe Kompatibilität untereinander. Seit den Anfangsjahren gab es nur Erweiterungen der Befehle. Daher können auch „alte“ Programme auf neuen Systemen (nach ISO 1995 Standard) ohne Aufwand verwendet werden. M ist durch die konsequente Pflege des Sprachstands in Komitees eine sehr portable Sprache auf verschiedenen Plattformen, da nur Betriebssystemspezifika beachtet werden müssen.

In der Fachliteratur wird ein M Programm als „Routine“ bezeichnet. Der Programmaufbau besteht aus einer oder mehreren Zeilen. Eine Programmzeile beginnt mit einem Leerzeichen (ASCII 32) oder einem Tabulatorzeichen (ASCII 9). Diesem folgt eine syntaktische Einheit, bestehend aus einem Befehl, gefolgt von einem oder mehreren durch Beistrich getrennten Befehlsargumenten. Die „Argumentless Command“-Option bei den Befehlen IF, ELSE, FOR, QUIT und DO bedeutet, ein „extra“, zweites Leerzeichen nach dem Befehl als Befehlsargument zu sehen. Mehrere syntaktische Einheiten können bis zum Ende einer Befehlszeile durch die Trennung mit Leerzeichen aneinandergefügt werden, z. B.: _Befehl1_Argument_Befehl2_Argument,Argument_Befehl3_Argument_Befehl4__Befehl5 usw. (Befehl4 wäre hier ein argumentloser Befehl mit 2 Leerzeichen)

Zeilenende ist CR/LF, CR oder LF Zeichen, mögliche Länge einer Programmzeile lt Standard mindestens 510 Zeichen bestehend aus den 95 druckbaren ANSI-Zeichen.

Optional kann vor jeder Programmzeile noch ein Label – auch Sprungziel oder Tag genannt – stehen. Bei einem DO (Sprungbefehl) auf ein Label mit einem angefügten runden Klammerpaar darin kann eine optionale Liste von Parametern übergeben werden (Z. B. DO AUSW oder DO AUSW(A,B,c,d). Wird einem Labelnamen ein $$ vorangestellt, kann dieses Label auch in Form eines Funktionsaufrufes (extrinsic function) verwendet werden. Eine „extrinsic variable“ ist eine vom Programmierer selbst definierte spezielle Variable, die durch den Rücksprungwert eines Subprogramms entsteht. Z. B: SET uhrzeit=$$JETZT^TIME

Innerhalb einer Befehlszeile gilt die strikte links/rechts-Abarbeitung, dies bezieht sich auch auf mathematische Konstrukte. Punkt vor Strich wird ohne Gruppierung mit Klammern nicht richtig verarbeitet. Logische Tests bei Befehl IF werden durch Beistrich getrennt, jedoch zur einfachen Lesbarkeit meist in runde Klammern gesetzt.

Lokale Variablen werden nach Bedarf dynamisch gesetzt und sind innerhalb einer Partition – Entwickler- oder Applikationsumgebung – gültig. Sie sind grundsätzlich vom Typ „String“ (Zeichenkette) mit variabler Länge. Es erfolgt eine kontextabhängige Interpretation bei logischen und mathematischen Operationen. Dazu wird vom Variablenwert nur der nummerische Teilstring bis zum ersten nichtnumerischen Zeichen verwendet, unter Berücksichtigung des ev. vorhandenen Vorzeichnens, Dezimalpunkts und Potenzoperators.

Lokale Variablen bzw. Variablenwerte können jederzeit „auf Stack“ gelegt werden. Meist werden sie bei einem Sprung in eine Unterprogramm-Ebene (d. h. neuer Programm-Stack) neu belegt und erhalten nach Rückkehr aus dieser Unterprogramm-Ebene/Stack ihren alten Wert (implizit, argumentlos und exklusiver NEW Befehl). Eine Organisation der Gültigkeit obliegt ausschließlich dem Programmierer.

Programmnamen, Labelbezeichnungen und Variablennamen (lokal oder global) sind case-sensitiv und müssen aus 1 Buchstaben oder „%“ Zeichen, gefolgt von 0-7 alphanumerischen Zeichen ohne Sonderzeichen, in ASCII-7 Codierung bestehen. (Beispiele dafür A123, %ANS, PRG, %1AN, etc.)

Alle Befehle können – soweit sinnvoll – auch mit einer logischen Nachbedingung geschrieben werden. Z. B. Statt IF a=0 SET b=125 kann auch SET:a=0 b=125 verwendet werden. Der IF Befehl würde sich im Gegensatz dazu auf die gesamte restliche Zeile auswirken.

Alle Befehle, Funktionen und Variablen, die mit dem Buchstaben Z bzw. $Z beginnen, sind für den Sprach-Implementor spezifisch und werden hier nicht besprochen. Dasselbe gilt für die VIEW Befehle und die $VIEW Funktionen, die den direkter Zugriff auf Speicher des Systems ermöglichen.

Alle Variablen können auch mittels Dereferenzierung ("name indirection" oder "argument indirection") verarbeitet werden. Bei Unterprogrammaufrufen auch call by value und call by reference genannt. Beispiele dazu: SET a="ABC" WRITE @a gibt den Wert von ABC aus ; SET a="b=1,c=2" SET @a setzt Variablen b=1 und c=2

Gültige Zahlenwerte sind im Bereich von -10E25,-10E-25 oder 10E25, 10E-25 oder Null. Die Genauigkeit der Zahlendarstellung ist 15 Stellen, beim Potenzoperator (**) 7 Stellen.

### Befehle

M kennt insgesamt 22 Standardbefehle, zudem herstellerspezifische Befehle, die mit „Z“ beginnen, transaktionsspezifische Befehle und die Befehle für die eventgesteuerte MWAPI Erweiterung. Jeder M Befehl kann auf eine zur Unterscheidung notwendige, minimale Anzahl von Buchstaben – meist 1 – verkürzt werden. Die Befehlsnamen sind so gewählt dass, bis auf wenige Ausnahmen, jeder Buchstabe des Alphabets nur einmal als Anfangsbuchstabe vorkommt. Alle Befehle sind nicht case sensitiv und bestehen aus einfachen englischen Vokabeln.

* Die Befehle für die Eingabe/Ausgabe Verwaltung (OPEN, USE, WRITE, READ, CLOSE) gelten für folgende Geräteklassen: Geräte, Dateien, Netzwerk und „Pipes“ (Datenstrom). Neben speziellen Hersteller- und Betriebssystem spezifischen Z-Befehlen dazu, seien auch ZLOAD, ZREMOVE und ZSAVE für die Programmverwaltung erwähnt. Diese Befehle können – wie auch JOB zum Start eines Hintergrundprozesses – mit einem Timeout verwendet werden.
* Zur Variablenverwaltung sind die Befehle SET, READ und KILL sowie MERGE vorhanden. Letzterer für das einfache Kopieren von Arrays und Teilarrays. Z. B. globale Arrays in lokale. Diese Befehle plus ihre Argumente werden bei aktiviertem Journaling in einen Journalblock geschrieben.
* Der LOCK Befehl wird zur Verwendung bzw. Erzeugung von Semaphoren zur Prozesssynchronisation eingesetzt.
* Die Befehle DO, QUIT und GOTO dienen der Programmflusssteuerung. (z. B.: DO label^programm, DO label, DO ^programm). Bei einem Label-Aufruf mit DO innerhalb eines Programms muss QUIT als Rücksprungbefehl – mit bzw. ohne Rückgabewert – am Ende immer explizit angeführt werden. Zu dieser Gruppe gehört auch der JOB Befehl der ein Programm im Hintergrund startet. Der DO Befehl kann auch zur Blockstrukturierung der Programmansicht verwendet werden. Dazu wird ein argumentloses DO und unmittelbar folgende Zeilen mit „.“ Punkt an erster Stelle verwendet. Hier entfällt der QUIT Befehl.
* Der FOR Befehl dient zum Aufbau von flexiblen Schleifenkonstrukten mit oder ohne einer Laufvariablen (FOR i=1.5:0.1:10). Die Schrittweiten sind nicht fixiert und es können mehrere Bereiche angegeben werden. Die argumentlose Form muss mit einem QUIT als Abbruchbefehl – z. B. FOR SET a=a+1 IF a>10 QUIT – kombiniert werden, da sich eine Schleife bis zum Ende der aktuellen Zeile erstreckt. (z B. komplexe Schleifenstrukturen sind möglich: FOR I=2*N:0,5:X*N)
* IF und ELSE dienen für logische Prüfungen und können mit beliebig vielen logischen Tests in einem Befehlsargument, getrennt durch Beistrich, geschrieben werden. Sie sind dann logisch UND verknüpft. (Z. B. IF a=2,b=5,(d>25!d<10) DO..) Als Besonderheit testen ELSE und IF in der argumentlosen Form nur den Zustand der Systemvariablen $TEST die das Ergebnis der letzten logischen Prüfung enthält.
* XECUTE kann verwendet werden um einen in einer Variablen gespeicherten M Code auszuführen.
* Der VIEW Befehl erlaubt Zugriffe auf die Systemumgebung wie z. B. Hauptspeicher.
* HANG und HALT sind beides Befehle die auf H abgekürzt werden können. Mit einer Ziffer als Argument wird eine Programmpause von n Sekunden ausgeführt. Ohne Argument beendet der H Befehl das Programm und gibt die Partition frei.
* Zur MWAPI (u.A. Windows GUI) sind die Befehle der Eventsteuerung hinzugekommen: ESTART, ESTOP und ETRIGGER
* Für die Transaktionsverwaltung sind die Befehle TSTART, TCOMMIT, TROLLBACK, TRESTART und Systemvariablen zur Statusabfrage realisiert worden.

### Funktionen

M kennt insgesamt 22 Standardfunktionen, deren Namen mit einem $ beginnen. Zudem herstellerspezifische Funktionen mit $Z als Präfix. Jeder M-Funktionsname kann auf eine zur Unterscheidung notwendige minimale Anzahl von Buchstaben – meist 1 – verkürzt werden. Die Funktionsnamen sind so gewählt dass, bis auf wenige Ausnahmen, jeder Buchstabe des Alphabets nur einmal als Anfangsbuchstabe vorkommt. Alle Funktionsnamen sind nicht case sensitiv und bestehen aus einfachen englischen Vokabeln.

* Zur Typverarbeitung gehören: $ASCII(string) – gibt den ASCII-Wert eines Buchstabens im String aus, $CHAR(n) – erzeugt einen ASCII String aus den Zahlen n. $JUSTIFY(n), $FNUMBER(n) machen Formatierungen. $TRANSLATE(sting) übersetzt Zeichen (z. B. A nach a). $REVERSE(variable) reversiert. (z. B. variable nach elbairva)
* Datenbank Funktionen sind: $DATA(varname) – prüft das Vorhandensein von lokalen und globalen Variablen. $GET(varname) – holt Variablenwerte. Die Funktionen $NAME(var), $ORDER(var), $QLENGTH(var), $QSUBSCRIPT(var), $QUERY(var) analysieren den Indexbaum.
* String Analyse erfolgt mit: $EXTRACT(var), $PIECE(var). Strings zerlegen mittels: $FIND(var), $LENGTH(var), $SELECT(var),
* $RANDOM(n) für Zufallzahlenerzeugung, $STACK unterstützt das Errorhandling (Programmstack), $TEXT(n) erlaubt Zugriff auf Programmcode, $VIEW für Analyse der I/O Kanäle und Systemumgebung.

### M-Variablen

Die Systemvariablen geben dem Programmierer Informationen über die Programmumgebung und Fehlerbedingungen. $DEVICE, $ECODE, $ESTACK, $ETRAP, $HOROLOG, $IO, $JOB, $KEY, $PRINCIPAL, $QUIT, $REFERENCE, $STACK, $STORAGE, $SYSTEM, $TEST, $X, $Y.

Auch hier ist eine Abkürzung auf den 1 bzw. 2 Buchstaben möglich. Häufig verwendet sind

$H=Tage sei 31.12.1840,Sekunden seit Mitternacht

$T=Auswertung des letzten IF oder eines Befehles mit Timeout.

$X, $Y = Cursorposition auf dem aktuellen Gerät

$JOB = ist die jeweilige Prozessnummer

### M-Operatoren

* Mathematische Operatoren sind a+b, a-b, a*b, a/b. Ein \ als Ganzzahl-Divisor, # für die (echte) Modulodivision und ** für Exponentialfunktionen: z. B. 2**3=8, 2**(1/3)=2
* Die logischen Operatoren sind =, >, <. Das ` (ASCII 96) Zeichen für logische Verneinung. Logisches UND wird mit & (Ampersand) und logisches ODER mit ! (Rufezeichen) ermittelt. ( a&b bzw. a!b)
* Mit den eckigen Klammern können Stringvergleichsoperationen ausgeführt werden: String folgt mit ], String enthält mit [, Sortierfolge nach/vor mit doppelter eckiger Klammer ]]. Das „?“ für spezielle exakte Mustervergleiche : wie z. B. "ABC"?3U oder "123-45-6789"?3N1"-"2N1"-"4N ( 3 Nummerisch, ein Bindestrich, 2 Nummerisch, etc.)

### Spezielle System-Variablen (ssvs)

Die "Structured System Variables" werden verwendet, um bestimmte System-Informationen im Detail abzufragen: ^$GLOBAL, ^$JOB, ^$LOCK, ^$ROUTINE, ^$SYSTEM

Z. B.: ^$JOB(prozessummer) gibt 23 Parameter eines bestimmten Prozesses aus, ähnlich vielfältig ist die Information die in der ^$SYSTEM enthalten ist.

### Diverses

* Wird ein "+" (Pluszeichen) vor den Variablennamen gesetzt, wird vom Variablenwert nur der Teilstring bis zum ersten nichtnumerischen Zeichen verwendet.
* Ausgabeformatierung bei WRITE- oder READ-Befehlen: Ein „!“ (Rufezeichen) wird zur Ausgabe eines CR/LF, CR oder LF – je nach OS – verwendet. Ein "#" (Rautezeichen) wird als Seitenvorschub (ASCI 12 – Form Feed) ausgegeben. Ein "?" (Fragezeichen) positioniert den Cursor an eine bestimmte Zeilenposition. (Z. B.: ?20)
* In einer Programmzeile wird der gesamte Text nach einem ";" (Strichpunkt) vom Interpreter ignoriert (Kommentar-Trenner).
* Der _ (Underliner) wird zur Stringverknüfung verwendet: "Hier "_"ist ein Text" > "Hier ist ein Text"

### M Windowing Application Programming Interface – MWAPI

Die Sprachanforderungen für eine GUI Programmierung (Graphical User Interface) wurde Mitte 1992 mit dem Entwurf des MWAPI (M Application Programming Interface) erfüllt und dann im 1993er Standard festgelegt. Zuvor gab es schon mehrere nicht befriedigende proprietäre Lösungen. MWAPI war ein gänzlich neuer Ansatz, der nicht nur für MS-Windows, sondern alle damals bekannten „Fenster“ gedacht war: X-Windows, OS/2, Motif und Apple Mac.

Der MWAPI Standard hat zwei wesentliche Komponenten:

^$WINDOW

Zum einen ist dies die Darstellung eines „Applikations-Fensters“ kurz Windows, inklusive der darin enthaltenen Objekte wie Button, Menü, Listboxen, Textfelder, usw. als objektorientiertes Datenbankobjekt – was aufgrund der Stärken von M im Datenbankbereich nahe lag. Diese Daten beschreiben die im Fenster enthaltenen Objekte, mit denen der Anwender bei der Nutzung der Oberfläche arbeitet. D.h. es sind alle Objekte, dazugehörigen Attribute und Methoden für alle Fenster/Windows und deren Objekte als Daten (global) abgelegt.

Der Übergang vom Datenbank-Objekt zum „echten“ Windows Objekt erfolgte, indem man diesen Global mit einem einzigen MERGE-Befehl (Kopieren von Arrays) in die strukturierte Systemvariable ^$W (ssvn) kopiert (z. B. M ^$W=^EW). Damit wird das „Datenbank - Window“ an die jeweilige Windows Engine zur Darstellung übergeben und diese fügt im Sinne der Vererbung auch alle notwendigen, noch fehlenden Attribute vom Parent-Objekt (Windows Instanz) zum Child-Objekt hinzu. Damit ist die Bildschirmmaske bereits, ohne Funktionsaufrufe wie in anderen Sprachen, nur mit bereits vorhandenen Sprach- und Datenbank Elementen dargestellt.

Beispiel – Ausschnitte der Datenstruktur des Windows „USI1PA“ und eines „Button1“ und „Button 2“ (Schaltfläche).

Natürlich wurde üblicherweise diese Datenstruktur nicht händisch erstellt – ein entsprechender grafischer Editor bzw. Entwicklerumgebung ist vorteilhaft.

Die Eventsteuerung – Ereignisorientierte Programmierung

Zum Anderen: Wie am obigen Beispiel erkennbar, hat das Objekt „Button1“ ein EVENT – Attribut. Mit der Benutzeraktivität d. h. dem Event „SELECT“ (draufklicken) würde ein DO-Befehl auf das Label %2 im Programm ^USI1PAg ausgeführt. Die Aktivierung der Eventsteuerung wird nach der Darstellung des „Windows“ im zweiten Schritt mit dem Befehlt ESTART ausgelöst. Erst mit dem Verlassen / Schließen des Windows oder in der Fehlerbehandlung wird diese wieder mit ESTOP gestoppt. Die eventgesteuerte Programmierung, also das Darlegen der Benutzermöglichkeiten (Applikationswindows) und dann das Reagieren auf „irgendeine“ Benutzer-Aktion, sei es mit Maus oder Tastatur, war für die M-Entwickler etwas völlig Neues. Die lineare Programmierung, also Führung eines Anwenders durch das Programm, entfällt, es wird nur noch auf Benutzeraktionen reagiert. Wiewohl durch den klugen Ansatz im MWAPI Konzept (DO Einsprung auf ein Programm-Label) alte Anwendungen sehr gut für Prüfungen, Datenspeicherung etc. weiterverwendet werden konnten.

Implementierung von MWAPI

Das MWAPI wurde 1995 als prägend für die kommerzielle Windows Programmierung und M gesehen. Die erste echte performante, praktikable Version 2.0.0 erschien Anfang 1998 von Micronetics als MSM-Workstation. Die Oberfläche und Handling dieser Entwicklungsumgebung war stark an MS-Visual Basic 4.0 angelehnt und tatsächlich auch zum Teil damit entwickelt worden. D.h. die MSM-Workstation kann wie Visual Basic auch alle Windows Bibliotheken, Add-Ons und Objekte verwenden. (DDL, OCX, MS-Office Objekte, etc.) Eine Eigenschaft, die bereits im 1993er Standard unter "Syntax externer Programmaufrufe" geregelt wurde. Als Endprodukt entstand ein Windows Programm als EXE-Datei. Selbstverständlich war sie auch als Client für M-Server Systeme konzipiert, konnte auch mit Cache, anderen M-Versionen und Borland-Produkten (Delphi) kommunizieren. Durch die Kannibalisierung des M-Markts durch die Firma Intersystems, welche den MWAPI Standard ablehnte, wurde die MSM-Workstation nach dem Kauf von Micronetics durch Intersystems eingestellt. Damit hatte die dasselbe Schicksal wie MWAPI von DEC und DTM, die frühzeitig verschwanden. Sie ist von Intersystems als open software freigegeben worden und noch vielerorts in Verwendung und als Abkömmling von MS-Visual Basic auch noch unter Windows 10 nutzbar

## Kodierung und Ergebnis

Das klassische Beispiel kann mit "ZS HELLOWOR" auf Medien abgespeichert und mit "DO ^HELLOWOR" gestartet werden oder alternativ mit "D WRI^HELLOWOR"

Die Ausgabe am Bildschirm jeweils

## Verbreitete Kritikpunkte

Mumps wurde entwickelt, bevor den Programmierern viele Vorgaben durch eine strenge Sprachsyntax gemacht wurden, (strukturierte Programmierung) z. B. Variablendeklaration (durch RDMS notwendig), Klammersetzung, Programmstruktur, Einrückungen usw. Der Sinn dieser Vorgaben ab den achtziger Jahren des vorigen Jahrhunderts waren, den Dokumentationsaufwand und die Gesamtentwicklungszeit planbar zu machen. Wobei M bei allen Untersuchungen die höchste Produktivität bei LOC Studien (Line of Code) hat.

Da sowohl lokale Variablen als auch syntaktische Elemente gleich benannt werden können (ein NoGo) und Befehle und Funktionen auf einen Buchstaben abgekürzt werden können, ist M-Programmcode in vielen Fällen nur nach Einarbeitung und Übung lesbar. Jede Entwicklungsumgebung erlaubt selbstverständlich, Abkürzungen der Syntax auch auf Langform darzustellen und natürlich Syntaxüberprüfungen usw. zu erlauben.

Im Programmstandard und in den ersten 20 Jahren der Programmentwicklung wurde in der IT und bei allen Sprachen grundsätzlich wenig Wert auf den Datenschutz gelegt. Der Schutz der Daten in der M-Datenbank ist nicht sonderlich komplex. Ähnlich wie bei Unix/Linux gibt es nur vier Gruppen, in die sich die Anwender gliedern. SYSTEM, USER, GROUP, WORLD.

