With the "silent" release of 4.9.4 I'm intrigued to learn how to actually use the alternative compile backend choice.
Initially confining myself to the `js` backend with HTML output.
1) A simple `(display "Hello World!")` gave no result.
Where does content written to standard-{output,error}-port end up?
2) Raising an error or `(##repl)` give me a more or less nice REPL. Unfortunately the source code does not look like a good starting point to learn how that REPL is implemented.
Attached my current "Hello World!" using `##inline-host-statement` to call into JavaScript. (Deduced from digging into gambit source.)
I ran into https://github.com/udem-dlteam/els2021-presentation which explains inline syntax but this syntax seems not to work with 4.9.4 unless there is a trick I missed.
Is there example code out there (or anything better) to learn how working code manipulating DOM could roughly work?
Any documentation on ##inline-host-* , @scm2host@ and friends would also be very welcome.
3) Figuring out what is or is not supported per backend could become a nightmare. Right now I found `open-tcp-server` to return #!void, `open-tcp-client` to complain about wrong number of arguments. Both are not really helpful to understand that this documented procedure is not yet implemented.
My own solution to the recurring situation is to have (very few) all upper case acronyms defined which are easy to spot visually or via grep. NYIE in this case, which is a procedure accepting any number of arguments and raises a not-yet-implemented-exception.
I don't expect a book of unimplemented features, am I missing something?
Thanks for Gambit!
/Jörg
Afficher les réponses par date
On Jan 20, 2022, at 2:07 PM, Jörg F. Wittenberger Joerg.Wittenberger@softeyes.net wrote:
With the "silent" release of 4.9.4 I'm intrigued to learn how to actually use the alternative compile backend choice.
Initially confining myself to the `js` backend with HTML output.
- A simple `(display "Hello World!")` gave no result.
Where does content written to standard-{output,error}-port end up?
The JavaScript backend implements the following:
#1 - The (current-output-port) is attached to the JavaScript console, which is viewable using your browser’s developer tools. So that’s where `display`, `write`, `newline`, `pretty-print`, will show their output by default.
For example this will show “Hello World!” in the JavaScript console:
$ cat hw.scm (display "Hello World!\n") $ gsc -target js -exe -o hw.html hw.scm $ open hw.html
#2 - The (repl-output-port) is attached to a “simulated console” implemented using the JavaScript `prompt` function, which shows up as a dialog box. So if you call `pp` or `(display … (repl-output-port))` the output will be scheduled to be shown in this dialog box… but the dialog box will only appear when the program reads from this console (which is normally the case in a Read-Eval-Print-Loop).
For example this will show “Hello World!” in the dialog box:
$ cat hw.scm (display "Hello World!\n" (repl-output-port)) (read) ;; dummy read to allow "simulated console" to be displayed $ gsc -target js -exe -o hw.html hw.scm $ open hw.html
You can call `(##repl-debug-main)` in the program to initiate the Gambit REPL that interacts with this simulated console:
$ cat hw.scm (##repl-debug-main) $ gsc -target js -exe -o hw.html hw.scm $ open hw.html
and this redirects the `(current-input-port)` and `(current-output-port)` to the simulated console so that I/O appears where most programmers expect it to go (in the REPL’s console). At any time you can use the `##stdout-port` to send output to the JavaScript console: (display "Hello!\n" ##stdout-port) .
- Raising an error or `(##repl)` give me a more or less nice REPL.
See previous point #2.
Unfortunately the source code does not look like a good starting point to learn how that REPL is implemented.
Attached my current "Hello World!" using `##inline-host-statement` to call into JavaScript. (Deduced from digging into gambit source.)
This is another option which uses `##inline-host-statement` to interface to the JavaScript `alert`:
$ cat hw.scm (define (alert msg) (##inline-host-statement "alert(@scm2host@(@1@));" msg)) (alert "Hello World!\n") $ gsc -target js -exe -o hw.html hw.scm $ open hw.html
Note that the `##inline-host-statement` can take parameters, which are accessible with `@1@`, `@2@`, etc in the string of code. Also note that the conversion from the Scheme object representation to the JavaScript object representation is not automatic. That’s why there’s an explicit call to the `@scm2host@` function. There’s a `@host2scm@` function also to convert in the other direction. The `@…@` notation is a way to automatically add to the identifier the identifier prefix that is currently being used by the Gambit JavaScript backend (it is `_` currently).
I ran into https://github.com/udem-dlteam/els2021-presentation which explains inline syntax but this syntax seems not to work with 4.9.4 unless there is a trick I missed.
Yet another option which simplifies the Scheme code it to use the `_six/js` module. This module provides a JavaScript FFI that is based on an infix syntax and the data conversions are done automatically. Here’s an example:
$ cat hw.scm (import (_six js)) (define (console-log msg) \console.log(`msg)) (console-log "hello world") $ gsc -target js -c -o js.js ~~lib/_six/js.sld $ gsc -target js -c -o six-expand.js ~~lib/_six/six-expand.scm $ gsc -target js -exe -o index.html -nopreload js.js six-expand.js hw.scm $ open index.html
Is there example code out there (or anything better) to learn how working code manipulating DOM could roughly work?
Marc-André Bélanger is working on a DOM module. He’s usually listening to the Gambit gitter chat if you want to drop by. A good place to start is the paper we wrote on the SIX JS FFI: http://www.iro.umontreal.ca/~feeley/papers/BelangerFeeleyELS21.pdf
Any documentation on ##inline-host-* , @scm2host@ and friends would also be very welcome.
Sorry… no official documentation. Part of the reason is that I think there will soon be a refactoring of all the FFI stuff (in all the backends) and `##inline-host-*` will probably be renamed `host-eval`, `host-exec` and `host-decl`. We need to experiment some more before it becomes official.
- Figuring out what is or is not supported per backend could become a
nightmare. Right now I found `open-tcp-server` to return #!void, `open-tcp-client` to complain about wrong number of arguments. Both are not really helpful to understand that this documented procedure is not yet implemented.
My own solution to the recurring situation is to have (very few) all upper case acronyms defined which are easy to spot visually or via grep. NYIE in this case, which is a procedure accepting any number of arguments and raises a not-yet-implemented-exception.
I don't expect a book of unimplemented features, am I missing something?
I agree that the Universal Backend doesn’t have the same level of polish as the C backend. The recent focus has been on experimentation and seeing what features can/should be implemented. What you suggest is certainly doable given enough time. Don’t hesitate to send in pull-requests or contribute to any part of Gambit that you feel needs improving… we are always looking for contributors!
Marc