3.13 Composite Functions

APPEND(U:list, V:list):list eval, spread
 
Returns a constructed list in which the last element of U is followed by the first element of V. The list U is copied, V is not.
EXPR PROCEDURE APPEND(U, V);

  IFNULL U THEN V

ELSE CAR U . APPEND(CDR U, V);

ASSOC(U:any, V:alist):{dotted-pair, NIL} eval, spread
 
If U occurs as the CAR portion of an element of the alist V, the dotted-pair in which U occurred is returned, else NIL is returned. ASSOC might not detect a poorly formed alist so an invalid construction may be detected by CAR or CDR.
EXPR PROCEDURE ASSOC(U, V);

  IF NULL V THEN NIL

ELSE IF ATOM CAR V THEN

ERROR(000, LIST(V, "is a poorly formed alist"))

ELSE IF U = CAAR V THEN CAR V

ELSE ASSOC(U, CDR V);

DEFLIST(U:dlist, IND:id):list eval, spread
 
A ”dlist” is a list in which each element is a two element list: (ID:id PROP:any). Each ID in U has the indicator IND with property PROP placed on its property list by the PUT function. The value of DEFLIST is a list of the first elements of each two element list. Like PUT, DEFLIST may not be used to define functions.
EXPR PROCEDURE DEFLIST(U, IND);

  IF NULL U THEN NIL

   ELSE << PUT(CAAR U, IND, CADAR U);

CAAR U >> . DEFLIST(CDR U, IND);

DELETE(U:any, V:list):list eval, spread
 
Returns V with the first top level occurrence of U removed from it.
EXPR PROCEDURE DELETE(U, V);

  IF NULL V THEN NIL

   ELSE IF CAR V = U THEN CDR V

   ELSE CAR V . DELETE(U, CDR V);

DIGIT(U:any):boolean eval, spread
 
Returns T if U is a digit, otherwise NIL.
EXPR PROCEDURE DIGIT(U);

  IF MEMQ(U, ’(!0 !1 !2 !3 !4 !5 !6 !7 !8 !9))

   THEN T ELSE NIL;

LENGTH(X:any):integer eval, spread
 
The top level length of the list X is returned.
EXPR PROCEDURE LENGTH(X);

  IF ATOM X THEN 0

   ELSE PLUS(1, LENGTH CDR X);

LITER(U:any):boolean eval, spread
 
Returns T if U is a character of the alphabet, NIL otherwise.a
EXPR PROCEDURE LITER(U);

  IF MEMQ(U, ’(!A !B !C !D !E !F !G !H !I !J !K !L !M

!N !O !P !Q !R !S !T !U !V !W !X !Y !Z

!a !b !c !d !e !f !g !h !i !j !k !l !m

!n !o !p !q !r !s !t !u !v !w !x !y !z))

THEN T ELSE NIL;

MEMBER(A:any, B:list):extra-boolean eval, spread
 
Returns NIL if A is not a member of list B, returns the remainder of B whose first element is A.
EXPR PROCEDURE MEMBER(A, B);

  IF NULL B THEN NIL

   ELSE IF A = CAR B THEN B

   ELSE MEMBER(A, CDR B);

MEMQ(A:any, B:list):extra-boolean eval, spread
 
Same as MEMBER but an EQ check is used for comparison.
EXPR PROCEDURE MEMQ(A, B);

  IF NULL B THEN NIL

ELSE IF A EQ CAR B THEN B

ELSE MEMQ(A, CDR B);

NCONC(U:list, V:list):list eval, spread
 
Concatenates V to U without copying U. The last CDR of U is modified to point to V.
EXPR PROCEDURE NCONC(U, V);

BEGIN SCALAR W;

   IF NULL U THEN RETURN V;

W := U;

WHILE CDR W DO W := CDR W;

RPLACD(W, V);

RETURN U

END;

PAIR(U:list, V:list):alist eval, spread
 
U and V are lists which must have an identical number of elements. If not, an error occurs (the 000 used in the ERROR call is arbitrary and need not be adhered to). Returned is a list where each element is a dotted-pair, the CAR of the pair being from U, and the CDR the corresponding element from V.
EXPR PROCEDURE PAIR(U, V);

  IF AND(U, V) THEN (CAR U . CAR V) . PAIR(CDR U, CDR V)

   ELSE IF OR(U, V) THEN ERROR(000,

     "Different length lists in PAIR")

ELSE NIL;

REVERSE(U:list):list eval, spread
 
Returns a copy of the top level of U in reverse order.
EXPR PROCEDURE REVERSE(U);

BEGIN SCALAR W;

   WHILE U DO << W := CAR U . W;

U := CDR U >>;

RETURN W

END;

SASSOC(U:any, V:alist, FN:function):any eval, spread
 
Searches the alist V for an occurrence of U. If U is not in the alist the evaluation of function FN is returned.
EXPR PROCEDURE SASSOC(U, V, FN);

  IF NULL V THEN FN()

   ELSE IF U = CAAR V THEN CAR V

ELSE SASSOC(U, CDR V, FN);

SUBLIS(X:alist, Y:any):any eval, spread
 
The value returned is the result of substituting the CDR of each element of the alist X for every occurrence of the CAR part of that element in Y.
EXPR PROCEDURE SUBLIS(X, Y);

  IF NULL X THEN Y

   ELSE BEGIN SCALAR U;

U := ASSOC(Y, X);

RETURN IF U THEN CDR U

ELSE IF ATOM Y THEN Y

ELSE SUBLIS(X, CAR Y) .

SUBLIS(X, CDR Y)

END;

SUBST(U:any, V:any, W:any):any eval, spread
 
The value returned is the result of substituting U for all occurrences of V in W.
EXPR PROCEDURE SUBST(U, V, W);

  IF NULL W THEN NIL

   ELSE IF V = W THEN U

ELSE IF ATOM W THEN W

ELSE SUBST(U, V, CAR W) . SUBST(U, V, CDR W);