TEACH LISTSUMMARY Aaron Sloman, updated Oct 1986
A PARTIAL SUMMARY OF LIST-PROCESSING IN POP11
CONTENTS - (Use <ENTER> g to access desired sections sections)
-- CREATING LISTS
-- ACCESSING COMPONENTS OF LISTS
-- MISCELLANEOUS PROCEDURES
-- GLOBAL VARIABLE (EMPTY LISTS)
-- CREATING LISTS -----------------------------------------------------
>>>> [ ]
These "list constant brackets" may contain text items, i.e words,
numbers and strings. 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. Can also be called NIL.
List brackets may also contain lists, E.g.:
[ [1 2] [3] 4 ] is a list with two lists and one number.
It contains exactly three elements, of which the first contains two.
>>>> [% %]
These "decorated list brackets" are used to create lists whose contents
depend on the values of variables or the results of executing
procedures. For instance:
[% 3, cat, hd(l) %]
is a list containing the number 3, the value of the variable CAT and the
first element of L, which must be a list, whereas
[ 3, cat, hd(l) ]
contains the number 3, the comma, the word "CAT", a comma, the word
"HD", the word "(", etc.
[% [% a %], [% b, c%], [% d %] %]
is a list of three lists, whose contents depend on the values of A B C
and D.
>>>> ^ (the "up-arrow" or "hat" symbol)
Can be used in place of "%". For example
[ ^x + ^y is ^(x + y) ] is the same as
[% x, "+", y, "is", x + y %] and
[ %x% + %y% is %x + y% ]
When followed by a variable, "^" means: "use the value of this
variable". When followed by a parenthesised expression, it means:
"use the value of the parenthesised expression".
>>>> ^^ (double "up-arrow" or "hat" symbol)
This is used to merge the contents of a list into an enclosing list.
Thus:
[ b c d ] -> list;
[a ^list e ] =>
** [a [b c d] e]
[a ^^list e ] =>
** [a b c d e]
The prefix "^^" can be thought of as "remove the list brackets".
>>>> ::
This is an operation for joining an element onto an existing list, to
make a new list, e.g.
3 :: [4 5 6] is a list of four numbers.
"cat" :: [] is the same as [cat]
"cat" :: "dog" will cause an error,
since :: must have a list as its second argument. Notice that
x :: y
is equivalent to
[^x ^^y]
The operation :: is easier for the machine, but otherwise has no
advantage.
>>>> CONSPAIR
This is a procedure, which can be thought of as equivalent to :: .
That is
conspair(x,l)
is the same as
x :: l
The only difference is that the second argument of CONSPAIR need not be
a list. E.g.
conspair(3, 4) -> l;
l =>
** [3|4] ;;; note the use of the vertical bar - indicating that
;;; the second element is not a list
tl(l) =>
This now produces an error, because TL insists on a proper list, and a
pair whose second element is not a pair is not acceptable. The procedure
BACK has no such qualms.
back(l) =>
** 4
CONSPAIR is rarely needed in straightforward programs.
>>>> <>
This is an operator which takes two lists and "concatenates" them to
produce a new list. The first list is copied, so that the original does
not have any extra elements added to its end. E.g.
[cat dog ] <> [pig mouse]
is the same as:
[cat dog pig mouse]
lista <> listb
means: make a new list containing the elements of LISTA and the elements
of LISTB.
[^x] <> l -> l is the same in effect as
x :: l -> l;
or
[^x ^^l] -> l;
But the former is much less efficient, since <> copies the first list.
Notice that when X and Y are lists:
x <> y
is equivalent to
[^^x ^^y]
The former has no advantages except that it is easier for the machine.
The operator <> can also be used to join two words, two vectors, two
strings.
>>>> REV
This is a procedure which takes a list as argument and creates a new one
containing the same elements in reverse order. E.g.
rev([a b c]) is [c b a]
>>>> MAPLIST
This is a procedure which takes a list and a procedure and applies the
procedure to every element of the list, finally creating a new list
containing all the results. E.g.
maplist(l, identfn) makes a copy of the list l.
maplist([cat dog 2 mouse 3 4 ], isword) =>
** [<true> <true> <false> <true> <false> <false> ]
It could have been defined thus, were it not in the system:
define maplist (l,f);
vars x;
[% for x in l do f(x) endfor%]
enddefine;
Compare the procedure APPLIST.
>>>> DATALIST
This procedure can be applied to a word, string, or vector. It will
create a list containing all the elements of the word string or vector.
The elements of a word or string will be the numbers representing the
characters in it. (The code for lower case A is 97, for B 98, for Z
122.) So:
datalist('abz') and datalist("abz")
both give the list [97 98 122]
maplist([cat dog mouse], datalist) =>
** [ [99 97 116] [100 111 103] [109 111 117 115 101] ]
This produces a list of lists of character codes. (See MAPLIST, above.)
NOTE: strictly, the above codes refer to the LOWER CASE characters.
-- ACCESSING COMPONENTS OF LISTS --------------------------------------
>>>> HD
This procedure takes a list as argument and returns the first element of
the list. HD(LIST) is equivalent to LIST(1). (See below).
>>>> TL
This procedure takes a list as argument and returns as its result the
sublist containing all but the first element. E.g. if L is a list then:
hd(tl(l)) is the second element
hd(tl(tl(l))) is the third element = l(3)
>>>> LAST
This library procedure, when applied to a list returns its last element:
last([a b c d]) =>
** d
Notice that:
last(x)
is equivalent to:
x(length(x))
>>>> Numerical subscripting of lists
In POP11 lists can be treated as procedures which take a number N, to
get the N'th element of a list. E.g.
vars l;
[a b c d] -> l;
l(2) =>
** b
l(3) =>
** c
The N'th element can also be altered by an assignment. Thus to replace
the third element with the list [THIRD ELEMENT], do:
[third element] -> l(3);
l =>
** [a b [third element] d]
l(3) =>
** [third element]
-- MISCELLANEOUS PROCEDURES -------------------------------------------
>>>> LENGTH
This procedure takes a list and counts the elements, returning a number
as its result. E.g
length([ 99 a [a b c] d]) is 4
length([]) is 0
>>>> ATOM
This is a type-testing procedure, which returns TRUE or FALSE as its
result. IF it is applied to a non-empty list (i.e. a list other than
[]), its result is FALSE. If it is applied to anything else, e.g. a
word, a procedure, a string, or [], the result is TRUE. So:
atom([]) is true
atom(99) is true
atom("cat") is true
atom(hd) is true
atom([cat dog]) is false
atom(3 :: []) is false
>>>> APPLIST
This procedure takes a list and a procedure and applies the procedure to
every element of the list. (Compare MAPLIST.) E.g.
applist([ 99 ], isinteger) yields <true>,
applist([ 1 2 a b 3], isinteger) puts on the stack:
<true>,<true>,<false>,<false>,<true>
whereas
applist([], f)
does nothing, whatever procedure F is.
APPLIST could have been defined like MAPLIST (above), but without the
decorated list brackets.
>>>> ISPAIR
This is TRUE if applied to a list (other than the empty list) FALSE
otherwise.
-- GLOBAL VARIABLE (EMPTY LISTS) --------------------------------------
>>>> NIL
This is a variable provided by the system whose value is the word "[]"
so that [], NIL, and VALOF("NIL") all refer to the same thing. [] is
conventionally used to represent the "empty" list, so that if you take a
list L and then assign TL(L) to L repeatedly, you'll end up with L
having the value []. Trying to apply HD or TL to [] will produce an
error ("non-list argument for list procedure, culprit []").
For more on lists see
R.Barrett, A.Ramsay, A.Sloman,
POP-11: A Practical language for Artificial Intelligence
Ellis Horwood and John Wiley, 1985.
Also, try the following TEACH files.
TEACH * LISTS *ARROW *PERCENT * MATCHES * MOREMATCH * DATABASE
TEACH * SETS
-----<Copyright University of Sussex 1986. All rights reserved.>-------