Skip to content

twolodzko/gol

Repository files navigation

Simple LISP implemented in Go

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.

Features

  • It has only the basic int, float, string, and list data types.
  • Booleans are represented as true and false. As in Clojure, and unlike Scheme, everything except false and nil 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 and cond conditionals are available, e.g. (cond (false "not this") (true "this!")).
  • Lists are internally Go's slices, so conj (append) is preferred to using cons (prepend). Lists can be concatenated using concat. Their elements are accessed using first, rest, init, last, and nth.
  • Arithmetic operators: +, -, *, /, % (modulo) do floating point computations and internally convert int values to float. If you want to do integer arithmetics, use the int+, int-, int*, int/, int% counterparts. Additionally, most of the functions from Go's math package are available under the lowercase names.
  • quote ('), quasiquote (`), unquote (,), and eval 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.

About

Simple LISP implemented in Go

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published