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!