?he 'LISTS2' 'Page %'
?fo 'Aaron Sloman'-% -'\*(DY'
.ce2
MORE EXAMPLES OF LIST PROCESSING
================================

Previous demos (INTRO2 and LISTS1)
have introduced some of the functions
and operations which can be applied to lists.  The examples which follow
illustrate the definition of functions which create new lists from old
ones.  I.e. they take lists as arguments and produce lists as results.
Try doing the questions in this handout and then, if you wish, go onto
NUMBERS or SETSETC.
.sp
1.  Here is a function which makes a list of all the words in a given list.
.tp 8
 	: FUNCTION WORDSIN(LIST);
 	:	IF	LIST = []
 	:	THEN	[]
 	:	ELSEIF	ISWORD(HD(LIST))
 	:	THEN	[%HD(LIST)%] <> WORDSIN(TL(LIST))
 	:	ELSE	WORDSIN(TL(LIST))
 	:	CLOSE
 	: END;
.br
Test this function:
 	: VARS LA; [0 99 CAT DOG 3 4 A B] -> LA; LA =>
 	: VARS LB; [%0, 1, "CAT", HD, "HD", REV, 'STRING'%] -> LB; LB =>
 	: VARS LC; [% 10, HD, REV, 'STRING' %] -> LC; LC =>
 	: TRACE WORDSIN;
 	: WORDSIN(LA) =>
 	: WORDSIN(LB) =>
 	: WORDSIN(LC) =>
 	: WORDSIN([]) =>
.br

2.  Construct some more lists of your own and test the function WORDSIN
on them.  Trace the function.
.sp
3.  Define a function called NUMBERSIN which takes a list and returns
a list of all the numbers in the list.  Test the function on LA LB LC
and other lists.  (You'll need to use the function ISINTEGER).  What is the 
value of NUMBERSIN(WORDSIN(LA))?
.sp
4.  Similarly, using ISFUNC define and test a function called FUNCTIONSIN.
Then define a function called WITHOUTWORDS, which takes a list as argument,
and produces a new list containing everything in that list, except the words.
.tp 3
So:	: WITHOUTWORDS([ CAT 2 ON 'STRING' 99 THE 'MAT']) =>
 	** [2 'STRING' 99 'MAT']
.sp
5. Define a function called SWAPNUMBERS which takes a list containing numbers
and other things, and produces from it a list in which every number has been
replaced by the word "N". Here is an outline:
.tp 8
 	: FUNCTION SWAPNUMBERS (LIST);
 	:	IF	...
 	:	THEN	[]
 	:	ELSEIF	ISINTEGER(...)
 	:	THEN	[% "N" %] <> ...
 	:	ELSE	...
 	:	CLOSE
 	: END;
.br
Trace the function and test it on LA, LB, LC and other lists.
.sp
6.  Define a function called NUMBERSBELOW, which takes two arguments, a number
N and a list, numbers L, and produces a new list containing all the numbers
below N in L.  Here's an outline of the definition, to help you:
.tp 8
 	: FUNCTION NUMBERSBELOW (N,L);
 	:	IF	L = []
 	:	THEN	...
 	:	ELSEIF	... < N
 	:	THEN	... <> NUMBERSBELOW(N,TL(L))
 	:	ELSE	...
 	:	CLOSE
 	: END;
.br
Fill in the dotted bits, then test the function, e.g.:
 	: VARS LD; [ 1 20 4 16 8 12 ] -> LD;
 	: NUMBERSBELOW(13, LD) =>
 	: NUMBERSBELOW(1, LD) =>
 	: NUMBERSBELOW(99, LD) =>
.br
.sp
7. Define a function REVMAPLIST, which takes a list L and a function F
as arguments, and
builds a new list out of the result of applying the function F
to elements of L in reverse order.  One way is to use the functions
REV and MAPLIST.  Try it.  Then test your function with:
 	: FUNCTION DOUBLE N; N + N; END;
 	: REVMAPLIST([1 2 3 4], DOUBLE) =>
.br
.sp
8.
Now try writing your own versions of REV and MAPLIST.
You will have to call your versions by new names so as not to confuse
the POP11 system, for example:
.tp 6
 	: FUNCTION REVERSE(LIST);
 	:	IF	LIST = []
 	:	THEN	...
 	:	ELSE	REVERSE(...) <> [%...%]
 	:	CLOSE
 	: END;
.tp 6
 	: FUNCTION MAPL(LIST,FUNC);
 	:	IF	LIST = []
 	:	THEN	...
 	:	ELSE	[% FUNC(...) %] <> MAPL(...,...)
 	:	CLOSE
 	: END;
.br
Can you now write a version of REVMAPLIST which doesn't
use REV and MAPLIST?
