With the most recent changes to the universal backend and library, Gambit's JavaScript and Python backends are now much easier to use.
The following steps will build and install the universal library with the JavaScript and Python backends:
% make % make _gambit.js _gambit.py % make install
Scheme programs can be compiled to either JavaScript or Python shell scripts by specifying the -exe flag and the target language to gsc:
% gsc -target js -o fib-js -exe fib.scm % ./fib-js (time (f 30)) 0.076000 secs real time 0.076000 secs cpu time (0.076000 user, 0.000000 system) no collections no bytes allocated no minor faults no major faults 832040 % cat fib.scm (declare (standard-bindings)) (define (f n) (if (< n 2) n (+ (f (- n 1)) (f (- n 2))))) (println (time (f 30)))
It is also possible to build a version of the Gambit interpreter implemented in JavaScript with:
% gsc -target js -o gsi-js -exe -prelude '(include"../lib/header.scm")' gsi/_gsi.scm
Replacing "js" with "python" will build gsi implemented in Python:
% ./gsi-python Gambit v4.9.3
(host-decl "import os") (define (env var) (host-eval "g_host2scm(os.environ[g_scm2host(@1@)])" var)) (env "TERM")
"dumb"
,q
% ./gsi-js Gambit v4.9.3
(define (f n) (if (< n 2) n (+ (f (- n 1)) (f (- n 2))))) (time (f 30))
(time (f 30)) 2.254000 secs real time 2.254000 secs cpu time (2.254000 user, 0.000000 system) no collections no bytes allocated no minor faults no major faults 832040
(apropos 'inexact)
"##" namespace: exact->inexact, fail-check-inexact-real, fail-check-inexact-real-list, flonum->inexact-exponential-format, inexact, inexact->exact, inexact? empty namespace: exact->inexact, inexact, inexact->exact, inexact?
(define (show x) (host-exec "console.log(g_scm2host(@1@));" x)) (show "hello")
hello
(show (host-eval "g_host2scm(new Date().toString())"))
Sun Mar 22 2020 23:20:29 GMT-0400 (GMT-04:00)
,q
The universal library is quite large (> 30MB)... so the memory conscious may choose to link with a custom runtime library that defines only the procedures needed. The compiler's -l flag is useful to specify the library to link with.
;;; minlib.scm
(println "running minlib.scm")
(define (twice thunk) ;; exported procedure (thunk) (thunk))
(define (##run-each-module) (declare (extended-bindings) (not safe)) (let ((mods (##vector-ref ##program-descr 0))) (let loop ((i 1)) ;; start at module after the current one (if (##fx< i (##vector-length mods)) (let ((mod (##vector-ref mods i))) ((##vector-ref mod 4)) ;; call module's init procedure (loop (##fx+ i 1)))))))
(##run-each-module) ;; run each module (after the current one)
;; To use this minimal library to compile a program prog.scm, ;; follow these steps: ;; ;; % cat prog.scm ;; (twice (lambda () (println "hello"))) ;; % TARGET=js # could also be python or php ;; % gsc -target $TARGET -c minlib.scm ;; % gsc -target $TARGET -l minlib -exe prog.scm ;; % ./prog ;; running minlib.scm ;; hello ;; hello ;; % head -1 prog ;; #! /usr/bin/env node
There are still some issues with the universal backend, but it is now much closer to the features offered by the C backend.
Marc
Afficher les réponses par date
I figured that users of the Javascript backend would prefer to have smaller file sizes than speed improvements on "bigger" bignums (bigger than about 2000 bits), so I just turned off the "fast" bignum algorithms for Javascript in this commit:
https://github.com/gambit/gambit/commit/eda058a10772fa93beef9398c297e41f6f5b...
I wanted to see what difference it might make in computation speed, so I took the file chud1.scm from
https://mailman.iro.umontreal.ca/pipermail/gambit-list/2013-June/006789.html
which computes pi to varying number of digits, and built it as Marc suggested. I then went back and turned fast algorithms back on
With "fast" algorithms:
firefly:~/programs/gambit/pi-programs> ./pi-js Chudnovsky's algorithm using binary splitting in Gambit Scheme: digits 10, CPU time: .01399993896484375. Last 5 digits 26535. Chudnovsky's algorithm using binary splitting in Gambit Scheme: digits 100, CPU time: .003999948501586914. Last 5 digits 70679. Chudnovsky's algorithm using binary splitting in Gambit Scheme: digits 1000, CPU time: .03099989891052246. Last 5 digits 1989. Chudnovsky's algorithm using binary splitting in Gambit Scheme: digits 10000, CPU time: .7229998111724854. Last 5 digits 75678. Chudnovsky's algorithm using binary splitting in Gambit Scheme: digits 100000, CPU time: 9.877000093460083. Last 5 digits 24646. Chudnovsky's algorithm using binary splitting in Gambit Scheme: digits 1000000, CPU time: 154.63499999046326. Last 5 digits 58151.
With no fast bignum algorithms:
firefly:~/programs/gambit/pi-programs> ./pi-js-old Chudnovsky's algorithm using binary splitting in Gambit Scheme: digits 10, CPU time: .01399993896484375. Last 5 digits 26535. Chudnovsky's algorithm using binary splitting in Gambit Scheme: digits 100, CPU time: .004000186920166016. Last 5 digits 70679. Chudnovsky's algorithm using binary splitting in Gambit Scheme: digits 1000, CPU time: .023000001907348633. Last 5 digits 1989. Chudnovsky's algorithm using binary splitting in Gambit Scheme: digits 10000, CPU time: .8480000495910645. Last 5 digits 75678. Chudnovsky's algorithm using binary splitting in Gambit Scheme: digits 100000, CPU time: 96.76300001144409. Last 5 digits 24646. Chudnovsky's algorithm using binary splitting in Gambit Scheme: digits 1000000, CPU time: 11859.043999910355. Last 5 digits 58151.
You don't really see much difference until you start computing 100,000 digits of pi (about 332,195 bits), were the "fast" algorithms are about 10 times as fast as the regular algorithms.
So I think that's the right trade-off to have slightly slower bignum operations for "small" bignums for about 5% smaller library.
Brad