The pymdl book
4. Basic introduction
This chapter introduces the listener, input conventions, files, and error recovery. Start pymdl using the commands in chapter 2, then try the expressions as you read. Part II develops the language from these first interactions through functions, data structures, and control flow. Compiled programs are covered in chapter 33.
1. Basic Introduction
The purpose of this chapter is to provide you with that minimal amount of information needed to experiment with MDL while reading this document. It is strongly recommended that you do experiment, especially upon reaching chapter 8 (Simple Functions).
pymdl's own. Every example in this book that is marked
mdlis run by the test suite against a fresh interpreter, so the answers printed beside them are this implementation's, today. Experimenting is the same thing by hand: start the listener (chapter 2) and type.
1.1. Loading MDL
First, catch your rabbit. Somehow get the interpreter running -- the program
in the file SYS:TS.MDL in the ITS version or SYS:MDL.SAV in the Tenex
version or SYS:MDL.EXE in the Tops-20 version. The interpreter will first
type out some news relating to MDL, if any, then type
LISTENING-AT-LEVEL 1 PROCESS 1
and then wait for you to type something.
The program which you are now running is an interpreter for the language MDL. All it knows how to do is interpret MDL expressions. There is no special "command language"; you communicate with the program -- make it do things for you -- by actually typing legal MDL expressions, which it then interprets. Everything you can do at a terminal can be done in a program, and vice versa, in exactly the same way.
The program will be referred to as just "MDL" (or "the interpreter") from here on. There is no ambiguity, since the program is just an incarnation of the concept "MDL".
pymdl's own. The incarnation here is
python -m pymdl.repl(chapter 2), and it prints the same line when it starts. The manual's point survives the change of machine exactly: there is no command language, the listener reads MDL, and anything you can type you can put in a file or a program.
1.2. Typing
Typing a character at MDL normally just causes that character to be echoed (printed on your terminal) and remembered in a buffer. The only characters for which this is normally not true act as follows:
Pressing ESC causes MDL to echo $ and evaluate the expressions in the
input buffer. It then prints the results and waits for more input. In the
manual's transcripts, $ represents the ESC key; do not type a literal
dollar sign to submit an expression.
Typing the rubout character (DEL in the ITS and Tops-20 versions, CTRL+A in the Tenex version) causes the last character in the buffer -- the one most recently typed -- to be thrown away (deleted). If you now immediately type another rubout, once again the last character is deleted -- namely the second most recently typed. Etc. The character deleted is echoed, so you can see what you're doing. On some "display" terminals, rubout will "echo" by causing the deleted character to disappear. If no characters are in the buffer, rubout echoes as a carriage-return line-feed.
Typing ^@ (CTRL+@) deletes everything you have typed since the last $,
and prints a carriage-return line-feed.
Typing ^D (CTRL+D) causes the current input buffer to be typed back out at
you. This allows you to see what you really have, without the confusing
re-echoed characters produced by rubout.
Typing ^L (CTRL+L) produces the same effect as typing ^D, except that, if
your terminal is a "display" terminal (for example, IMLAC, ARDS, Datapoint),
it first clears the screen.
Typing ^G (CTRL+G) causes MDL to stop whatever it is doing and act as if an
error had occurred (section 1.4). ^G is generally most useful for
temporary interruptions to check the progress of a computation. ^G is
"reversible" -- that is, it does not destroy any of the "state" of the
computation it interrupts. To "undo" a ^G, type the characters
<ERRET T>$
(This is discussed more fully far below, in section 16.4.)
Typing ^S (CTRL+S) causes MDL to throw away what it is currently doing
and return to a normal "listening" state. (In the Tenex and Tops-20
versions, ^O also should have the same effect.) ^S is generally most
useful for aborting infinite loops and similar terrible things. ^S
destroys whatever is going on, and so it is not reversible.
Most expressions in MDL include "brackets" (generically meant) that must be
correctly paired and nested. If you end your typing with the pair of
characters !$ (!+ESC), all currently unpaired brackets (but not
double-quotes, which bracket strings of characters) will automatically be
paired and interpretation will start. Without the !, MDL will just sit
there waiting for you to pair them. If you have improperly nested
parentheses, brackets, etc., within the expression you typed, an error will
occur, and MDL will tell you what is wrong.
Once the brackets are properly paired, MDL will immediately echo
carriage-return and line-feed, and the next thing it prints will be the
result of the evaluation. Thus, if a plain $ is not so echoed, you have
some expression unclosed. In that case, if you have not typed any characters
beyond the $, you can usually rub out the $ and other characters back to
the beginning of the unclosed expression. Otherwise, what you have typed is
beyond the help of rubout and ^@; if you want to abort it, use ^S.
MDL accepts and distinguishes between upper and lower case. All "built-in functions" must be referenced in upper case.
pymdl's own. Every one of those keys works at pymdl's listener and chapter 2 tabulates them, including
!$. Two notes.^Greally is an error here as it was there --*ERROR* CONTROL-G?and a new listening level, measured on MDL 55 -- and not a printed imitation of one; and when standard input is not a terminal there is no character mode at all, so a newline is whitespace and forms may span lines (chapter 2). The Tenex personality's quit character is^A, as the manual says.
1.3. Loading a File
If you have a program in MDL that you have written as an ASCII file on some device, you can "load" it by typing
<FLOAD file>$
where file is the name of the file, in standard operating-system syntax,
enclosed in "s (double-quotes). Omitted parts of the file name are taken
by default from the file name DSK: INPUT > (in the ITS version) or
DSK: INPUT.MUD (in the Tenex and Tops-20 versions) in the current disk
directory.
Once you type $, MDL will process the text in the file (including FLOADs)
exactly as if you had typed it on a terminal and followed it with $, except
that "values" produced by the computations are not printed. When MDL is
finished processing the file, it will print DONE.
When MDL starts running, it will FLOAD the file MUDDLE INIT (ITS version)
or MUDDLE.INIT (Tenex and Tops-20 versions), if it exists.
pymdl's own. Both hold. A file specification lands under pymdl's file root by the rules chapter 2 tabulates, the default first and second names are the manual's
INPUTand>(orMUDunder the Tenex personality), and the listenerFLOADsMUDDLE INITwhen it starts.FLOADanswers theSTRING"DONE".
1.4. Errors -- Simple Considerations
When MDL decides for some reason that something is wrong, the standard sequence of evaluation is interrupted and an error function is called. This produces the following terminal output:
*ERROR*
often-hyphenated-reason
function-in-which-error-occurred
LISTENING-AT-LEVEL integer PROCESS integer
You can now interact with MDL as usual, typing expressions and having them evaluated. There exist facilities (built-in functions) allowing you to find out what went wrong, restart, or abandon whatever was going on. In particular, you can recover from an error -- that is, undo everything but side effects and return to the initial typing phase -- by typing the following first line, to which MDL will respond with the second line:
<ERRET>$
LISTENING-AT-LEVEL 1 PROCESS 1
If you type the following first line while still in the error state (before
<ERRET>), MDL will print, as shown, the arguments (or "parameters" or
"inputs" or "independent variables") which gave indigestion to the unhappy
function:
<ARGS <FRAME <FRAME>>>$
[ arguments to unhappy function ]
This will be explained by and by.
<+ 1 FOO>$
*ERROR*
UNASSIGNED-VARIABLE
FOO
GVAL
LISTENING-AT-LEVEL 2 PROCESS 1
<ARGS <FRAME <FRAME>>>$
[FOO GVAL]
<ERRET>$
LISTENING-AT-LEVEL 1 PROCESS 1
Measured, MDL 55. The banner is the era's, irritants and all, and chapter 19 has it in full: the reason is an
ATOMfrom theERRORSoblist,PRINCed without its trailer; each irritant goes on its own line; levels are counted per process, so the number afterPROCESSis not decoration. pymdl's listener reproduces it, and the error handler's behaviour after the banner -- whatERRETreturns to, whether a nested error stacks, whatRETRYdoes -- was measured form by form in one stateful era session (chapter 37).