Javascript Partial Continuations
I've been playing around with Rhino, a Javascript interpreter written in Java, using it as a server side scripting language. Rhino supports continuations so I thought I'd try and port the bshift and breset implementation I ported to Factor to Javascript.
My initial attempt is in partial-continuations.js.This can be loaded into the Rhino interpreter using:
Rhino's 'load' understands URL's so you can even do:
A simple use of the 'range' example in Javascript is:
This works fine printing the number from 1 to 5. I've struck a bit of wierdness with the attempt to translate the CLU-iterator idiom mentioned in my previous post. My Javascript translation was:
This works, printing '55'. But if I change it to the following it prints 10:
For some reason the range call is not calling the entire breset scope. It's only calling from the 'range' onwards. Can anyone spot what's wrong with my implementation?
Categories: javascript
My initial attempt is in partial-continuations.js.This can be loaded into the Rhino interpreter using:
load("partial-continuations.js")Rhino's 'load' understands URL's so you can even do:
load("http://www.bluishcoder.co.nz/code/partial-continuations.js")A simple use of the 'range' example in Javascript is:
function range(rc, from, to) {
return bshift(rc, function(pcc) {
while(from <= to) {
pcc(from++);
}
return undefined;
});
function test1() {
breset(function(rc) {
print(range(rc, 1, 5));
return 0;
});
}
This works fine printing the number from 1 to 5. I've struck a bit of wierdness with the attempt to translate the CLU-iterator idiom mentioned in my previous post. My Javascript translation was:
function test3() {
var sum = 0;
breset(function(rc) {
var tmp = range(rc, 1, 10);
sum += tmp;
});
print(sum);
}
This works, printing '55'. But if I change it to the following it prints 10:
function test3() {
var sum = 0;
breset(function(rc) {
sum += range(rc, 1, 10);
});
print(sum);
}
For some reason the range call is not calling the entire breset scope. It's only calling from the 'range' onwards. Can anyone spot what's wrong with my implementation?
Categories: javascript

5 Comments:
Chris,
Excellent stuff!
I've used Rhino continuations mostly (if not "only" ;) to return control back from script to host application.
Your examples are really very interesting and inspiring -- never thought this is possible with Rhino.
Regarding your latest statement – according to my (minimal) LISP knowledge, I see no errors in translation, and the fact that "+=" variant and one with temporal variables give different results points to the problems with Rhino Continuations itself (most likely interpreter). I saw your question in Mozilla JS group, but probably it would be better to post same question to Apache Cocoon mailing list –Rhino Continuations originates from this project.
Valery
Chris,
Excellent stuff!
I've used Rhino continuations mostly (if not "only" ;) to return control back from script to host application.
Your examples are really very interesting and inspiring -- never thought this is possible with Rhino.
Regarding your latest statement – my (minimal) LISP knowledge see no errors in translation, and the fact that “+=” variant and variant with temporal variables give different results points to the problems with Rhino Continuations itself (most likely interpreter). I saw your question in Mozilla JS group, but probably it would be better to post same question to Apache Cocoon mailing list –Rhino Continuations originates from this project.
Valery
Thanks for the comment, I'll check out the Cocoon list. I'm keen to see how Rhino's continuations can be used.
Another area I want to explore is web continuations using Rhino. I've written some code to drive Jetty 6 with Rhino - letting you create servlets, etc from the interpreter command line, and modify the server while it's running that way. Adding continuations into the mix from there shouldn't be too hard.
Chris,
I think about this issue a bit. The problem with Rhino Continuation is that "point of resume" is not obvious, and finding out what operator (not in JS language, but on interpreter stack) will be executed next is problematic.
Here is re-write of your test3:
-----8<----------
Array.prototype.toString = function()
{
return "[" + this.join(", ") + "]";
}
function nop(v)
{
print("tarce: " + v);
return v;
}
function test3() {
var sum = [0];
breset(function(rc) {
nop(sum)[0] = nop(sum)[0] + range(rc, 1, 10);
});
print(sum[0]);
}
-----8<----------
Output:
tarce: [0]
tarce: [0]
10.0
It looks like code for assignment is not part of code that is resumed after continuation.
Now let us try order of "+" operands:
-----8<----------
/* nop & Array.prototype.toString are same */
function test3() {
var sum = [0];
breset(function(rc) {
nop(sum)[0] = range(rc, 1, 10) + nop(sum)[0];
});
print(sum[0]);
}
-----8<----------
Output:
tarce: [0]
tarce: [0]
tarce: [1]
tarce: [3]
tarce: [6]
tarce: [10]
tarce: [15]
tarce: [21]
tarce: [28]
tarce: [36]
tarce: [45]
55.0
Right result!!!
So this is a Rhino bug (or very tricky "feature" ;)
Btw, now your code may be used without "tmp" variable:
function test3() {
var sum = 0;
breset(function(rc) {
sum = range(rc, 1, 10) + sum;
});
out.println(sum);
}
Valery
Very cool! Thanks for looking into it Valery and finding the problem!
Post a Comment
<< Home