I was inspired by the ClojureScript project, a Clojure to JavaScript compiler, to look into the feasibility of a JavaScript back-end for Gambit. A JavaScript back-end would allow running Gambit programs in web browsers. Moreover, Scheme objects, including closures and continuations, could be sent between a Gambit Scheme program running on the browser and a Gambit Scheme program running on the server.
I did a fairly direct translation of the GVM code for the fib function into JavaScript (see the code attached below which interleaves the GVM code and JavaScript code). Under V8 on a recent Mac Book Pro, this JavaScript program runs about 10 times slower than when the Scheme program is compiled with the C back-end (and 4 times faster than when the Scheme program is interpreted with gsi). This is not so bad considering that JavaScript is a dynamic language with more overhead than C. Moreover, for event-driven programs, which are most of the time waiting for input, this is probably an acceptable level of performance.
If anyone would like to pursue this idea, please let me know.
Marc
// GVM state var _stack; var _nargs; var _r0; var _r1;
//**** #<primitive | fib.o1|> = //#line 10 "/Users/feeley/gambit/work/fib.scm"
//#1 0 entry-point 0 () ; +0=# function _primitive_fib_o1() { if (_nargs !== 0) error("wrong number of arguments"); var _stk = {parent: _stack}; // allocate frame
//#line 16 // -1 = +0 ; -1=# _stk.slot1 = _r0;
// +1 = '40 ; -1=# +1=. _r1 = 40;
// +0 = #3 ; -1=# +0=. +1=. _r0 = _primitive_fib_o1_label3;
// -2 = . ; -1=# -2 +0=. +1=. // -3 = . ; -1=# -2 -3 +0=. +1=. // -4 = . ; -1=# -2 -3 -4 +0=. +1=. // jump* 4 #2 ; -1=# -2 -3 -4 +0=. +1=. //#2 4 ; -1=# -2 -3 -4 +0=. +1=. // jump 4 '#<primitive fib> 1 ; -1=# -2 -3 -4 +0=. +1=. _nargs = 1; _stack = _stk; return _primitive_fib; }
//#3 4 return-point ; -1=# -2 -3 -4 +1=. function _primitive_fib_o1_label3() { var _stk = _stack;
// +0 = -1 ; -1 -2 -3 -4 +0=# +1=. _r0 = _stk.slot1;
// jump* 4 #4 ; -1 -2 -3 -4 +0=# +1=. //#4 4 ; -1 -2 -3 -4 +0=# +1=. // jump 0 println 1 ; +0=# +1=. _nargs = 1; _stack = _stk.parent; // pop frame return _primitive_println; }
// //**** #<primitive fib> = //#line 10 "/Users/feeley/gambit/work/fib.scm" //#1 0 entry-point 1 () ; +0=# +1=n function _primitive_fib() { if (_nargs !== 1) error("wrong number of arguments");
//#line 11 // if (##fx< +1 '2) jump 0 #5 else #3 ; +0=# +1=n return (_r1 < 2) ? _primitive_fib_label5 : _primitive_fib_label3; }
//#line 10 //#2 0 ; +0=# +1=n function _primitive_fib_label2() {
//#line 11 // if (##fx< +1 '2) jump 0 #5 else #3 ; +0=# +1=n return (_r1 < 2) ? _primitive_fib_label5 : _primitive_fib_label3; }
//#3 0 ; +0=# +1=n function _primitive_fib_label3() { var _stk = {parent: _stack}; // allocate frame
//#line 13 // -1 = +0 ; -1=# +1=n _stk.slot1 = _r0;
// -2 = +1 ; -1=# -2=n +1=n _stk.slot2 = _r1;
// +1 = (##fx- +1 '1) ; -1=# -2=n +1=. _r1 = _r1 - 1;
// +0 = #4 ; -1=# -2=n +0=. +1=. _r0 = _primitive_fib_label4;
// -3 = . ; -1=# -2=n -3 +0=. +1=. // -4 = . ; -1=# -2=n -3 -4 +0=. +1=. // -5 = . ; -1=# -2=n -3 -4 -5 +0=. +1=. // -6 = . ; -1=# -2=n -3 -4 -5 -6 +0=. +1=. // -7 = . ; -1=# -2=n -3 -4 -5 -6 -7 +0=. +1=. // -8 = . ; -1=# -2=n -3 -4 -5 -6 -7 -8 +0=. +1=. // jump* 8 #2 ; -1=# -2=n -3 -4 -5 -6 -7 -8 +0=. +1=. _stack = _stk; return _primitive_fib_label2; }
//#4 8 return-point ; -1=# -2=n -3 -4 -5 -6 -7 -8 +1=. function _primitive_fib_label4() { var _stk = _stack;
//#line 14 // -3 = +1 ; -1=# -2=n -3=. -4 -5 -6 -7 -8 +1=. _stk.slot3 = _r1;
// +1 = (##fx- -2 '2) ; -1=# -2 -3=. -4 -5 -6 -7 -8 +1=. _r1 = _stk.slot2 - 2;
// +0 = #6 ; -1=# -2 -3=. -4 -5 -6 -7 -8 +0=. +1=. _r0 = _primitive_fib_label6;
//#line 11 // if (##fx< +1 '2) jump 8 #5 else #3 ; -1=# -2 -3=. -4 -5 -6 -7 -8 +0=. +1=. return (_r1 < 2) ? _primitive_fib_label5 : _primitive_fib_label3; }
//#5 0 ; +0=# +1=n function _primitive_fib_label5() {
//#line 12 // jump 0 +0 ; +1=. return _r0; }
//#line 14 //#6 8 return-point ; -1=# -2 -3=. -4 -5 -6 -7 -8 +1=. function _primitive_fib_label6() { var _stk = _stack;
//#line 13 // +1 = (##fx+ -3 +1) ; -1=# -2 -3 -4 -5 -6 -7 -8 +1=. _r1 = _stk.slot3 + _r1;
// jump* 8 #7 ; -1=# -2 -3 -4 -5 -6 -7 -8 +1=. //#7 8 ; -1=# -2 -3 -4 -5 -6 -7 -8 +1=. // jump 0 -1 ; +1=. _stack = _stk.parent; // pop frame return _stk.slot1; }
function _primitive_println() { if (_nargs !== 1) error("wrong number of arguments");
print(_r1);
return _r0; }
function main() { var pc;
pc = _primitive_fib_o1; _nargs = 0; _r0 = null;
while (pc !== null) pc = pc(); }
main();
Afficher les réponses par date
On Mar 13, 2012, at 10:10 AM, Marc Feeley wrote:
I was inspired by the ClojureScript project, a Clojure to JavaScript compiler, to look into the feasibility of a JavaScript back-end for Gambit. A JavaScript back-end would allow running Gambit programs in web browsers. Moreover, Scheme objects, including closures and continuations, could be sent between a Gambit Scheme program running on the browser and a Gambit Scheme program running on the server.
I did a fairly direct translation of the GVM code for the fib function into JavaScript (see the code attached below which interleaves the GVM code and JavaScript code). Under V8 on a recent Mac Book Pro, this JavaScript program runs about 10 times slower than when the Scheme program is compiled with the C back-end (and 4 times faster than when the Scheme program is interpreted with gsi). This is not so bad considering that JavaScript is a dynamic language with more overhead than C. Moreover, for event-driven programs, which are most of the time waiting for input, this is probably an acceptable level of performance.
If anyone would like to pursue this idea, please let me know.
Marc,
As you may remember, I have a compiler/interpreter project of my own in the works. Bard is basically a response to my long-term pining for circa-1992 Dylan ( was part of the Apple team that wrote an OS for Newton in Dylan), plus my more recent affection for functional languages like Haskell.
Our Monday demo of Nelson went well. We are now working very hard to try to make the Thursday demo go even better, in hopes of securing the next round of contracts to build these educational games.
That next round of contracts involves promises that we hope to fulfill, in part, by completing a working Bard interpreter. The idea is that the in-game puzzle-description interpreter will be a Bard interpreter.
My ambitions for Bard extend beyond our games, though. For one thing, I'd like to turn it into a decent language for writing web apps. If bard is implemented in Gambit, and Gambit compiles to Javascript, then it seems to me like making a good Bard webapp framework gets a lot easier.
I don't know any specifics of how we might help each other, and don't have the cognitive bandwidth to think about it until after Thursday, but my intuition is that there's something useful we might be able to do for one another's projects. (At the very least, if we get enough funding we might be able to pay you or perhaps your students to help in our tooling effort).
Again, no mnetal bandwidth for this right now, but let's talk later.
--me
I know some that would be very very happy with this :))) At the moment, you need to use Gambit for the backend and scheme2js (which uses Bigloo) for the frontend. I don't think I can help coding this backend at the moment, but I'll be testing it with a project as soon as something is available, for what is worth. Oh, just thinking of a Node.scheme + termite world is filling me with joy.
On Tue, Mar 13, 2012 at 4:10 PM, Marc Feeley feeley@iro.umontreal.ca wrote:
I was inspired by the ClojureScript project, a Clojure to JavaScript compiler, to look into the feasibility of a JavaScript back-end for Gambit. A JavaScript back-end would allow running Gambit programs in web browsers. Moreover, Scheme objects, including closures and continuations, could be sent between a Gambit Scheme program running on the browser and a Gambit Scheme program running on the server.
I did a fairly direct translation of the GVM code for the fib function into JavaScript (see the code attached below which interleaves the GVM code and JavaScript code). Under V8 on a recent Mac Book Pro, this JavaScript program runs about 10 times slower than when the Scheme program is compiled with the C back-end (and 4 times faster than when the Scheme program is interpreted with gsi). This is not so bad considering that JavaScript is a dynamic language with more overhead than C. Moreover, for event-driven programs, which are most of the time waiting for input, this is probably an acceptable level of performance.
If anyone would like to pursue this idea, please let me know.
Marc
// GVM state var _stack; var _nargs; var _r0; var _r1;
//**** #<primitive | fib.o1|> = //#line 10 "/Users/feeley/gambit/work/fib.scm"
//#1 0 entry-point 0 () ; +0=# function _primitive_fib_o1() { if (_nargs !== 0) error("wrong number of arguments"); var _stk = {parent: _stack}; // allocate frame
//#line 16 // -1 = +0 ; -1=# _stk.slot1 = _r0;
// +1 = '40 ; -1=# +1=. _r1 = 40;
// +0 = #3 ; -1=# +0=. +1=. _r0 = _primitive_fib_o1_label3;
// -2 = . ; -1=# -2 +0=. +1=. // -3 = . ; -1=# -2 -3 +0=. +1=. // -4 = . ; -1=# -2 -3 -4 +0=. +1=. // jump* 4 #2 ; -1=# -2 -3 -4 +0=. +1=. //#2 4 ; -1=# -2 -3 -4 +0=. +1=. // jump 4 '#<primitive fib> 1 ; -1=# -2 -3 -4 +0=. +1=. _nargs = 1; _stack = _stk; return _primitive_fib; }
//#3 4 return-point ; -1=# -2 -3 -4 +1=. function _primitive_fib_o1_label3() { var _stk = _stack;
// +0 = -1 ; -1 -2 -3 -4 +0=# +1=. _r0 = _stk.slot1;
// jump* 4 #4 ; -1 -2 -3 -4 +0=# +1=. //#4 4 ; -1 -2 -3 -4 +0=# +1=. // jump 0 println 1 ; +0=# +1=. _nargs = 1; _stack = _stk.parent; // pop frame return _primitive_println; }
// //**** #<primitive fib> = //#line 10 "/Users/feeley/gambit/work/fib.scm" //#1 0 entry-point 1 () ; +0=# +1=n function _primitive_fib() { if (_nargs !== 1) error("wrong number of arguments");
//#line 11 // if (##fx< +1 '2) jump 0 #5 else #3 ; +0=# +1=n return (_r1 < 2) ? _primitive_fib_label5 : _primitive_fib_label3; }
//#line 10 //#2 0 ; +0=# +1=n function _primitive_fib_label2() {
//#line 11 // if (##fx< +1 '2) jump 0 #5 else #3 ; +0=# +1=n return (_r1 < 2) ? _primitive_fib_label5 : _primitive_fib_label3; }
//#3 0 ; +0=# +1=n function _primitive_fib_label3() { var _stk = {parent: _stack}; // allocate frame
//#line 13 // -1 = +0 ; -1=# +1=n _stk.slot1 = _r0;
// -2 = +1 ; -1=# -2=n +1=n _stk.slot2 = _r1;
// +1 = (##fx- +1 '1) ; -1=# -2=n +1=. _r1 = _r1 - 1;
// +0 = #4 ; -1=# -2=n +0=. +1=. _r0 = _primitive_fib_label4;
// -3 = . ; -1=# -2=n -3 +0=. +1=. // -4 = . ; -1=# -2=n -3 -4 +0=. +1=. // -5 = . ; -1=# -2=n -3 -4 -5 +0=. +1=. // -6 = . ; -1=# -2=n -3 -4 -5 -6 +0=. +1=. // -7 = . ; -1=# -2=n -3 -4 -5 -6 -7 +0=. +1=. // -8 = . ; -1=# -2=n -3 -4 -5 -6 -7 -8 +0=. +1=. // jump* 8 #2 ; -1=# -2=n -3 -4 -5 -6 -7 -8 +0=. +1=. _stack = _stk; return _primitive_fib_label2; }
//#4 8 return-point ; -1=# -2=n -3 -4 -5 -6 -7 -8 +1=. function _primitive_fib_label4() { var _stk = _stack;
//#line 14 // -3 = +1 ; -1=# -2=n -3=. -4 -5 -6 -7 -8 +1=. _stk.slot3 = _r1;
// +1 = (##fx- -2 '2) ; -1=# -2 -3=. -4 -5 -6 -7 -8 +1=. _r1 = _stk.slot2 - 2;
// +0 = #6 ; -1=# -2 -3=. -4 -5 -6 -7 -8 +0=. +1=. _r0 = _primitive_fib_label6;
//#line 11 // if (##fx< +1 '2) jump 8 #5 else #3 ; -1=# -2 -3=. -4 -5 -6 -7 -8 +0=. +1=. return (_r1 < 2) ? _primitive_fib_label5 : _primitive_fib_label3; }
//#5 0 ; +0=# +1=n function _primitive_fib_label5() {
//#line 12 // jump 0 +0 ; +1=. return _r0; }
//#line 14 //#6 8 return-point ; -1=# -2 -3=. -4 -5 -6 -7 -8 +1=. function _primitive_fib_label6() { var _stk = _stack;
//#line 13 // +1 = (##fx+ -3 +1) ; -1=# -2 -3 -4 -5 -6 -7 -8 +1=. _r1 = _stk.slot3 + _r1;
// jump* 8 #7 ; -1=# -2 -3 -4 -5 -6 -7 -8 +1=. //#7 8 ; -1=# -2 -3 -4 -5 -6 -7 -8 +1=. // jump 0 -1 ; +1=. _stack = _stk.parent; // pop frame return _stk.slot1; }
function _primitive_println() { if (_nargs !== 1) error("wrong number of arguments");
print(_r1);
return _r0; }
function main() { var pc;
pc = _primitive_fib_o1; _nargs = 0; _r0 = null;
while (pc !== null) pc = pc(); }
main();
Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
On Tue, Mar 13, 2012 at 11:10:11AM -0400, Marc Feeley wrote:
I was inspired by the ClojureScript project, a Clojure to JavaScript compiler, to look into the feasibility of a JavaScript back-end for Gambit. A JavaScript back-end would allow running Gambit programs in web browsers. Moreover, Scheme objects, including closures and continuations, could be sent between a Gambit Scheme program running on the browser and a Gambit Scheme program running on the server.
I did a fairly direct translation of the GVM code for the fib function into JavaScript (see the code attached below which interleaves the GVM code and JavaScript code). Under V8 on a recent Mac Book Pro, this JavaScript program runs about 10 times slower than when the Scheme program is compiled with the C back-end (and 4 times faster than when the Scheme program is interpreted with gsi). This is not so bad considering that JavaScript is a dynamic language with more overhead than C. Moreover, for event-driven programs, which are most of the time waiting for input, this is probably an acceptable level of performance.
If anyone would like to pursue this idea, please let me know.
There's also Google's Opa project, Opa, as I understand it, resembles OCaml but gets compiled to javascript on the browser and something else on the server and manages to be completely transparent as to what runs where and even distributes cleanly into the so-called Cloud.
-- hendrik