Some excellent questions from an audience member about the differences between ZIL/MDL and Lisp merit a response here.
This question made me realize I misspoke when I said evaluating a list produces a new list with the same contents. It actually produces a new list with the evaluation of the first list’s contents. I’ve edited my earlier post, and I shall briefly hang my head in shame before continuing.
Now then!
MDL has its own version of quoting: <QUOTE (THIS IS A LIST)>, when evaluated, will return the list unchanged. This can be abbreviated as an apostrophe prefix: '(1 2 3).
It often appears in the argument list of macro definitions:
<DEFMAC PROB ('A)
<FORM L? <FORM RANDOM 100> .A>>
In that context, it means that the argument supplied at the macro call site won’t be evaluated, i.e., it’s effectively quoted. In other words, if you write <PROB <+ 1 2>>, then .A will expand to the form <+ 1 2>, not the number 3; the macro can then return that form inside the new form it creates. This is almost always what you want, so the arguments in macro definitions are almost always quoted.
You might also see quoting inside the body of a macro if it returns some code that never varies:
<DEFMAC SHORT-REPORT? ()
'<=? ,REPORT-MODE ,SHORT-REPORT>>
A parenthesized list without quoting will, when evaluated, first evaluate everything inside it and then wrap it in a new list. So evaluating (<+ 10 1> <+ 20 2> <+ 30 3>) will perform all three additions and return (11 22 33). A list of questions gets you a list of answers.
But what about all the parentheses we see in `COND`s and object definitions? They aren't quoted, so are they evaluated?
Well, OBJECT evaluates all of its arguments, so every property definition in an object is in fact evaluated. This is handy when you want the property value to be something other than a simple constant. For example, you can initialize a property to point to a table elsewhere in RAM:
<OBJECT NOTEPAD
(CONTENTS <ITABLE BYTE 200>)>
By the time OBJECT sees it, ITABLE has already been called and returned the address of a freshly allocated table.
On the other hand, COND is an FSUBR[1], which is the equivalent of a special form in Lisp: it doesn’t evaluate all of its arguments automatically, because it contains its own logic about which of them to evaluate and when.
“Single-namespace” means functions and variables share the same namespace, so you can’t have a function and a variable with the same name; only one of them is visible at any given point. “Dual-namespace” means they have their own namespaces, and passing a function as an argument requires explicit syntax to tell the system you want the function.
Answer: it’s dual-namespace, but not quite in the same way.
An atom can have a global value[2], which is accessed with SETG and a comma prefix[3]. It can also have a local value, which is accessed with SET and a period prefix[4]. By default, functions are stored in the global values: ,SANDWICH-BAG-FCN will return the function with that name in interpreted code (or the address of the routine with that name in compiled code). That means you can give a local variable the same name as a global variable and still access both, because you always have to be explicit about which one you’re using, but functions share a namespace with global variables.
Precisely. According to the MDL manual, “FIX means integer, because the decimal point is understood always to be in a fixed position: at the right-hand end.”
The name made more sense in the original MDL, since it also supported floating-point numbers (type FLOAT), which ZILF doesn’t.