or learn more

ToriLisp – an ersatz LISP for tiny birds

Dec 22, 2020

When deciding to work on a side-project three factors are needed to transition from fancy to application: goal, motivation, and time.

Time is usually the biggest sticking point for me personally but with COVID most of what I may have spent my time on this year was cancelled. However, motivation was still a huge sticking point until I came across a couple of projects that helped propel me forward. First, I spent some time earlier this year combing over Mary Rose Cook‘s lovely Little Lisp interpreter code. Given what I knew about Mary’s previous projects it was no surprise that the Little Lisp implementation was simple and elegant. However, what I wasn’t prepared for was that hacking on the interpreter turned out to be straight-forward and addictive. However, it wasn’t until I re-discovered William Taysom‘s old Scheme-like language Misp that I had a form for the interpreter in mind. At the time of William’s original blog posts about Misp I was drawn to his passion and enjoyed the implementations of the language that he posted.1 Around the same time I found Paul Graham’s original Arc tutorial tut.txt and used it extensively to guide me in what to implement next.2 All discussion about Arc aside, I definitely appreciate the clarity and layout of the Arc tutorial and found it a great outline for a little language.

Finally, as some of you might know I dabbled in functional programming in JavaScript and even went so far as to create a couple of libraries pushing the fringe of fp in js; namely Lemonad and underscore-contrib. Some of the ideas in these libraries found their way into my own interpreter which ultimately pushed my code away from Misp, Little Lisp, and Arc into …something else — that something else I’m calling Tori Lisp — an ersatz LISP for little birds.

ToriLisp = Litle Lisp + Misp + tut.txt + Lemonad + underscore-contrib + a pinch of CLJ

Here’s a very small sample of the language:

鳥>  (let (x 3 y 4)
       (+ (* x 2) (* y 2)))
;;=> 14

(def map
  (λ (fn list)
    (if (no list)
      (cons (fn (first list))
            (map fn (rest list))))))

鳥>  (map (+ 10) '(1 2 3))
;;=> [ 11, 12, 13 ]

鳥>  ({x y | (/ (+ x y) 2)} 2 4)
;;=> 3

鳥>  (len "abc")
;;=> 3
鳥>  (len {a | a})
;;=> 1
鳥>  (len +)
;;=> 2

鳥>  (read "(push [1] 'Z)")
;;=> [ "'push", [ "'list", 1 ], [ "'quote", "'Z" ] ]
鳥>  (eval (read "(push [1] 'Z)"))
;;=> [ "'Z", 1 ]  

If I wanted to present a list of features then the following list would work:3

  • Functional
  • Immutable access to JavaScript arrays and hash-maps.
  • Function auto-currying
  • Function introspection
  • Bottoms-out at JavaScript structures and functions
  • ML-like Refs
  • Lightweight syntax for common language forms

If you’re interested in checking out the language then the ToriLisp Github repository has a quick start, test suite, and its own tut.txt.

  1. Though the implementations did not make the Internet Archive it seems. I reached out to Mr. Taysom years ago and he was kind enough to send me the code but I hesitate to share it publicly without his approval. 

  2. Consider this a form of README-driven language development

  3. Currently ToriLisp doesn’t have macros though not because it would have been terribly difficult to add. Instead, I wanted to start with functional literals and auto-currying and see how far it could take me. I may add them at a later date but only time will tell. 

No Comments, Comment or Ping

Reply to “ToriLisp – an ersatz LISP for tiny birds”