To recap, Heist is a Scheme interpreter I’m writing in Ruby in order to teach myself a few things about how languages work while I read Structure and Interpretation of Computer Programs (which I’m lagging behind with, having been focusing on implementing Scheme rather than learning it). It’s a reasonably advanced toy, supporting tail call optimisation, macros and first-class continuations.
This release totally revises the runtime to properly implement lists (Lisp lists
are linked lists made of chained pair objects, rather than arrays), and adds all
the R5RS list and pair functions, making Heist considerably more powerful for
manipulating data structures. It also adds dotted pair notation, improper lists,
rational and complex numbers and associated functions, as well as ‘rest
arguments’ for functions using the dot notation in the argument list. A bunch of
macro bugs have been squashed relating to keyword handling and nested
repetitions, and we now support the R6RS ellipsis escaping (
(... ...)) feature
to better provide for macro-writing macros.
Finally, this release allows interpreters embedded in Ruby programs to run Scheme code expressed as Ruby data, opening up all sorts of possibilities for manipulating code using Ruby. For example:
scheme = Heist::Runtime.new scheme.exec [:define, [:square, :x], [:*, :x, :x]] scheme.exec [:square, 9] #=> 81
At some point I’d like to better expose the Scheme macro system to Ruby as this could make rewriting Ruby code easier, potentially complementing tools like Reg Braithwaite‘s rewrite gem. The internals are still in flux at the moment so this idea will have to wait a bit.
All the new features are a simple
gem install heist away. If you want to know
how it works I’ve added a lot of comments to the code throughout the runtime, so
if you find anything in there that makes no sense let me know and I’ll try to do
something about it. Happy Scheming!