----------------------------
Documentation with SLPL/SCOR
----------------------------

SLPL/SCOR is an implementation of a simple list processing language à
la LISP. This implementation, in Comal, should not be regarded for any
serious use except studying the source of the interpreter.  SLPL stands
for Simple List Processing Language; SCOR means Shock Course on
Recursion :-)

The world of SLPL is made up of two things : LISTs and ATOMs.

An atom is a character string (maximum length 31) consisting of
numbers, letters and other characters not containing space, (, ) and '.

Valid atoms are :

	COMPUTER
	45
	THIS-IS-A-LONG-ATOM
	CAR78-O

As you see atoms can represent names, numbers and the like. The other
concept in SLPL is the list. A list is an ordered structure made up of
atoms and other lists.

Valid lists are :

	( THIS IS A LIST )
	( A LIST ( WITH SUBLISTS ) )
	( 1 2 3 )

A list contains a number of elements. The first list contains 4
elements. The second list contains 3 elements, two atoms and a list.
As you can see a list in SLPL is represented by a '(' and a ')' with
inbetween the elements. You can look upon the list as a nephew of the
well known 'set' which is a concept from mathematics. The difference is
that lists are ordered, whilst sets are not: The set {a,b,c} is equal
to the set {c,a,b},  whilst the list (A B C) is different from the list
(C A B).

The list containing no elements () is referred to as the null list or
NIL

So the list and the atom are the data structures SLPL can handle. With
them you have enough power to do anything you want. With lists and
atoms you can represent array's (mono and multidimensional), binary
trees, sparse matrices etc. etc.

The power of list processing languages lies in the evaluation engine.
The evaluation engine is the heart of the SLPL interpreter and its sole
purpose is the evaluation of lists.  SLPL will always try to evaluate
something. The result of this: evaluation will be handed back to the
requester as a function result.

When you start up SLPL you'll get a introductory message followed
by the prompt 'Evaluate :'. SLPL wants you to present it with
an input line it can evaluate. After the evaluation it'll respond
'Value is : ....'.

Now just enter:

	(+ 4 5)   [return]

SLPL will think some time and then say 'Value is : 9'. This value
is the result of the evaluation of the list (+ 4 5).

When you request SLPL to evaluate a list it looks upon that list as a
function call. The first element of the list is the function and the
rest are its parameters. It then starts evaluating all parameters (2nd,
3rd ... elements of the list) and after that hands over the control to
the requested function.

So when you type:

	(* 2 5 6)

SLPL sees the '*' as the requested function. It evaluates the 2, 5 and
6 as parameters and tells '*' to do its work. '*' multiplies the
numbers and hands back the result. Voila!

Now you know that the evaluation engine evaluates all of the
parameters you will not be surprised that you can build some quite
complex function calls :

	(- (* 2 2) (* 4 1 8))

Can be used to partially solve an equation X^2+2X+8=0 by determining
the value b^2-4ac. SLPL first evaluates (* 2 2) and stores the value,
then looks at (* 4 1 8) ans stores that value and after this subtracts
the two values.

So much for the evaluation of lists. Now a view of how SLPL evaluates
atoms.

When the evaluation engine discovers that is has to evaluate an atom it
first looks whether the character string making up the atom can be
re.g.:rded as a valid number. Is this so then it returns that number. If
the atom is not numeric it starts looking in its in its variable tables
whether it can find a variable with the same.  name. If it finds one
then it returns the value of the variable, otherwise an error condition
is raised and you will get a message and a trace of the offending
structures.

In yonder paragraph I said that SLPL knows about variables. These
variables have names which are atom like. You can give a variable a
value with the function SET:

	(SET 'MONKEY 1)

is the appropiate thing to type when you want to set a variable
names MONKEY to the value 1. (Don't bother about the ' yet)

When you now type:

	(+ MONKEY 3)

SLPL responds with the message that the value is '4'. It has been
asked to evaluate MONKEY, looked in its variable tables and
found that MONKEY was equal to 1.

Note that in order to set a variable you must do a function call. SET
is an ordinary SLPL function. So to set a variable you must request
SLPL to evaluate a function call to SET.

Now more complex SLPL statements can be written:

	(SET 'A 1)
	(SET 'B 2)
	(SET 'C 3)
	(SET 'D (- (* B B) (* 4 A C)))

You might be bothered a bit by the quote that SET seems to require:

As said before the evaluation engine always wants to evaluate
the parameters of a function call. In the case of SET however you
do not want to evaluate the first parameter because that is the
variable name to which you want to tie a value.

By putting a ' before a structure the evaluation engine does not
evaluate that structure but leaves it "untouched". So if you type :

	MONKEY

the evaluation engine starts looking in its tables to find a variable
with the name of MONKEY and returns that value. But if you type :

	'MONKEY

SLPL will just return the atom MONKEY as its value.

Rather complicated eh?

An example:

	(SET 'A MONKEY)
	(SET 'A 'MONKEY)

Suppose that MONKEY was set to 1 by (SET 'MONKEY 1), in the first
case the variable A is set to 1 whilst in the second case A is set
to MONKEY.

Or, to stay in Comal terms :

	(SET 'MONKEY 1)      <-->  monkey:=1
	(SET 'A MONKEY)      <-->  a:=monkey
	(SET 'A 'MONKEY)     <-->  a:="monkey"  (or a$)

The quote (') is also valid for lists. The function call

	(SET 'PP '(COMAL PASCAL C))

will make variable PP equal to the list (COMAL PASCAL C). SLPL will not
try to evaluate this list. If you forget the quote the& evaluation
engine will start to look for the function COMAL en tries to evaluate
the atoms PASCAL en C and hand their values over to the named function.

Now for functions:

SLPL knows two types of functions : Internal and user ones.
Internal functions are represented by a special value and the
evaluation engine gives control to a special part of the interpreter
as soon as it starts evaluating such an internal function.

User functions are written by the user to perform a specific task.
They are represented by variables whose values are lists making up the
function. A user function is a list containing two lists as its
elements. The first list contain the local names of its parameters and
the second list forms the function body.

A function PLUS to add two number could have the following definition:

	( ( A B ) (+ A B ) )

The first element is the list (A B). These are the parameters of the
function. The second element is the list that is evaluated after
the parameters are tied to their values.

To define the function PLUS you'll have to set the variable PLUS
to its value:

	(SET 'PLUS '( (A B) (+ A B) ) )

Now you have defined a function PLUS. You can call PLUS as follows:

	(PLUS 6 7)

SLPL starts looking for the variable PLUS. It is then returned the
list ((A B) (+ A B)). The evaluation engine ties the variable A to 6
and B to 7. Then it evaluates the list (+ A B). The result of this
evaluation is handed back to the caller.

So now you can define your own functions to do the things you want:

	(SET 'DIS '( (A B C) (- (* B B) (* 4 A C))))

Calling this as

	(DIS 1 2 8)

calculates the value of b^2-4ac for the specified polynome.

The following internal functions are currently built into SLPL/SCOR:

IDLIST       : Returns a list containing all known variables in theL
		system.
QUIT         : Quits SLPL
FIRST        : Returns the first element of a list.
		e.g.: (FIRST '(A B C)) returns A
REST         : Returns the rest of the list.
		e.g.: (REST '(A B C)) returns (B C))
+,-,*,/      : Built in arithmetic. Can have more than 2 parameters.
		e.g.: (* 7 6 5), (- 10 4 5) etc.
SET          : Sets variable to value.
		e.g.: (SET 'VAR (DIS 5 6 7))
EVALUATE     : Evaluates its parameter.
		e.g.: (SET 'A '(* 1 2))
			(EVALUATE A)
SAVE         : Saves current workspace to disk
		e.g.: (SAVE 'WS1)
LOAD         : Loads a workspace from disk.
		e.g.: (LOAD 'WS1)  (All other definitions lost)
MAKELIST     : Makes a list of its parameter
		e.g.: (MAKELIST 'HAI) returns ( HAI )
APPEND       : Appends two lists.
		e.g.: (APPEND '( LIST 1) '(LIST 2)) = (LIST 1 LIST 2)
PROG         : Evaluates all of its parameters(
		e.g.: (PROG st1 st2 st3)
		Can be used to evaluate more than 1 list where only
		one is allowed
IF           : Used as (IF expr st1 st2)
		If expr is TRUE then evaluates st1 else evaluates st2
>,<
>=,<=
=,<>         : Comparision operatorsx
		e.g.: (< 7 6)
OR, AND      : Logical functions
		e.g.: (AND (= A B) (< T 6))
PRINT        : Prints parameter
		e.g.: (PRINT 'Hello 'There)
INPUT        : Inputs a structure from keyboard.
		e.g.: (SET 'A INPUT)

Above descriptions are quite short but the reader is invited to play 
around a bit with them. As said before SLPL/SCOR is not intended for 
any serious programming use.

Some examples :

Counting how many elements there are in a list ":

	(SET 'COUNT '(
		( LIST )
		( IF (= LIST ())
			0
			(+ 1
				(COUNT (REST LIST))
			)
		)
	))

This definition can be roughly compared to the following COMAL
function which determines the length of a string :

	FUNC count ( a$ )
		IF a$="" THEN
			RETURN 0
		ELSE
			RETURN 1+count(a$(2:))
		ENDIF
	ENDFUNC

	
Pick the Nth element out of a list :

	(SET 'PICK '(
		(N LIST)
		( IF (= N 0)
			(FIRST LIST)
			(PICK (- N 1) (REST LIST))
		)
	))

This function as well can be written as a COMAL definition:

	FUNC pick$(n,a$)
		IF n=0 THEN
			RETURN a$(1:1)
		ELSE
			RETURN pick$(n-1,a$(2:))
		ENDIF
	ENDFUNC

Determining the hexadecimal equivalent of a 0<=number<=15

	(SET 'HEXDIGIT '(
		( DIGIT )
		( PICK DIGIT '(0 1 2 3 4 5 6 7 8 9 A B C D E F))
	))

However, the following also works :

	(SET 'HEXDIGIT2 '(
		( DIGIT )
		( IF (< DIGIT 10)
			DIGIT
			(PICK (- DIGIT 10) '(A B C D E F))
		)
	))

Because of the recursive nature of PICK in the first definitionz
of HEXDIGIT nesting can become as deep as 16. You might get
a COMAL 'Out of Memory' error because the interpreter which uses
recursion as much as SLPL fills available stack memory rather quickly.

SLPL/SCOR was conceived of, designed and implemented by Jos Visser
<josvisser66@gmail.com>
