gol is a simple LISP with a Clojure-like syntax. My goal was to learn more about programming language internals, Go, and LISP. It all started with reading the classic Structure and Interpretation of Computer Programs by Abelson, Sussman, and Sussman. I decided I want to write my LISP, to go even deeper into the rabbit hole. I found the Build Your Own LISP book by Daniel Holden, which teaches you C while building a LISP interpreter. However I didn't like the idea of doing it in C. Nonetheless, the idea of learning another language while building an interpreter sounded interesting. This is how I found the great Writing An Interpreter In Go by Thorsten Ball. To catch up with Go, I've read the Learning Go book by Jon Bodner, which was very helpful for me. While working on it, I also found the Make a LISP repository that helped me with structuring my work. Another resource worth mentioning is the (How to Write a (Lisp) Interpreter (in Python)) article by Peter Norvig.
- It has only the basic
int
,float
,string
, andlist
data types. - Booleans are represented as
true
andfalse
. As in Clojure, and unlike Scheme, everything exceptfalse
andnil
is true. - Values can be assigned to symbols using:
(def x 42)
. - Functions are first-class citizens. Anonymous functions use the syntax:
(fn (x y) (+ x y))
. They can be named using(def add1 (fn (x) (+ 1 x)))
, or the shorthand, Scheme-like syntax:(def (add1 x) (+ x 1))
. - Contexts handling with
let
uses Clojure's syntax:(let (x 2 y (+ x 1)) (/ x y))
. begin
,apply
,map
work as in Scheme.if
andcond
conditionals are available, e.g.(cond (false "not this") (true "this!"))
.- Lists are internally Go's slices, so
conj
(append) is preferred to usingcons
(prepend). Lists can be concatenated usingconcat
. Their elements are accessed usingfirst
,rest
,init
,last
, andnth
. - Arithmetic operators:
+
,-
,*
,/
,%
(modulo) do floating point computations and internally convertint
values tofloat
. If you want to do integer arithmetics, use theint+
,int-
,int*
,int/
,int%
counterparts. Additionally, most of the functions from Go's math package are available under the lowercase names. quote
('
),quasiquote
(`
),unquote
(,
), andeval
can be used for metaprogramming.- Function arguments are passed by value as in Go. The only way to mutate a variable
is by using
set!
. - Garbage collection is handled by Go's internal garbage collector.
- Tail call optimization is based on github.com/kanaka/mal.