Wednesday, May 03, 2006

Scheme Implementation in Javascript

A post on Lambda the Ultimate recently was about an Oberon interpreter written in Javascript, allowing Oberon to be embedded in the browser.

This reminded me of an near-R5RS compatible Scheme written in Javascript called jsScheme. It's a very nice implementation to play with but is IE 6 only. I've done some hacking at it and made it compatible with Firefox. I've put the modified version here.

The modified version has some changes to cater for Firefox and some things still don't work. JIT compilation for example, so I've left the checkbox for this disabled by default. This does slow things down quite a bit but I'll enable it again when I find the problem. For IE JIT works fine and you can enable it. If you find any other issues I'd be keen to get feedback. Leave a comment here or email me. I've also put the modified version in a darcs repository available with:
darcs get http://www.bluishcoder.co.nz/repos/javascript-scheme

Please send me any patches you'd like to apply.

What's nice about this system is it has most of R5RS scheme implemented, including tail recursion and first class continuations. A simple FFI for calling into Javascript is also available. For example, here's how to do some Javascript Date manipulation:
(define d  (js-eval "new Date();"))
(display (js-invoke d "toString"))
(newline)

'js-eval' will evaluate Javascript code and return the object. 'js-invoke' will invoke methods on that object. There is also 'js-call' which can call Javascript functions. Unfortunately Firefox had problem using 'js-call' on things like 'alert' and 'setTimeout' so I wrapped these built-ins with Javascript functions which can be called:
(js-call (js-eval "jsAlert") "Hello World!")

'js-call' will a Javascript function object. The 'js-eval' was required to return that function object given the function name.

Lambda the Ultimate also pointed to a Links paper recently. In this paper they describe compiling the Links language to Javascript in continuation passing style and using this to implement user level threading for client side Javascript. This should be possible using this Scheme system as well. We can create continuations using call/cc and use the 'set-timeout!' function I added which wraps 'setTimeout' to do the scheduling. Here's an example of using 'set-timeout!'.
(set-timeout! (lambda () (alert "Hello World")) 1000)

This example waits one second and displays the alert. Any Scheme function can be passed, including continuations:

(define abort #f)

(define (yield)
(call/cc
(lambda (k)
(set-timeout! k 10)
(abort))))

(define (spawn thunk)
(call/cc
(lambda (k)
(set! abort k)
(thunk))))

(define (fib n)
(yield)
(if (= n 0)
0
(if (= n 1)
1
(+ (fib (- n 1)) (fib (- n 2))))))

This code allows you to spawn a single thread which will run in the background of the browser. That thread can call 'yield' to return control back to the browser for a brief time. A simple fibonacci function is provided which calls 'yield'. For example:
(spawn (lambda () (display (fib 10))))

This will return control immediately. You can carry on using the browser and the result will be displayed when the thread completes. A simple thread scheduler implementation would be an interesting exercise.

Categories: ,

8 Comments:

Blogger b7j0c said...

interesting. there is a definite need to unshackle web programming from javascript as a requirement. not to say javascript should "go away", simply that no system can dictate one language. look at the world of databases - while sql is the default query language, coders use language bindings to perform a lot of the other logic, leaving sql simply for the read/write phase. well, thats how i do it.

in any case, the browser stack must become a language neutral environment. i would like to see a portable VM that takes bytecode (with a requirement of source being available via a known url or mouse-click), or straight source, which compiles to a local VM which enforces security. oddly enough IE was the first to make a stab at this with VB support beside javascript.

the mozilla folks are looking at making python a language for XUL apps, but not for general web apps. i hope there is pressure to adopt a cross language mechanism.

5:18 AM  
Anonymous Daniel said...

I've been thinking on and off for some time now on the need for alternative languages for browser scripting. If we can replace the P in LAMP with anything we want, why should the J in AJAX be any different? And it just so happens that the particular language I wanted was Scheme, so you are, as we say on The Internets, teh win!

1:55 AM  
Blogger Chris Double said...

Glad you found it interesting. One neat trick from the Oberon-in-Javascript paper I want to implement is 'script' tags with Scheme code.

Basically you do something like:
<script type="text/x-scheme">
(something)
</script>

And in the document load you enumerate all the script tags with that type and evaluate it with the scheme interpreter. In this way it looks even more embedded as a browser language,

2:23 AM  
Anonymous Anonymous said...

Thanks for that, allows me to actually get some work done at college where i don't have access to gambit.

11:11 PM  
Blogger TheGZeus said...

Any interest in contributing to Conkeror?
www.conkeror.org
It's basically Emacs+Firefox, but written in Javascript. I'd imagine alot more Emacs users could be courted more quickly if one was working in a Lisp dialect while writing Conkeror code.
Not the Jovascript is a bad language, but it's pretty far from Elisp.

4:00 AM  
Blogger Tom said...

Chris, jsScheme is certainly quite interesting. Who holds the copyright? I once saw the version of it at http://alex.ability.ru/scheme.html, but that has been gone for awhile. How could I get permission to modify and redistribute it? Under what licenses would that be possible? Thanks in advance.

I've got a version of jsScheme stripped from the HTML, in case you'd like to see it.

Regards, Tom
tomelam@gmail.com

2:57 AM  
Blogger Tom Elam said...

Hi, Chris. I did see that this Scheme is GPL -- but which GPL? Could this be the LLGPL (as described at http://www.cliki.net/LGPL and http://opensource.franz.com/preamble.html)? I have done some work on the code and would like to clarify things.

Also, I found Alex's page saved at http://web.archive.org/web/20080119020130/http://alex.ability.ru/scheme.html .

3:54 AM  
Blogger Tom Elam said...

This post has been removed by the author.

3:57 AM  

Post a Comment

<< Home