Hello. This is Scheme in the Browser with Guile Hoot and WebAssembly. I am surrogate
Robin Templeton. We are the Spritely Institute. We build decentralized network technology.
I'm going to open up with what is WebAssembly. It's a W3C open standard. It is a low level
compilation target for the web. It's available in browsers since 2017. One of the big things
we needed to make this happen is support for Wazem GC. It stands for garbage collection.
Supported in Firefox and Chromium since very recently, late 2023. Why should you care?
Why should you give a hoot? JavaScript is no longer the only game in town. You have a language
that you really like. You can use that language. If you are familiar with some, I know there are
a bunch of Guile people in the room. We have tried compiling to JavaScript and we have seen
a lot of languages that have done such things in the past. You had to take a lot of compromises.
They were a lot slower. It was messy. By compiling to WebAssembly instead, you are compiling to a
virtual machine designed for you to bring your language to it. It follows the capability
security model. As you may know, we are all about the object capability security model.
Things are reasonably fast. It is increasingly used in non-browser context.
Despite the name web, it is used as an abstract virtual machine for many different things, including
people to write and use it as a Docker replacement, etc. What is Guile? We are targeting this
Guile thing. It is a flexible scheme. It supports a bunch of standards, etc. It has a nice VM.
It is also traditionally used for very unixy systems. Robins here. Until today. We will do a tradeoff
when Robin gets up here. We have had some decisions that we have needed to make. I will let Robin
resume with what those decisions are. I will come straight up.
We are abstractly replacing.
Yes, I was in the next room for a few minutes accidentally. Continuing with decisions.
Thanks for starting it off. Sorry I am running late. Continuing with the decisions we had to make
starting this project. We could have just compiled Guile in C via M script in it or something
and run it straight in the web browser along with its various C dependencies like the BGMP and the BWGC.
We would have probably gotten that done in a week or two. We would have paid a big performance
penalty and also we would have had much worse integration with JavaScript. We expect.
The second option was to work with the experimental WebAssemblyGC extensions and we could expect a higher
performance with that. In fact, that is what we are seeing. Not that we have a comparison, but
presumably we are getting decent performance and excellent integration with JavaScript.
We will not with option two, of course. That is Guile Hoot. It is a WebAssembly to Scheme compiler.
It is built on the newly shipped WebAssemblyGC extensions. It includes a full WebAssembly toolchain.
We are bringing the whole Scheme language to web applications so you can use Continuation,
Nubium, Merrick Tower, any normal Scheme thing in your interactive Web application.
The goals for this project were, of course, first of all, to run Goblet's applications in Web browsers,
which essentially means general support for Guile applications. Plus some sort of user interface library.
As well as to advocate for dynamically typed languages in general in the WebAssembly world.
We are also providing an alternative WebAssembly toolchain as a consequence of our development process.
I am not going to go through the code for this, but this is the inner loop for Wireworld, which is a
sort of a circuit simulator. We will quickly...
You can switch tabs, but I have it open.
Okay, thanks. Is this the tab for it?
Control tab through. This will be good enough.
This is a graphical demonstration of Wireworld. We might have a live version here.
This is a bit slow actually drawing, but yes, as we all learn in physics class, electrons have a head and tail.
There will generate one, and that is a tiny circuit simulator.
Back to the presentation.
As far as our status, as far as how far we have gotten in Gauhut, we have basically all of our 7-in-1-small Scheme.
That was our initial target because it is a very small and modern specification and has several implementations and a nice benchmark suite and so on.
We are starting to add Gauhut in R6RS features.
In version 3 that we released this week, we just added an R6RS library system.
A couple of hash table types based on R6RS.
We are starting to work on debugability in the browser starting with names for WebAssembly level objects.
WebAssembly functions, for example, have names that you can see in the browser debugger like in backtraces.
We can also run the R7RS benchmarks now.
We are getting decent results there. We are now focusing on performance as well as functionality.
Who does a bit of an unusual list implementation because it is not a standalone self-hosting self-contained compiler.
It is heavily integrated with Gauhut. It will presumably always be integrated with Gauhut, but it is not a normal Unix Gauhut.
We reuse the compiler tower that Gauhut has that takes in Scheme or another language like EmacsLisp on the front end.
It goes through a couple of intermediate representations.
Normally we would output at the last stage after TRIAL, which is Minimum List Scheme basically, and a Continuation Passing Style layer that is quite low level.
We would output Gauhut bytecode, which is a high level bytecode for list-byte languages.
With some tweaks to the compiler tool chain, we are able to output WebAssembly instead of Gauhut bytecode.
That required very minor changes to the compiler, comparatively speaking.
We also cannot use libGaile, which is in C and has a bunch of C dependencies, including its own garbage clutter where we want to use the browsers.
We are building a new Scheme Runtime as part of Gauhut.
That is written in WebAssembly as well as Scheme and Scheme Intermix with WebAssembly and so on.
We are targeting Gauh compatibility overall and making progress on that front.
From the host, typically the browser and WebAssembly terms,
we need a few things beyond the basic WebAssembly that would have been available a few years ago,
that you might have used in Google Docs or something like that.
We need the garbage collection extensions.
Those only got enabled in browsers by default in Chromium and Firefox last December, so quite new.
We need tail calls, which are part of the basic specification as far as I know,
and so that's very nice to not have to have any workarounds there with trampolining and things like that.
We need string support, which is not part of base WebAssembly at this time.
There's a proposal we like that we use on the source code level,
but we have workarounds that work in browsers with native JavaScript strings with a bit of overhead.
Like I mentioned, the latest Firefox and Chromium have all the extensions you need,
and it is being actively worked on in WebKit,
so we're expecting all major browsers to support Hoot programs in the very near future.
End of the year, definitely.
Any project like this has its pros and cons, so on the good side,
WebAssembly text is the source code format for WebAssembly, and it's just S expressions.
We don't even have a separate parser for anything, we just write scheme S expressions.
That's quite nice for both generating WebAssembly code and for integrating it, embedding it, and scheme.
We have tail calls for free, which is definitely convenient,
and the reference type system that WasmGC provides for heap objects,
which gives you more than just numbers, it gives you structures for subtyping,
it gives you arrays, it gives you 31-bit integer value for tags, stuff, and dynamic languages.
So that's all good, and then there are some difficulties that we will be addressing,
so there's limited support for strings in WebAssembly or in browsers in general.
There are no first class continuations, so we have to sort of reify a lot of the things
that would normally just be implicit in the scheme program to get access to it
for where, say, access to the stack is limited from WebAssembly for security reasons.
Access to the heap is limited for security reasons, so things like that.
And there are limited GC features, so there are no finalizers for example,
and that's mostly because languages are so diverse in what they allow for that kind of feature.
But we'll want some advanced GC features for goblins.
So this is a little example from the runtime, showing a bit of WebAssembly code.
This is a portp predicate, testing if x is a port object.
You see the inline Wasm special form, and then a quoted bit of WebAssembly source code
that represents an anonymous function.
RefEek is the scheme untypes, scheme value, so we have a function from a scheme value
to a scheme value, and it just tests if the x object is a port structure or not
and returns the magic five values for true or false depending.
So pretty simple, but very convenient for writing the standard library.
So we provide our own self-contained WebAssembly tool chain.
It lets you develop WebAssembly in one place conveniently from your REPL or whatever you like to use,
so it is an alternative to the more mainstream options like binary N or the WebAssembly binary toolkit.
It's a set of scheme modules that provide easy access in programs and from the REPL,
also some command line tools where that makes sense.
That can name basically what you'd expect, parser, assembler, disassembler, linker, dumper.
But we also have a very nice interpreter that my co-worker Dave Thompson mostly wrote,
and that allows you to do debugging of WebAssembly using tools very similar to what you get in a GaL REPL,
which is great for interactive development.
So a little example is a function that squares the number.
We're importing a couple of packages to get access to the runtime or the interpreter.
And we're compiling this Lambda expression.
When we look at the Hoot square expression on the next line,
the Hoot wrapper indicates that it is a WebAssembly object, not a regular scheme procedure.
And then we can call it transparently like a scheme procedure to see that 4 times 4 equals 16.
So the basics work.
In the future, we're going to be working on more R7 or R5 small features.
That's mainly the library system where we just landed R6RS libraries.
So we'll be building our 7RS small libraries and GaO modules on top of that functionality.
We're going to want definitely a lot more GaO compatibility in terms of libraries and surfies and stuff,
and especially fibers for concurrency.
It's very important for goblins.
And finally, we want to be able to run goblins programs on top of GaO Hoot,
and we really expect to be able to do that with few to no changes in terms of the network interfaces and things like that.
And the future of WebAssembly also has some bearing on the direction of our projects.
We had a pretty decent impact on the WASM GC proposals.
The W3C WebAssembly community group is open to anyone who's interested.
You don't have to be a big organization.
We're definitely not, but we had some influence on the proposal as an early adopter,
along with languages like OCaml and Kotlin.
And so GaO Hoot makes a scheme, a practical alternative to JavaScript for interactive web applications.
So you can write full programs with no JavaScript besides what is needed for loading the WebAssembly file.
We believe WebAssembly should have space for all languages, not just low-level statically type ones,
and hooters for scheme, but not necessarily just for scheme because our tool chain may be interesting for other projects.
We have...
We'll skip the rebel demo.
We have to stop Robin.
Alright.
So next speaker can set up.
Robin, you can still answer questions.
Oh yes.
Any questions?
Here's one.
Where's the microphone?
You can have one.
I can sound.
What happened to the mic?
The microphone.
There you go.
Oh, thank you.
I got it.
Enjoy the actual question.
Do you have a place to get a form in the background?
No, maybe.
It's not going to work out because there's no narration.
Okay, a question.
You said that you don't support first class continuations, but you also said that you already do CPS in real.
So my question is, if you already do CPS, if you verify your stack, then it seems not so difficult to do that first class continuations after all.
We have first class continuations.
Repeat the question.
Yes, so repeat the question.
I think the question was basically...
Sorry, could you repeat the premise that started the question?
I mean, you said you don't have first class continuations yet, right?
We do have...
So the question was whether we...
was partly whether we have first class continuations, and we do.
So we had to modify, add a pass to the GAL compiler tower to do tailification, which is just turning all non-tail calls into tail calls.
And so that turns the...
That gets us to the point on the Web assembly level where everything is split into small basic blocks.
And we have...
An ABI that reifies various stacks, and so we do have access to delimited continuations and who...
And actually, call with current continuation is implemented in terms of delimited continuations, which I think is pretty rare for schemes.
Okay, so you do reify the stack.
Yeah, we have to reify stack.
We have to reify several stacks because of Web assembly details, but we do have first class...
Delimited and full continuations available right now.
It's one of the first things we designed for.
And that was Andy's design work for getting you out to work with Web assembly.
Any more questions?
I think we have a couple of questions.
Andy, you have to go back for getting you out to work with Web assembly.
Any more questions?
You have to go back?
Yes.
How do you shoot in Strigoform?
I believe that you hit the Z or Z button.
Strigoform.
Strigoform?
Okay, so yes.
So Z fires.
And yes, if you load the talk in or just load up the game directly on HIO, it's by my co-worker David Thompson with Graphics by Christine.
And it's got particle effects, parallax shooting, audio, etc. are going on.
But Scheme is not the bottleneck in terms of performance.
The bottleneck is the JavaScript canvas.
So we're doing that well on performance already without having taken it into consideration before.
Thank you.
Oh. Do we have time for another?
I have a question from Matrix.
I understand one of the goals is compatibility with Gile.
However, some of the functions in the Gile standard library like open file and networking functions are not defined with security capabilities in mind.
What's your plan to deal with these cases?
That's a fantastic question.
Christine will address some of this in hard talk at noon.
And there are also some WebAssembly proposals like Wazzy and Wazix that could provide POSIX compatibility if we wanted to run it on a non-vouser runtime for, say, geeks integration or something like that.
But in general, those APIs won't be used by Goblin's programs for the most part.
But we will provide the compatibility.
We will provide both because we already started the next talk.