Lisp One Point Five

The first version of LispLanguage to become popular.

The History of LISP project (http://www.softwarepreservation.org/projects/LISP/) has PDFs of the LISP 1.5 Programmer's Manual (http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf), The Programming Language Lisp : Its Operation and Applications (http://www.softwarepreservation.org/projects/LISP/book/III_LispBook_Apr66.pdf) and LISP 1.5 Primer (http://www.softwarepreservation.org/projects/LISP/book/Weismann_LISP1.5_Primer_1967.pdf).

It is now possible to run Lisp 1.5 on the SIMH IBM 7094 emulator. http://www.sonoma.edu/users/l/luvisi/

One interesting thing about Lisp 1.5 is that the top level was not eval, like we're used to nowadays. It was evalquote. You would give the interpreter a function and a list of arguments to that function, and the interpreter would apply the function to the arguments, without "evaluating" any of them. For example, in an eval top level, one might type:
  (+ 1 1)
    => 2

In an evalquote top level, one would type:
  + (1 1)
    => 2

Some more examples:
  cons (a (b c d))
    => (a b c d)
  car ((a b)) ; List of arguments containing one argument, (a b).
    => a
  cdr ((a b))
    => (b)

Lisp 1.5 used DynamicScoping, implemented with DeepBinding in the interpreter. The compiler used ShallowBinding for "special" variables and DeepBinding for "common" variables (which could be shared with interpreted functions). Variables in compiled code that were not declared "special" or "common" were allocated on the runtime stack and only available to the function they were in (like in CeeLanguage).

Lisp 1.5 had DynamicClosures, often called "funargs" or "the funarg device". They are described in The Function of FUNCTION in LISP (ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-199.pdf).

LispMacros had not yet been invented, but it did have the FEXPR, a function which would be called with two arguments: the list of unevaluated arguments it was called with, and the current alist (dynamic environment).

JohnMcCarthy's history of Lisp http://www-formal.stanford.edu/jmc/history/lisp/lisp.html says "The first successful LISP compiler was programmed by Timothy Hart and Michael Levin. It was written in LISP and was claimed to be the first compiler written in the language to be compiled."

The illustrious PeterDeutsch implemented the first interactive LISP on the PDP-1 computer in 1963 (while still in high school!), after reading the LISP 1.5 Programmer's Manual. It was called "Basic PDP-1 Lisp". There is a chapter on it in The Programming Language Lisp : Its Operation and Applications. It runs quite well on the SIMH PDP-1 emulator. You can get both SIMH and Basic PDP-1 Lisp from http://simh.trailing-edge.com/

Property lists existed even in the earliest versions of Lisp.

Contrary to common belief, Lisp 1.5 had both arrays and non-recursive statement lists ("the program feature")
I think I'm confusing myself on one point. Lisp 1.5 had evalquote, not eval, and property-list-based FEXPR, and the Lisp 1.5 function index (http://mhss.nease.net/lisp1.5/node46.html) makes it obvious that various functions had property fexpr/fsubr vs expr/subr...so...umm...I guess I'm wondering why you're saying FEXPR was limited to 2 params, or that it was function-based. Using a FEXPR marker in the property list would seem to allow any number of parameters.

When used, an FEXPR could be passed any number of arguments (actual parameters, one might say), none of which would be evaluated before calling the FEXPR. When run, the FEXPR would receive all of the arguments as a list in its first argument (or first formal parameter). The alist would be passed as its second argument. Does that make sense?

Thanks for clarifying. In one way it seems just common sense, I suppose, since it needs an alist, but that means FEXPR was assymetric with EXPR? Or did EXPRs also receive a single parameter which was a list of its actual parameters after evaluation?? (See how easily I confuse myself? :-) The same issue with subr/fsubr presumably would be a completely invisible matter of interpretation.

EXPRs are normal functions. They must be passed the same number of arguments as they expect. Each argument is evaluated and bound to one lambda variable, just like you're used to. I suppose that counts as an asymmetry. "define" creates EXPRs by sticking the lambda expression on the property list after the symbol EXPR. To create FEXPRs you do the same thing, but stick the lambda expression after the symbol FEXPR. "deflist" does just this sort of thing.

Here's an attempt at an example:
  deflist ((
    (test-fexpr (lambda (args alist) (prog () (print args) (print alist))))
   ) FEXPR)
    => (test-fexpr)

define (( (test1 (lambda (a) (test-fexpr b c))) )) => (test1)

test1 (6) (b c) ((a . 6)) => NIL


LISP 1.5 Programmer's Manual http://mhss.nease.net/lisp1.5/mccarthy.html (BrokenLink see http://web.archive.org/web/20060307131425/http://mhss.nease.net/lisp1.5/mccarthy.html) includes Appendix I: LISP FOR SHARE DISTRIBUTION (1965 Stanford AI Lisp 1.5 distribution) NOTE: This is just a discussion about the SHARE LISP distribution. It doesn't actually contain the source code. The folks at the History of LISP project are trying to find it. We found it -- see http://www.softwarepreservation.org/projects/LISP/lisp15_family/#SHARE_LISP_1.5_ .

See also: LispLanguage, DynamicClosure, CommonLisp, InterLisp, MacLisp, SchemeLanguage


CategoryLisp CategoryHistory

EditText of this page (last edited July 20, 2012) or FindPage with title or text search