jcoglan / fargo

Lisp with fibers for Node.js
http://fargo.jcoglan.com
157 stars 10 forks source link

Compile to JavaScript #1

Closed judofyr closed 13 years ago

judofyr commented 13 years ago

Would be interesting to see if it's possible to compile the code to efficient JS. Any idea how to handle the stack(less) stuff?

jcoglan commented 13 years ago

(Sorry if all this is already obvious to you, but it's nice to spell this out in case others ask.)

The inclusion of fibers complicates this significantly. This is why I can't hack this into CoffeeScript -- partly because it's easier to do on a new, small codebase but also because Coffee is intended to compile to readable JavaScript. When you have any sort of execution semantics not supported by the target language you can't easily emit readable code.

For example, this Fargo function:

(define (loop x)
  (yield x)
  (loop (+ x 1)))

Does not simply compile to this JavaScript:

var loop = function(x) {
  Fiber.yield(x);
  loop(x+1);
};

Two problems: the recursion would blow up the stack in JavaScript whereas Fargo has tail call optimisation. Second, the function has to halt after Fiber.yield(i) in such a way that one can resume execution from that point at any later time. So really, the output would need to be compiled to continuation-passing style. Because of all the sorts of places a yield can appear, the output would end up being very messy -- consider (define x (yield y)) or (if (yield x) a b).

Probably a better idea would be to introduce a bytecode VM implemented in JS, but I'm nowhere near knowing how to do that. Getting there, but slowly.