The simplest way to construct a list is to use square brackets. But there are several others:
These "list constant brackets" may contain text items, i.e words, numbers strings, lists, or anything else. E.g.:
[ A B C D] is a list of four words [1 cat 2 dog 3 pig ] is a list of six items. [string 'a short string' 66] is a list with a word a string and a number.[] is the empty list. There's more on this below.
List brackets may also be used to construct lists which contain lists, E.g.:
[ [1 2] [3] 4 ]is a list with two lists of numbers and one number. It contains exactly three elements, of which the first contains two elements.
A list can also contain vectors, signified with the vector brackets { } which themselves can enclose further lists or vectors to any depth: e.g. (using more spaces than necessary, for clarity):
[ a b { c d [ e { f } ] } [ g h ] ]This is a list containing four items: two (quoted) words "a" and "b", a vector { c d [ e { f } ] } and a two element list [ g h ].
The words in a list are by default quoted, apart from the list and vector brackets, which signify embedded lists and vectors.
So even if the words are Pop-11 identifiers, their values are not inserted in the list, just the words themselves. (This is unlike the convention in Lisp, where, by default, the values are inserted.)
Example:
[true false if + * then sqrt ] => ** [true false if + * then sqrt]
In order to get the contents of a list (or vector) expression evaluated,
or unquoted, it is possible to use either ^
or matching pairs of % ... %
as in this deliberately confusing example
vars x = "cat", cat = "x"; [x cat ^x ^cat] => ** [x cat cat x]which is equivalent to each of
[x cat %x% %cat%] => [x cat %x, cat%] => [% "x", "y", x, cat %] =>Another example would be
vars n1 = 5, n2 = 7; [the sum of n1 and n2 is %n1 + n2%] => ** [the sum of n1 and n2 is 12]So, in order to insert the value of a single variable, it is simplest to use
^
variable, whereas pairs of percents % ... % may be more
appropriate for longer expressions to be evaluated.
NOTE: ^
cannot cannot be used outside a list or vector expression.
However, % has an additional use in forming closures, using partial
application, as described in Chapter 4, and HELP PERCENT
Between the percent signs in a list or vector expression the normal syntactic rules for Pop-11 apply, so that, for example, expressions must be separated by commas, and in order to quote a word the word quote symbol `"' must be used.
For historical reasons, the use of the percent symbols is equivalent
to the use of ^
followed by a parenthesized expression. Thus, the
last two examples could be written
[ ^( "x", "y", x, cat )] => [the sum of n1 and n2 is ^(n1 + n2)] =>There is no difference in meaning or efficiency between
^
( ... ) and
% ... %.
If embedded list or vector expressions are used inside these "unquoted"
portions of a list, then by default they too quote their contents,
unless % or ^
is used to unquote, e.g.
[% [two words], [% n1, "a"%], [% n2 % b c] %] => ** [[two words] [5 a] [7 b c]]is a list of three lists, whose contents depend on the values of the identifiers n1 and n2, but treats all other words as quoted.
The symbol "%" can occur anywhere in a list expression (or vector expression). But it must occur in pairs. Roughly speaking, in a list the first occurrence of each pair means: "switch from quoting to non-quoting mode", and the second occurrence means "switch from non-quoting to quoting mode". In non-quoting mode variables are replaced by their values and any procedures are run and their values are inserted in the list instead of the names of the procedures being put in the list.
There is no restriction at all on the sequence of expressions that can occur in the unquoted portion of a list. The Pop-11 instructions are run, and any results produced that are left on the stack will be incorporated in the final list.
So for example, it is possible to use a loop between % .. % to create a list of numbers.
vars n; [% for n from 1 to 20 do n endfor % ] => ** [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]Similarly the contents of the list, may be conditional on something else, as in
[The list was % if n > 15 then "big" else "small" endif % ] => ** [The list was big]