LispKit: building custom Lisp interpreters in Squeak
by Stéphane Rollandin
The LispKit package provides an easy (and fun !) way to play with Lisp interpreters within Squeak.
LispKernel implements a Lisp engine completely embedded in Smalltalk, in the same sense as Schelog is a Prolog embedded in Scheme: there is no hard boundary in syntax or evaluation.
Most notably LispKit does not use a specific parser. Lisp code/data is represented by a
ConsCell, which can be built from an
Array by sending it
So for example
prog := #(funcall (lambda (x) (sqrt x)) 5) asCons
is a Lisp program. Because it is plain Smalltalk code, if
prog is defined as above somewhere in a method, you will find it by looking for the senders of
#funcall (using alt-n); more about this below...
Now the usual interface with a Lisp interpreter is a GUI accepting plain text input (scanned and parsed via the regular
ELisp GUI in Squeak 4.5, with an explorer on a
At top we have a workspace, at bottom a read-eval-print loop
LispKernel is a dynamic (variables are not lexically scoped) Lisp-2 (one namespace for values, one namespace for functions) inspired by Emacs Lisp.
LispKernel has been designed for pedagogy (its own author going through the learning process !); it is a tool for understanding what is Lisp and how it works. All the machinery is clearly exposed and hopefully commented well enough.
LispKernel one can built an interpreter for its own Lisp dialect.
Currently we have
- it will have more primitives and special forms, which are instance-side methods of one argument
- it will have libraries of Lisp code to load, which are class-side methods of no argument returning an
- it will maybe have a different semantics, for example it can be a static Lisp-1 instead of a dynamic Lisp-2, which can be done by overriding critical class or instance side methods
- it will have its own GUI
LispKernel augmented with enough primitives and libraries to be somewhat usable
SLisp, an experimental dialect allowing Smalltak code within Lisp forms
CLisp, a Lisp-1 with lexical scoping and special variables like Common Lisp
ULisp, aka the Uncommon Lisp, a Scheme implementation
The Scheme implementation:
ULisp GUI in Squeak 4.5
pi.scm is a file from the SCM distribution
You can see the pretty printer from SLIB at work on the code for pi
- R4RS compliant, at least according to the r4rstest.scm from the SCM distribution
- SLIB (3b3) provides lots of good stuff (notably hygienic macros)
- features an object system (LKOS) adapted from STklos
ULisp includes the following third-party applications as libraries (all work fine):
The most current code for LispKit is available on SqueakMap: check up the entry LispKit.
LispKit can be installed in any Squeak image from version 3.8 upward (last tested on 5.2)
You can also get it here: LispKit-97.sar (October 10th, 2018), although this may not be the latest version.
What are we talking about here ?
Squeak and Smalltalk links
More (random) details
The documentation is to be found in the class comments of the
LispKernel hierarchy; start by
About Lisp code in Array format
Array syntax can be cumbersome and has definite limits, hence Lisp code can easily come to look a bit weird, like
#(defun #'my-function' (a b) (list a $'and b))
my-function needs to be quoted (else it would be parsed in the three symbols
#function) and the quotation mark needs to be introduced as a character since it is the string delimiter in Smalltalk.
More stuff to come here soon...