[gambit-list] Using the JavaScript back-end

Marc Feeley feeley at iro.umontreal.ca
Sat Jan 31 16:18:41 EST 2015


> On Jan 31, 2015, at 12:38 PM, Blake McBride <blake at mcbride.name> wrote:
> 
> Dear Mark,
> 
> Thanks for your pointers regarding scheme back-ends for JavaScript.  I starting using Gambit but ran into a few problems as follows:
> 
> 1.  The -target compiler option is undocumented.  I think Gambit is more capabilities than the public is aware of - i.e. JavaScript back-end.

The JavaScript backend is not yet ready for general public usage.  The JS code generator is close to complete, but the system lacks a full Scheme library.  I am working on a full Scheme library (see https://github.com/feeley/univ-lib) and better debugging support, but it is not quite there yet.  Some people are using the JS backend for commercial products but it requires some careful use of the compiler to avoid some of the current pitfalls.

> 2.  When I compile anything into JS and run it in node I get:
> 
>     pc = pc();
>          ^
> TypeError: undefined is not a function
> 
> 
> If I change the definition of gambit_trampoline to:
> 
> function gambit_trampoline(pc) {
>   while (pc !== false  &&  pc !== undefined) {
>     pc = pc();
>   } 
> }
> 
> it fixes the problem.

The problem is not in gambit_trampoline.  You are probably calling a Scheme library function without knowing it, for example (+ 1 2) without having the proper declarations to ensure that the + will be inlined by the compiler (because currently a Scheme library is *not* linked with the app).

It would be good to see the code you are trying to compile.

> 3.  I'd like to print results to the console so I can see what is going on.  I'd prefer to use (print) or (display) but I can't get (console.log) to work either. 
> 
> I even tried:
> 
> (define (console.log x)
>   ;; Note: the parameter x will be in variable Gambit_r1
>   (##inline-host-code "console.log(Gambit_r1);\n")
>   #f)
> 
> but that didn't work either.
> 
> I checked, console.log seems to be a JS standard.  Perhaps your compiler can convert print and display to console.log.
> 
> How can I display something?

The generated code assumes that the “print” JS function will print the argument on a line.  This works with d8 and js, the V8 shell and SpiderMonkey shell.  Using console.log will not work in those shells, but it will work in browser environments (in web pages).  This is such a frequent gotcha that I just changed it so that a Scheme (println obj)  will check at run time for the presence of console.log .

An interface to console.log can be written this way:

  (define (console.log obj)
    (##inline-host-statement "console.log(gambit_scm2js(@1@));" obj))

In any case, here is a simple example and instructions on how to run the code in a JS shell and in the browser.  If you want to use non-primitive predefined Scheme library functions (such as equal?, append, map, write, etc) you will need to look into univ-lib .  The goal is to have all of this neatly packaged in gsc so that one invocation of gsc will do all that is necessary.  One issue is linking… should the .js file contain all of the application code including Scheme libraries, or should it contain just the code for the compiled file (so that it can be dynamically loaded by the web page)?  Both should be supported with an appropriate compile flag.

Marc


;; File: fib.scm
;;
;; compile with: gsc -c -target js fib.scm
;;
;; execute with: d8 fib.js
;;
;; or use it in an HTML page like this:
;;
;; <!DOCTYPE html>
;; <html>
;; <head>
;;     <title>fib</title>
;;     <script type="text/javascript">
;;         function print(x) { console.log(x); }
;;     </script>
;;     <script type="text/javascript" src="fib.js"></script>
;; </head>
;; <body></body>
;; </html>

(declare
  (standard-bindings)
  (extended-bindings)
  (not safe)
  (fixnum)
  (block)
)

(define (fib n)

  (define (fib n)
    (if (< n 2)
        n
        (+ (fib (- n 1))
           (fib (- n 2)))))

  (fib n))

(define start (real-time-milliseconds))

(println (fib 30))

(define end (real-time-milliseconds))

(println (- end start))

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4839 bytes
Desc: not available
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20150131/ff0506a3/attachment.bin>


More information about the Gambit-list mailing list