feeley on master
Universal backend: fix bitrot i… (compare)
gambiteer on master
Add partition unit tests Merge branch 'master' of https:… (compare)
feeley on master
Windows: allocate new console o… (compare)
perhaps your design is wrong
For me to understand please provide pseudocode/a code example that illustrates how this would be done. I guess typical would be input available on port (say on two ports), port become writable (say on two ports), mutex lock completed, and sleep completed.
Bumping this up in case it was unnoticed
@feeley I haven't studied the building of the online Gambit REPL (https://github.com/gambit/gambit/tree/master/contrib/try) but I wonder if you could point me to a way to reduce the built size of the JavaScript for that. It was over 11 MB when I built it. Is there a part of it (say, without some of the SRFI code or some of the math code) that can be built by redefining some make or shell variable? Something like that? I'd like to have an online Gambit REPL in just 1 or 1.5 MB of JavaScript.
Redefining a make target would be a good option, too, if it wouldn't make the build process fail.
du -hs VM.min.js*
4.9M VM.min.js
688K VM.min.js.gz
find /nix/ -name 'libgambit.so' -exec du -h {} \;
8.5M /nix/store/m27913wknikn3nkqiny6j0m68kily4np-gambit-unstable-2020-07-29/gambit/lib/libgambit.so
@tomelam Please read the comments at the top of contrib/try/makefile.in
:
# To build VM.js from VM.scm you need a recent Gambit with the JavaScript
# backend. It can be compiled like this (from an existing bootstrapped
# recent installation):
#
# cd gambit
# git pull
# make clean
# ./configure --enable-single-host --enable-targets=js --enable-default-compile-options="(compactness 9)" --prefix=/usr/local/Gambit
# make
# make doc
# make modules
# sudo make install (optional)
The VM.js
file (the bulk of the Gambit online REPL) will be postprocessed by the google closure compiler and when the result is gzipped you will get a 640KB file
If you want to go even smaller, you can trim some stuff from the runtime library, such as support for complex numbers, exact rationals and bignums by using configure
options such as --disable-cpxnum
, etc. To enable the “smart linker” you need to do a “whole-program” compilation that includes the file lib/_univlib.scm
and prefix the code with (declare (optimize-dead-definitions))
. Note that this will remove some of the runtime library so your REPL won’t be able to access the definitions that were removed (it is a compilation strategy that works best for complete applications).
#!optional
when specifying a named #!key
? In the following example, I thought opt-a
would get a default value of #f
:> (define (f req #!optional opt-a #!key key-x) (list req opt-a key-x))
> (f 1)
(1 #f #f)
> (f 1 2)
(1 2 #f)
> (f 1 key-x: 3)
*** ERROR IN (stdin)@4.1 -- Wrong number of arguments passed to procedure
(f 1 key-x: 3)
1>
key-x:
is a value that will be bound to the opt-a
parameter. So the first two arguments are handled as required and optional parameters. What is left is the argument 3
which is not acceptable since there are no additional optional parameters to match to. Please read section 6.2 of the manual for the detailed semantics (which is the one specified for DSSSL).
@tomelam Don’t hesitate to ask more questions here if you get stuck.
@feeley So very kind of you. Gambit's JS target is the 3rd Scheme in JS I've used. Currently I'm using Biwascheme for my hobby project (https://tomelam.gitbook.io/mashweb, http://web-call.cc, https://mashweb.club). If I can get the payload small enough, it will be a great boon to my project. Currently Biwascheme is missing some important things, even though it's interesting to work with. My degree was in EE, not CS. Compiler-like stuff is way over my head.
load
or import
or eval
. What programming language features are needed by your app?
@tomelam To get you started, here is how to compile a minimal web app to Scheme… First you should build Gambit with:
./configure --enable-single-host --enable-targets=js --enable-default-compile-options="(compactness 9)”
make
make modules
This will build the JS version of the Gambit runtime library and produce compact JS code. Then create a mini-web-app
directory and put in it this makefile
, index.html
and app.scm
:
all: app.min.js
app.js: app.scm
gsc -target js -label-namespace "z" -exe -o app.js app.scm
app.min.js: app.js
npx google-closure-compiler --language_in=ECMASCRIPT_2015 --language_out=ECMASCRIPT_2015 --js app.js --js_output_file app.min.js
sed -I .tmp -e "s/^'use strict';//" app.min.js
gzip -k -9 app.min.js # optional but useful if the web server can send .gz files
clean:
rm -f app.js app.min.js app.min.js.gz
<!doctype html>
<html>
<head><script src="app.min.js"></script></head>
<body onload="scheme_program_start();"></body>
</html>
;;; File: "app.scm"
(include "~~lib/_gambit#.scm")
(include "~~lib/_six/js#.scm")
(##inline-host-declaration #<<end-of-host-code
// Defer Scheme code execution until scheme_program_start is called.
scheme_program_start = @all_modules_registered@;
@all_modules_registered@ = function () { };
end-of-host-code
)
(define alert \alert)
(define prompt \prompt)
(define (body-html-set! html) \document.body.innerHTML=`html)
(body-html-set! (string-append "<h1>"
(prompt "Please enter your name")
"</h1>"))
(thread-sleep! 0.1) ;; let browser update the screen
(alert "The body now contains your name!\nClick OK to replace it with the New-York weather forecast.\n")
(define (fetch-json url)
\fetch(`url).then(function (r) { return r.json(); }))
(define x
(fetch-json "https://forecast.weather.gov/MapClick.php?lat=40.78333&lon=-73.96667&FcstType=json"))
(define temp \(`x).currentobservation.Temp)
(define name \(`x).currentobservation.name)
(body-html-set! (string-append "<h1>" name ": " temp "F</h1>"))
;; uncomment the following to start a REPL:
;;(thread-sleep! 0.1) ;; let browser update the screen
;;(##repl-debug-main)
Then after a make
just open index.html
in a browser.
call/cc
, a arithmetic operations (at least block floating point), hopefully a module system, the ability to load a full Scheme implementation bit by bit, and a foreign function interface for JavaScript.
call/cc
. Briefly, the idea is to create something like POSIX's system calls select(2)
and poll(2)
. I will sort out the priorities of the events in the top-level event loop.
with-handlers
, which is perhaps not the best name). If a particular type of input could best be handled in a different thread (like Ajax events from the loading of a large file), that could also be done. But at some point the page will need to change state to reflect a pivotal event like the completion of an input string or the press of a submit button. Since the human user could direct a different response (for example, by pressing a 'Cancel' button), I designed with-handlers
to gate any and every event that could affect the subsequent flow of the main loop of the program.