Git Product home page Git Product logo

lisp's Introduction

Lisp 1.5

This is an implementation of the language defined, with sublime concision, in the first few pages of the LISP 1.5 Programmer's Manual by McCarthy, Abrahams, Edwards, Hart, and Levin, from MIT in 1962.

It is a pedagogical experiment to see just how well the interpreter (actually EVALQOUTE/APPLY) defined on page 13 of that book really works. The answer is: perfectly, of course.

This program was a joy to put together. Its purpose was fun and education, and in no way to create a modern or even realistic Lisp implementation. The goal was to turn that marvelous page 13 into a working interpreter using clean, direct Go code.

The program therefore has several profound shortcomings, even with respect to the Lisp 1.5 book:

  • No SET or SETQ.
  • No PROG. The intepreter, by calling APPLY, can evaluate only a single expression, a possibly recursive function invocation. But this is Lisp, and that's still a lot.
  • No character handling.
  • No I/O. Interactive only, although it can start by reading a file specified on the command line.

It is slow and of course the language is very, very far from Common Lisp or Scheme.

Although I may add PROG and perhaps SET[Q] one day, that's about where I'd draw the line. I plan to use this as a teaching tool, not a practical programming environment.

It does do one important thing differently from the book, though: lexical scoping. There is no association list; instead a function has access only to the locals in its own frame, as well globals like T.

Use

A few details about the interpreter.

A semicolon introduces a comment that extends to newline.

For convenience, 'A is the familiar shorthand for (QUOTE A)

T and F are upper case, but all the other words (car, nil, and such) are lower case.

Numbers are implemented by Go's big.Int, so there is no floating point but numbers can be big.

Identifiers can be Unicode. Just for fun, λ is a synonym for lambda. (It's really the other way around, isn't it?)

Identifiers must be alphanumeric. The addition function is add not +.

Built-in functions.

I never liked to type DIFFERENCE or QUOTIENT, so arithmetic uses the much shorter add sub mul div rem, and the comparision operators come from Fortran (why not?): eq ne lt le gt ge ne, as well as and and or.

Other builtin functions are: apply atom, car, cdr, cond, cons, list, null, and quote.

Function definition is done with the defn builtin:

(defn (
	(add2 (λ (n) (add 2 n)))
	(add4 (λ (n) (add2 (add2 n))))
))

An example session.

Here is a typescript. There is a library in lib.lisp; passing it as an argument causes lisp to load it before reading standard input.

% lisp lib.lisp
(fac gcd ack equal not negate mapcar length opN member union intersection)
> ; Funcs
> (add 1 3)
4
> ; Define a lambda that adds 2.
> (defn ((add2 (lambda (n) (add 2 n))) ))
(add2)
> (add2 3)
5
> ; Or add 1 twice.
> (defn ((add2 (lambda (n) (add 1 (add 1 n)))) ))
(add2)
> (add2 3)
5
; There's a startup library in lisp.lib. Let's look at fac. It is recursive:
> fac
(lambda (n) (cond ((eq n 0) 1) (T (mul n (fac (sub n 1))))))
> ; Breaking it down:
> (car fac)
lambda
> (cadr fac)
(n)
> (caddr fac)
(cond ((eq n 0) 1) (T (mul n (fac (sub n 1)))))
> ; Let's run it.
> (fac 1)
1
> (fac 10)
3628800
> ; We have big integers.
> (fac 100)
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
> ; Equal in Lisp.
> equal
(lambda (x y) (cond ((eq x y) T) ((atom x) F) ((atom y) F) ((equal (car x) (car y)) (equal (cdr x) (cdr y))) (T F)))
> (equal '(1 2 (3)) '(1 2 (3)))
T
> (equal '(1 2 (3)) '(1 2 (4)))
F
> ; Mapcar, a Lisp staple: Apply function to each list element.
> mapcar
(lambda (fn list) (cond ((null list) nil) (T (cons (fn (car list)) (mapcar fn (cdr list))))))
> (mapcar fac '(1 2 3 4 5 6 7 8 9 10))
(1 2 6 24 120 720 5040 40320 362880 3628800)
> ; Using a lambda directly.
> (mapcar '(lambda (n) (add 1 (add 1 n))) '(2 3 4))
(4 5 6)
> ; Let's build a function.
> ; A helper: list makes it easier than using cons to build long lists. (Variadic)
> (list 'a 'b '(c))
(a b (c))
> ; Easier than
> (cons 'a (cons 'b (cons (cons 'c nil) nil)))
(a b (c))
> ; Remember how we built add2 above:
> (defn ((add2 (lambda (n) (add 2 n))) ))
(add2)
> ; Now build a function that adds arbitrary N to its argument.
> (defn( (addN (lambda (N) (list 'lambda '(a) (list 'add N 'a)))) ))
(addN)
> (addN 5)
(lambda (a) (add 5 a))
> ((addN 5) 3)
cannot eval ((addN 5) 3)
> ; A Lisp 1.5-ism: apply vs. eval.
> (apply (addN 5) 3)
8
> (mapcar (addN 5) '(1 2 3 4))
(6 7 8 9)
> ; Why not program the op too?
> (defn( (opN (lambda (op N) (list 'lambda '(a) (list op N 'a)))) ))
(opN)
> (mapcar (opN 'sub 5) '(1 2 3 4))
(4 3 2 1)
> ; One last piece of interest: The Ackermann function.
> ; The first argument is a kind of level: constant, n, 2n, 2^n 2^2^n etc.
> ack
(lambda (m n) (cond ((eq m 0) (add n 1)) ((eq n 0) (ack (sub m 1) 1)) (T (ack (sub m 1) (ack m (sub n 1))))))
> (ack 3 4) ; apply called 51535 times!
125
> ^D
%

lisp's People

Contributors

alrs avatar robpike avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.