beowulf.host
provides Lisp 1.5 functions which can’t be (or can’t efficiently be) implemented in Lisp 1.5, which therefore need to be implemented in the host language, in this case Clojure.
AND
(AND & args)T if and only if none of my args evaluate to either F or NIL, else F.
In beowulf.host principally because I don’t yet feel confident to define varargs functions in Lisp.
ASSOC
(ASSOC x a)If a is an association list such as the one formed by PAIRLIS in the above example, then assoc will produce the first pair whose first term is x. Thus it is a table searching function.
All args are assumed to be beowulf.cons-cell/ConsCell objects. See page 12 of the Lisp 1.5 Programmers Manual.
NOTE THAT this function is overridden by an implementation in Lisp, but is currently still present for bootstrapping.
ATOM
(ATOM x)Returns T if and only if the argument x is bound to an atom; else F. It is not clear to me from the documentation whether (ATOM 7) should return T or F. I’m going to assume T.
ATOM?
macro
(ATOM? x)The convention of returning F from predicates, rather than NIL, is going to tie me in knots. This is a variant of ATOM which returns NIL on failure.
CAR
(CAR x)Return the item indicated by the first pointer of a pair. NIL is treated specially: the CAR of NIL is NIL.
CDR
(CDR x)Return the item indicated by the second pointer of a pair. NIL is treated specially: the CDR of NIL is NIL.
CONSP
(CONSP o)Return T if object o is a cons cell, else F.
NOTE THAT this is an extension function, not available in strct mode. I believe that Lisp 1.5 did not have any mechanism for testing whether an argument was, or was not, a cons cell.
DEFINE
(DEFINE a-list)Bootstrap-only version of DEFINE which, post boostrap, can be overwritten in LISP.
The single argument to DEFINE should be an association list of symbols to lambda functions. See page 58 of the manual.
DEFLIST
(DEFLIST a-list indicator)For each pair in this association list a-list, set the property with this indicator of the symbol which is the first element of the pair to the value which is the second element of the pair. See page 58 of the manual.
DOC
(DOC symbol)Open the page for this symbol in the Lisp 1.5 manual, if known, in the default web browser.
NOTE THAT this is an extension function, not available in strct mode.
EQUAL
(EQUAL x y)This is a predicate that is true if its two arguments are identical S-expressions, and false if they are different. (The elementary predicate EQ is defined only for atomic arguments.) The definition of EQUAL is an example of a conditional expression inside a conditional expression.
NOTE: returns F on failure, not NIL
GET
(GET symbol indicator)From the manual:
‘get is somewhat like prop; however its value is car of the rest of the list if the indicator is found, and NIL otherwise.’
It’s clear that GET is expected to be defined in terms of PROP, but we can’t implement PROP here because we lack EVAL; and we can’t have EVAL here because both it and APPLY depends on GET.
OK, It’s worse than that: the statement of the definition of GET (and of) PROP on page 59 says that the first argument to each must be a list; But the in the definition of ASSOC on page 70, when GET is called its first argument is always an atom. Since it’s ASSOC and EVAL which I need to make work, I’m going to assume that page 59 is wrong.
hit-or-miss-assoc
(hit-or-miss-assoc target plist)Find the position of the binding of this target in a Lisp 1.5 property list plist.
Lisp 1.5 property lists are not assoc lists, but lists of the form (name value name value name value...). It’s therefore necessary to recurse down the list two entries at a time to avoid confusing names with values.
lax?
(lax? symbol)Are we in lax mode? If so. return true; is not, throw an exception with this symbol.
OBLIST
(OBLIST)Return a list of the symbols currently bound on the object list.
NOTE THAT in the Lisp 1.5 manual, footnote at the bottom of page 69, it implies that an argument can be passed but I’m not sure of the semantics of this.
OR
(OR & args)T if and only if at least one of my args evaluates to something other than either F or NIL, else F.
In beowulf.host principally because I don’t yet feel confident to define varargs functions in Lisp.
PAIRLIS
(PAIRLIS x y a)This function gives the list of pairs of corresponding elements of the lists x and y, and APPENDs this to the list a. The resultant list of pairs, which is like a table with two columns, is called an association list.
Eessentially, it builds the environment on the stack, implementing shallow binding.
All args are assumed to be beowulf.cons-cell/ConsCell objects. See page 12 of the Lisp 1.5 Programmers Manual.
NOTE THAT this function is overridden by an implementation in Lisp, but is currently still present for bootstrapping.
PUT
(PUT symbol indicator value)Put this value as the value of the property indicated by this indicator of this symbol. Return value on success.
NOTE THAT there is no PUT defined in the manual, but it would have been easy to have defined it so I don’t think this fully counts as an extension.
QUOTIENT
(QUOTIENT x y)I’m not certain from the documentation whether Lisp 1.5 QUOTIENT returned the integer part of the quotient, or a realnum representing the whole quotient. I am for now implementing the latter.
RPLACA
(RPLACA cell value)Replace the CAR pointer of this cell with this value. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps)
RPLACD
(RPLACD cell value)Replace the CDR pointer of this cell with this value. Dangerous, should really not exist, but does in Lisp 1.5 (and was important for some performance hacks in early Lisps)
SET
(SET symbol val)Implementation of SET in Clojure. Add to the oblist a binding of the value of var to the value of val. NOTE WELL: this is not SETQ!
TRACE
(TRACE s)Add this s to the set of symbols currently being traced. If s is not a symbol or sequence of symbols, does nothing.
uaf
(uaf l path)Universal access function; l is expected to be an arbitrary LISP list, path a (clojure) list of the characters a and d. Intended to make declaring all those fiddly #'c[ad]+r' functions a bit easier
UNTRACE
(UNTRACE s)Remove this s from the set of symbols currently being traced. If s is not a symbol or sequence of symbols, does nothing.