HomeBlogDynamic scope & lexical scope — how?

Dynamic scope & lexical scope — how?

Some time back I started working on a Lisp interpreter in JavaScript.  That's because I've been going through SICP, and section 4.1 is extraordinarily inspiring—if you read that, you want to write a Scheme interpreter.  Except that, being already a Common Lisp programmer, I wanted to write a Common Lisp interpreter.  Or at least a tiny part of it.

The version that's published on Github right now has both static (lexical) and dynamic scope, but it's somewhat cheating.  To implement dynamic scope I used JavaScript's try/finally, in order to pop dynamic bindings once a LET block that established them finished execution.  However, that version has a show-stopper bug: because JavaScript doesn't have tail call optimization (and even if it would)—it ruins the stack quite easily and you can't generally do loops via recursion.

So I started a new branch (which will be on Github pretty soon); on this new version all the interpreter is implemented in “continuation-returning-style”, if I may say so—instead of calling another function, or returning a value, each expression returns a function that knows what to do next.  The evaluation means to call a function, and the returned function, and the function returned from the returned function, until the cows come home.  (trampoline-style)

This incidentally gave me call/cc “for free”, which is nice (I already gave up my dreams of implementing a subset of Common Lisp, so I'll implement a superset instead :-p).  However dynamic variables turn out to be quite a hassle now.  I don't have the luxury of using the exceptions of the underlying language, because the stack is cleared after each expression evaluates.  Somehow I need to catch the moment when a scope exits, in order to restore the dynamic variables that it modified, but I'm not quite sure how—and the problem is exaggerated by having continuations...   Grr, I'll think of it some more this weekend.

Anyway, I'll publish a toy Lisp environment, with an Ymacs demo for the browser.  Soon.  It will be totally useless for practical purposes, of course.  It can solve WOTF in 10 seconds, with a Schemeish amb macro. (100 times slower than the plain JavaScript implementation).

Update: this is it:

Still no dynamic scope.

    Page info
    Created:
    2011/07/22 01:50
    Modified:
    2011/07/27 00:59
    Author:
    Mihai Bazon
    Tags:
    javascript, lexical closures, lisp, programming, ymacs
    See also