summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Whitten <whitten@worldvista.org>2023-12-14 09:46:30 -0500
committerGitHub <noreply@github.com>2023-12-14 15:46:30 +0100
commit88ce2147560246483a4aad78c6bfd73d0dc42f38 (patch)
treee5d192ed4cc1ba041cea445093451cc9fad83844
parente74217e5cf63894aaf76fe66fa3f38cbc7b2c506 (diff)
expanded m.html.markdown (#4036)
Slightly re-arranged and including more explanations and links.
-rw-r--r--m.html.markdown101
1 files changed, 66 insertions, 35 deletions
diff --git a/m.html.markdown b/m.html.markdown
index 87e0875e..46e7313b 100644
--- a/m.html.markdown
+++ b/m.html.markdown
@@ -17,8 +17,8 @@ more fits on one screen without scrolling.
The M database is a hierarchical key-value store designed for high-throughput
transaction processing. The database is organized into tree structures called
-"globals", which are sparse data structures with parallels to modern formats
-like JSON.
+"globals", (for global variables) which are sparse data structures with parallels
+to modern formats like JSON.
Originally designed in 1966 for the healthcare applications, M continues to be
used widely by healthcare systems and financial institutions for high-throughput
@@ -26,7 +26,7 @@ real-time applications.
### Example
-Here's an example M program to calculate the Fibonacci series:
+Here's an example M program using expanded syntax to calculate the Fibonacci series:
```
fib ; compute the first few Fibonacci terms
@@ -39,28 +39,38 @@ fib ; compute the first few Fibonacci terms
```
### Comments
+Comments in M need at least one space before the comment marker of semicolon.
+Comments that start with at least two semicolons (;;) are guaranteed to be accessible
+within a running program.
```
-; Comments start with a semicolon (;)
+ ; Comments start with a semicolon (;)
```
### Data Types
-M has two data types:
+M has one data type (String) and three interpretations of that string.:
```
-; Numbers - no commas, leading and trailing 0 removed.
-; Scientific notation with 'E'.
-; Floats with IEEE 754 double-precision values (15 digits of precision)
-; Examples: 20, 1e3 (stored as 1000), 0500.20 (stored as 500.2)
; Strings - Characters enclosed in double quotes.
; "" is the null string. Use "" within a string for "
; Examples: "hello", "Scrooge said, ""Bah, Humbug!"""
+;
+; Numbers - no commas, leading and trailing 0 removed.
+; Scientific notation with 'E'. (not 'e')
+; Numbers with at least with IEEE 754 double-precision values (guaranteed 15 digits of precision)
+; Examples: 20 (stored as 20) , 1e3 (stored as 1000), 0500.20 (stored as 500.2),
+; the US National Debt AT sometime on 12-OCT-2020 retrieved from http://www.usdebt.org is 27041423576201.15)
+; (required to be stored as at least 27041422576201.10 but most implementations store as 27041432576201.15)
+;
+; Truthvalues - String interpreted as 0 is used for false and any string interpreted as non-zero (such as 1) for true.
```
### Commands
-Commands are case insensitive, and have a shortened abbreviation, often the first letter. Commands have zero or more arguments,depending on the command. M is whitespace-aware. Spaces are treated as a delimiter between commands and arguments. Each command is separated from its arguments by 1 space. Commands with zero arguments are followed by 2 spaces.
+Commands are case insensitive, and have full form, and a shortened abbreviation, often the first letter. Commands have zero or more arguments,depending on the command. This page includes programs written in this terse syntax. M is whitespace-aware. Spaces are treated as a delimiter between commands and arguments. Each command is separated from its arguments by 1 space. Commands with zero arguments are followed by 2 spaces. (technically these are called argumentless commands)
+
+#### Common Commands from all National and International Standards of M
-#### W(rite)
+#### Write (abbreviated as W)
Print data to the current device.
@@ -68,13 +78,19 @@ Print data to the current device.
WRITE !,"hello world"
```
-! is syntax for a new line. Multiple statements can be provided as additional arguments:
+Output Formatting characters:
+
+ The ! character is syntax for a new line.
+ The # character is syntax for a new page.
+ The sequence of the ? character and then a numeric expression is syntax for output of spaces until the number'th colum is printed.
+
+Multiple statements can be provided as additional arguments before the space separators to the next command:
```
w !,"foo bar"," ","baz"
```
-#### R(ead)
+#### Read (abbreviated as R)
Retrieve input from the user
@@ -82,13 +98,13 @@ Retrieve input from the user
READ var
r !,"Wherefore art thou Romeo? ",why
```
-Multiple arguments can be passed to a read command. Constants are outputted. Variables are retrieved from the user. The terminal waits for the user to enter the first variable before displaying the second prompt.
+As with all M commands, multiple arguments can be passed to a read command. Constants like quoted strings, numbers, and formatting characters are output directly. Values for both global variables and local variables are retrieved from the user. The terminal waits for the user to enter the first variable before displaying the second prompt.
```
r !,"Better one, or two? ",lorem," Better two, or three? ",ipsum
```
-#### S(et)
+#### Set (abbreviated as S)
Assign a value to a variable
@@ -100,19 +116,21 @@ w !,centi,!,micro
;.01
;.00001
```
-#### K(ill)
+#### Kill (abbreviated as K)
Remove a variable from memory or remove a database entry from disk.
-
+A database node (global variable) is killed depending on the variable name being prefixed by the caret character (^).
+If it is not, then the local variable is removed from memory.
+If KILLed, automatic garbage collection occurs.
```
KILL centi
k micro
```
### Globals and Arrays
-In addition to local variables, M has persistent variables stored to disk called _globals_. Global names must start with a __caret__ (__^__). Globals are the built-in database of M.
+In addition to local variables, M has persistent, shared variables that are the built-in database of M. They are stored to disk and called _globals_. Global names must start with a __caret__ (__^__).
-Any variable can be an array with the assignment of a _subscript_. Arrays are sparse and do not have a predefined size. Arrays should be visualized like trees, where subscripts are branches and assigned values are leaves. Not all nodes in an array need to have a value.
+Any variable (local or global) can be an array with the assignment of a _subscript_. Arrays are sparse and do not have a predefined size. Only if data is stored will a value use memory. Arrays should be visualized like trees, where subscripts are branches and assigned values are leaves. Not all nodes in an array need to have a value.
```
s ^cars=20
@@ -128,7 +146,7 @@ w !,^cars("Tesla",1,"Name")
; Model 3
```
-Arrays are automatically sorted in order. Take advantage of the built-in sorting by setting your value of interest as the last child subscript of an array rather than its value.
+The index values of Arrays are automatically sorted in order. There is a catchphrase of "MUMPS means never having to say you are sorting". Take advantage of the built-in sorting by setting your value of interest as the last child subscript of an array rather than its value, and then storing an empty string for that node.
```
; A log of temperatures by date and time
@@ -171,13 +189,14 @@ s ^TEMPS("11/12","1700",43)=""
#### Order of operations
Operations in M are _strictly_ evaluated left to right. No operator has precedence over any other.
-You should use parentheses to group expressions.
+For example, there is NO order of operations where multiply is evaluated before addition.
+To change this order, just use parentheses to group expressions to be evaluated first.
```
w 5+3*20
;160
;You probably wanted 65
-w 5+(3*20)
+write 5+(3*20)
```
### Flow Control, Blocks, & Code Structure
@@ -193,7 +212,7 @@ w !,$$tag^routine(a,b)
M has an execution stack. When all levels of the stack have returned, the program ends. Levels are added to the stack with _do_ commands and removed with _quit_ commands.
-#### D(o)
+#### Do (abbreviated as D)
With an argument: execute a block of code & add a level to the stack.
@@ -216,12 +235,14 @@ if a=1 do
w "hello"
```
-#### Q(uit)
+#### Quit (abbreviated as Q)
Stop executing this block and return to the previous stack level.
-Quit can return a value.
+Quit can return a value, following the comamnd with a single space.
+Quit can stop a loop. remember to follow with two spaces.
+Quit outside a loop will return from the current subroutine followed by two spaces or a linefeed
-#### N(ew)
-Clear a given variable's value _for just this stack level_. Useful for preventing side effects.
+#### New (abbreviated as N)
+Hide with a cleared value a given variable's value _for just this stack level_. Useful for preventing side effects.
Putting all this together, we can create a full example of an M routine:
@@ -233,20 +254,22 @@ main
n length,width ; New length and width so any previous value doesn't persist
w !,"Welcome to RECTANGLE. Enter the dimensions of your rectangle."
r !,"Length? ",length,!,"Width? ",width
- d area(length,width) ;Do a tag
- s per=$$perimeter(length,width) ;Get the value of a function
+ d area(length,width) ;Do/Call subroutine using a tag
+ s per=$$perimeter(length,width) ;Get the value of a function
w !,"Perimeter: ",per
- q
+ quit
area(length,width) ; This is a tag that accepts parameters.
; It's not a function since it quits with no value.
w !, "Area: ",length*width
- q ; Quit: return to the previous level of the stack.
+ q ; Quit: return to the previous level of the stack.
perimeter(length,width)
- q 2*(length+width) ; Quits with a value; thus a function
+ q 2*(length+width) ; Returns a value using Quit ; this is a function
```
+
+
### Conditionals, Looping and $Order()
F(or) loops can follow a few different patterns:
@@ -255,13 +278,15 @@ F(or) loops can follow a few different patterns:
;Finite loop with counter
;f var=start:increment:stop
-f i=0:5:25 w i," " ;0 5 10 15 20 25
+f i=0:5:25 w i," "
+;0 5 10 15 20 25
; Infinite loop with counter
; The counter will keep incrementing forever. Use a conditional with Quit to get out of the loop.
;f var=start:increment
-f j=1:1 w j," " i j>1E3 q ; Print 1-1000 separated by a space
+f j=1:1 w j," " i j>1E3 q
+; Print 1-1000 separated by a space
;Argumentless for - infinite loop. Use a conditional with Quit.
; Also read as "forever" - f or for followed by two spaces.
@@ -355,7 +380,11 @@ f s date=$ORDER(^TEMPS(date)) q:date="" d
## Further Reading
-There's lots more to learn about M. A great short tutorial comes from the University of Northern Iowa and Professor Kevin O'Kane's [Introduction to the MUMPS Language][1] presentation.
+There's lots more to learn about M. A great short tutorial comes from the University of Northern Iowa and Professor Kevin O'Kane's [Introduction to the MUMPS Language][1] presentation. More about M using VistA is at
+
+Intersystems has some products which are a super-set of the M programming language.
+* [Iris Description Page][5]
+* [Cache Description Page][6]
To install an M interpreter / database on your computer, try a [YottaDB Docker image][2].
@@ -368,3 +397,5 @@ YottaDB and its precursor, GT.M, have thorough documentation on all the language
[2]: https://yottadb.com/product/get-started/
[3]: https://docs.yottadb.com/ProgrammersGuide/langfeat.html
[4]: http://tinco.pair.com/bhaskar/gtm/doc/books/pg/UNIX_manual/index.html
+[5]: https://www.intersystems.com/products/intersystems-iris/
+[6]: https://en.wikipedia.org/wiki/InterSystems_Caché