Marc-André Bélanger
Marc Feeley
Presented at ELS 2021
https://zenodo.org/record/4711424Built with Gambit Scheme and RevealJS.
Available at https://udem-dlteam.github.io/els2021-presentation/
(c-declare "#include <math.h>")
(define ldexp (c-lambda (double int) double "ldexp"))
The FFI is implementation specific, idiosyncratic.
(c-declare #<<c-declare-end
typedef char EBCDIC; /* EBCDIC encoded characters */
void put_char (EBCDIC c) { ... } /* EBCDIC I/O functions */
EBCDIC get_char (void) { ... }
char EBCDIC_to_ISO_8859_1[256] = { ... }; /* conversion tables */
char ISO_8859_1_to_EBCDIC[256] = { ... };
___SCMOBJ SCMOBJ_to_EBCDIC (___SCMOBJ src, EBCDIC *dst)
{
int x = ___INT(src); /* convert from Scheme character to int */
if (x > 255) return ___FIX(___UNKNOWN_ERR);
*dst = ISO_8859_1_to_EBCDIC[x];
return ___FIX(___NO_ERR);
}
#define ___BEGIN_CFUN_SCMOBJ_to_EBCDIC(src,dst,i) \
if ((___err = SCMOBJ_to_EBCDIC (src, &dst)) == ___FIX(___NO_ERR)) {
#define ___END_CFUN_SCMOBJ_to_EBCDIC(src,dst,i) }
#define ___BEGIN_CFUN_EBCDIC_to_SCMOBJ(src,dst) \
{ dst = ___CHR(EBCDIC_to_ISO_8859_1[src]);
#define ___END_CFUN_EBCDIC_to_SCMOBJ(src,dst) }
#define ___BEGIN_SFUN_EBCDIC_to_SCMOBJ(src,dst,i) \
{ dst = ___CHR(EBCDIC_to_ISO_8859_1[src]);
#define ___END_SFUN_EBCDIC_to_SCMOBJ(src,dst,i) }
#define ___BEGIN_SFUN_SCMOBJ_to_EBCDIC(src,dst) \
{ ___err = SCMOBJ_to_EBCDIC (src, &dst);
#define ___END_SFUN_SCMOBJ_to_EBCDIC(src,dst) }
c-declare-end
)
(c-define-type EBCDIC "EBCDIC" "EBCDIC_to_SCMOBJ" "SCMOBJ_to_EBCDIC" #f)
(define put-char (c-lambda (EBCDIC) void "put_char"))
(define get-char (c-lambda () EBCDIC "get_char"))
(c-define (write-EBCDIC c) (EBCDIC) void "write_EBCDIC" ""
(write-char c))
(c-define (read-EBCDIC) () EBCDIC "read_EBCDIC" ""
(read-char))
The FFI is implementation specific, idiosyncratic.
(define (hello name)
\alert("Hello, "+(`name)+"!"))
(define (set-bg-color color)
\document.body.style.background=`color)
function foo(x) {
return x;
}
(define (foo x) x)
Gambit has a reader extension to parse an infix language
Interfacing to pure JavaScript
(* (+ 1 2) \3+4 (+ 5 6))
(string-append \"a" "b" \"c")
\alert("ELS 2021")
\document.body.style.background="blue"
(define add1 \function(x) { return x+1; })
Mixing JavaScript and Scheme expressions
\1+`(* 2 3)
\1+`var
(string-append "now: " \ new Date().toString())
(+ 1 2 \3*4*(`5) 6 7)
\Math.sqrt(`9)-3
(let ((x 10)) \Math.sqrt(1/`x))
Resolving identifier ambiguities
(define number-of-items 100)
\10*`number-of-items
\`number-of-items*10
\(`number-of-items)*10
The \
reader macro constructs an AST from a SIX expression>
'\2*`v[i+1]
(six.infix
(six.x*y
(six.literal 2)
(six.index
(quasiquote v)
(six.x+y
(six.identifier i)
(six.literal 1)))))
six.infix
macro`
expression, eval'd, converted and passedPass-through types
(scheme val) ---> _Scheme object
foreign(val) ---> _Foreign object
(define (add1 x) \(`x)+1)
(define num 1+2i)
(println \(`num).scmobj.imag)
\(`num).scmobj.imag=9
(println num)
(define-syntax future
(lambda (stx)
(syntax-case stx ()
((future expr)
#'(thread (lambda () expr))))))
(define touch thread-join!)
(define (pmap f lst)
;; "parallel" map
(map touch (map (lambda (x) (future (f x))) lst)))
(define memo
(string-append
"Scheme_-_An_interpreter_for_extended_"
"lambda_calculus.djvu"))
(define (page n)
(string-append
"https://upload.wikimedia.org/wikipedia"
"/commons/thumb/1/1e/" memo
"/page" (number->string n) "-593px-" memo ".jpg"))
(define (fetch-blob url)
\fetch(`url).then(function (r) { return r.blob(); }))
(define (->URL blob)
\URL.createObjectURL(`blob))
(define (show url)
\document.getElementById("threads").insertAdjacentHTML(
"beforeend",
"<img src='"+(`url)+"' width=200px>"))
(define (images)
(pmap (lambda (n) (->URL (fetch-blob (page n))))
(iota 43 1)))
;(for-each show (images))
(define (fetch-json url)
\fetch(`url).then(function (r) { return r.json(); }))
(define url "https://api.wheretheiss.at/v1/satellites/25544")
(define (add-marker p)
(let loop ()
(let* ((json (fetch-json url))
(lat \(`json).latitude)
(lon \(`json).longitude)
(marker (list->table `(("latLng" ,lat ,lon)))))
\iss_markers.push(`marker)
\map.addMarker(iss_markers.length, `marker)
(thread-sleep! p)
(loop))))
(define (update-iss-position p)
(thread (lambda () (add-marker p))))
(define (start)
\document.getElementById("ui-10").style.display="none"
\showMap()
(thread-sleep! 2)
(update-iss-position 10))
foreign import javascript "console.log($1)" f :: Double->IO()
(.println System.out$ "hello")
→ System.out.println("hello")
#lang
) or single form:
(+ 1 #reader"js.rkt"Math.sqrt(2) 3)
This presentation is available at
https://udem-dlteam.github.io/els2021-presentation/
Try out Gambit Scheme's JS REPL at
https://gambitscheme.org/try