WEBVTT 00:00.000 --> 00:11.600 Okay, thank you all. We are going to start now with David, who is going to talk to us about 00:11.600 --> 00:18.600 wasom gc, easy subject, right? Yeah, it's super easy. Can everyone hear me? Okay, cool. 00:18.600 --> 00:25.280 Hi everybody, my name is Dave, I am the CTO at the Sprite Lee Institute, and I'm here to talk 00:25.280 --> 00:32.000 to you about WebAssembly, and specifically the garbage collection proposal that was recently 00:32.000 --> 00:38.200 put into the standard. So we'll quick about Sprite Lee. We're a small US-based 501C3 non-profit, 00:38.200 --> 00:44.080 and our mission is to develop the next generation of decentralized technology for the social 00:44.080 --> 00:50.240 web. And in TSO, we have a number of projects. Just a quick overview. Our big ones are 00:50.240 --> 00:54.800 goblins of the distributed programming environment. We'll cap in the object capability network. 00:54.800 --> 01:00.240 It's a protocol we're developing, not only with ourselves, but with other like-minded organizations. 01:00.240 --> 01:04.640 But the one that's most relevant to this discussion, this talk, is a suit. It's a scheme to 01:04.640 --> 01:11.680 WebAssembly compiler and a WebAssembly tool chain. So here's our little cute pixel art mascot, made by 01:11.680 --> 01:17.760 our executive director, Christine Lamar Weber. And yeah, so real quick, before I get into general 01:17.840 --> 01:23.840 Razum's stuff, so who's a compiler? It's a compiler WebAssembly. The source language is Giles scheme. 01:23.840 --> 01:30.400 We're big fans of Lisp at Sprite Lee. It's a whole program compiler that aims to try to make 01:30.400 --> 01:36.080 this as small of a binary as possible for efficient delivery to clients, you know, particularly 01:36.080 --> 01:42.320 in web browsers. And we target the GC proposal, and we're pretty early adopters of that proposal 01:42.320 --> 01:47.440 before it made it, you know, to phase four, which is like the final phase in the- in the 01:47.440 --> 01:52.720 Wazum community group for adoption to the standard. And notably, it does not use the unscripted 01:52.720 --> 01:59.520 info chain, which most WebAssembly projects use, because it's its own tool chain. We have an 01:59.520 --> 02:05.200 assembler, we have a disassembler, we have a linker, we have a validator, which we then use to 02:05.200 --> 02:09.280 interpret the WebAssembly. So we actually have our own, like, in-house interpreter, which is 02:09.360 --> 02:14.160 really useful for testing purposes. You know, for internal testing, we both have our own interpreter, 02:14.160 --> 02:19.120 and then we also use Node.js as kind of like an oracle of correctness for things. But having 02:19.120 --> 02:23.520 our own interpreter and tool chain gives us a lot of freedom to do as we please with WebAssembly. 02:24.560 --> 02:30.480 And so, like, my experience has been both a user of WebAssembly, but also an implementer of it. 02:31.200 --> 02:36.480 An occasional joiner of hybrid meetings of the WebAssembly community group, but I don't- I don't get it 02:36.480 --> 02:44.240 in there as much as I'd like to. So real quick, who knows what WebAssembly is? Okay, who's actively 02:44.240 --> 02:49.600 like used a project, like worked with WebAssembly directly? Okay, much smaller numbers. So I'll 02:49.600 --> 02:56.160 just do a really quick overview of WebAssembly and move on. So WebAssembly is a portable stack-based 02:56.160 --> 03:03.600 virtual machine. I guess another show of hands, who's ever heard of ASM.js? Okay, a lot of people, 03:03.600 --> 03:08.640 but smaller than the people that heard of WebAssembly. So WebAssembly is like the successor to ASM.js. 03:08.640 --> 03:13.680 That was a project started up in Missouri to basically use a subset of JavaScript that can be 03:13.680 --> 03:19.440 compiled efficiently. And then out of that, became, like, well, why don't we actually have a good 03:19.440 --> 03:27.600 compilation target? That's not JavaScript, and thus WebAssembly was born. So despite WebAssembly, 03:27.760 --> 03:33.760 it's kind of not Web and not assembly. It's like an intermediate representation for a virtual 03:33.760 --> 03:39.920 machine. It's not native, you know, native assembly language. And also, there's run times for the 03:39.920 --> 03:45.040 browser, but there's many, many other run times, both JavaScript-based ones like in Node.js, like 03:45.040 --> 03:51.040 that's using V8, but also many other native run times, such as WasmTime is a big one. And it's 03:51.040 --> 03:56.080 WebAssembly is getting adoption in many non-web contexts, including things like IoT. 03:57.040 --> 04:02.720 So it's developed to the WasmTime community group with W3C, and it's a very approachable 04:02.720 --> 04:07.280 specification. I highly encourage people if you're interested in this at all, take a look at the 04:07.280 --> 04:12.560 WebAssembly spec. You do not have to be an expert to get started into, like, actually work with 04:12.560 --> 04:17.200 this with this technology. It's one of the most approachable web standards I've ever encountered. 04:17.920 --> 04:25.120 You can do a lot with a little effort. So real quick. So we just, the previous side was what is 04:25.120 --> 04:31.520 Wasm. And now, what is WasmTime? This is the WebAssembly text format, WAT, and it looks like a weird 04:31.520 --> 04:36.720 list. It has all the parentheses. It's got the prefix notation. And what you see here is a, 04:36.720 --> 04:41.120 this is an entire WebAssembly module. It's very simple. It has a single exported function named 04:41.120 --> 04:47.280 factorial. And what the code you see in there is just an iterative factorial algorithm. And 04:48.000 --> 04:51.680 things you might, if you're familiar with looking at assembly languages, there's some things that 04:51.760 --> 04:56.000 stand out. There's structured control flow. There's things like loops. You see if blocks, 04:56.000 --> 05:02.640 there's a lot of nesting. So it's not your average assembly language, but it's quite neat. 05:02.640 --> 05:09.680 And if you like this, but you'll very much enjoy working with it, I think. So WebAssembly has a lot of 05:09.680 --> 05:13.840 interesting security properties. Most notably, that it's a capability security system. 05:15.200 --> 05:17.920 And I just realized that throughout my timer, well, let's start it now. 05:18.880 --> 05:24.800 So WebAssembly modules are essentially little secure sandboxes. They have no ambient authority. 05:24.800 --> 05:30.080 They have no means to reach out into the world and say they can HTTP request or read a file or anything 05:30.080 --> 05:36.480 like that. The only, all it can do in terms of talking to the outside world, the things that are 05:36.480 --> 05:47.520 passed into it from the host or who's instantiating the module. So capabilities must be granted 05:47.520 --> 05:54.000 by the host in the form of import. So WebAssembly modules can leave little holes of import, say, a function. 05:54.000 --> 05:58.560 And the module will specify what the signature of that function must be and it's imported name. 05:58.560 --> 06:04.560 And it's up to the instantiator to pass that in. So we'll look at that a little bit more in a bit. 06:04.560 --> 06:10.000 But it allows practical implementation or practical use of the principle of these authority. You can 06:10.000 --> 06:15.360 make a module and you can give it just enough authority to do it. It needs to do it and no more. 06:15.360 --> 06:18.720 If it doesn't need to make an HTTP request, you don't have to give it that ability. 06:19.760 --> 06:24.880 Which means you can tend to run code you don't even trust in a secure way, at least in theory. 06:26.160 --> 06:30.000 And then finally, you know, those are, I've been talking about imports. That's kind of compile time 06:30.560 --> 06:36.640 or instantiation time capabilities. Through WebAssembly, we also get sharing of reference references, 06:36.640 --> 06:41.120 heat-allocated references. And so those themselves are a form of object capabilities. So 06:41.200 --> 06:45.920 very interesting security properties. Just a quick, like, bit of history. 06:45.920 --> 06:49.760 It wasn't one point out that the initial specification, I like to say it's for crabs. 06:49.760 --> 06:54.080 It's for the the rust, the C++, these like static, ahead of time compiled languages. 06:55.680 --> 06:59.920 And particularly languages that use linear memory, they're dealing with like pointers into, you know, 06:59.920 --> 07:04.320 offset into memory. Which meant the wasn't one point. It was really good for like offloading some 07:04.320 --> 07:09.360 number crunching from JavaScript to another language so it could be more efficient. And then kind of doing 07:09.440 --> 07:15.120 your high level stuff in JavaScript. And this is, you know, like, rust uses the LLVM 07:15.120 --> 07:21.360 in tripped into a chain for this a lot of things. That's was a 1.0. You know, some managed memory 07:21.360 --> 07:26.320 languages, languages like, want to have a garbage collector. They used was a 1.0. I think Haskell 07:26.320 --> 07:31.360 is one that did it. There are others. But it has a lot of downsides to doing that. So the big one 07:31.360 --> 07:36.000 being that the binaries are just massive. You're just shipping a lot of code to the user. It's not 07:36.080 --> 07:40.880 bandwidth efficient at all. And the reason being mostly is that you have to ship a garbage collector 07:40.880 --> 07:46.080 in your binary. It's not another great situation. And it's not only the bandwidth cost. It's also 07:46.080 --> 07:51.680 that WebAssembly is not, it doesn't have the ability to do all the things that a native assembly language 07:51.680 --> 07:55.920 can do. Like you don't have threads, for example. And on the web you don't have true threads anyway. 07:55.920 --> 08:00.240 There's other, you know, workers and things like that. So what you ship is not a very good garbage 08:00.240 --> 08:04.720 collector. You ship a really bad garbage collector that way slow space. And then it has its own 08:04.720 --> 08:09.840 separate heap. So if you want to interoperate with with heap values from JavaScript, you're going 08:09.840 --> 08:16.960 to have a bad time. So that's kind of the motivating factor for what was published in WebAssembly 08:16.960 --> 08:20.720 through point out, which is why I was in for the rest of us. It's for those of us that want to use 08:22.720 --> 08:27.520 a dynamic programming languages. So I use scheme, but there's many others that I'll mention a few 08:27.680 --> 08:34.080 later. So last and 3.0 added a hierarchy. This type hierarchy graph you see here of GC managed 08:34.080 --> 08:38.160 reference types. The most important one being the one all the way to the left that kind of has 08:38.160 --> 08:44.240 that diamond shape. It adds things like composite types like heap allocated structs and arrays. 08:44.880 --> 08:50.800 It also has this interesting i31 type, which is a 31-bit integer, which anyone that does language 08:50.800 --> 08:55.840 implementation knows you can use to implement immediate values, things that you don't actually 08:55.840 --> 09:01.120 have to allocate on the heap. They fit in a word, so you can just put them in there efficiently. 09:01.120 --> 09:04.400 So all those things are there. It's really great. And then the other one I want to call your 09:04.400 --> 09:13.040 attention to is all the way on the other side. My left, your right, I guess, is the external type. 09:13.600 --> 09:18.640 That's the way you could say get a JavaScript value, say a dom node or something, and hold on to 09:18.640 --> 09:23.920 that reference in your WebAssembly program and then say pass it back to do some manipulation of a user 09:23.920 --> 09:30.560 interface, for example. So wasn't 3.0, all this stuff with all these new types. The type system 09:30.560 --> 09:37.360 is called iso recursive. Type groups can have recursive references to other types in the group. 09:37.360 --> 09:42.560 They form, you know, so a collection of types form a group, and the canonicalize, which means 09:42.560 --> 09:47.760 different WebAssembly modules that have type groups that are the same shape. At one time are considered 09:47.760 --> 09:53.120 equivalent types. So you can have modules that interoperate by having the same exact type group 09:53.120 --> 09:57.280 definitions. And so a reference of one, understood in one module can be passed over and then 09:57.280 --> 10:03.200 understood and destructured by another module. So it's a way to have interoperability amongst modules. 10:03.200 --> 10:11.440 So with this dynamic language implementation becomes feasible. But why isn't you see is pretty 10:11.440 --> 10:16.880 misunderstood? I tend to read, why isn't this course online and not comment so much because I just 10:16.880 --> 10:20.480 find it pretty frustrating. It feels like it's doomed to repeat the same old things about 10:21.120 --> 10:25.440 GCA. I just feel like there's a lot of misinformation out there about it. So I'd like to bust a few 10:25.440 --> 10:31.440 myths real quick. The biggest one being that Ryzen Gc is below. Why would you put things relevant 10:31.440 --> 10:35.440 to garbage collection in something that's supposed to be in assembly language? That doesn't make any 10:35.440 --> 10:41.680 sense. That's the argument anyway. But as I said before, not having this means we have binaries 10:41.680 --> 10:48.080 that are just massive and inferior to what you could get when your web browser has a world-class 10:48.160 --> 10:55.120 garbage collector sitting right there. And so not only is it not bloated, it makes things 10:55.120 --> 11:01.760 it actually unblope things. The reference types and the garbage collection instructions combined 11:01.760 --> 11:07.120 really only add about 30 or so instructions to the instruction set. And that's nothing compared to 11:07.120 --> 11:11.520 say what the Cindy instructions added and stuff like that. It's a very small set of instructions. 11:12.240 --> 11:16.720 We get smaller binaries and we get faster ones because we actually get to use the good garbage 11:16.720 --> 11:22.640 collectors that are in Chrome and Firefox and it's firing everything. And so just as a personal anecdote 11:22.640 --> 11:28.480 my I work, I say we're a nonprofit, which means we work with not a lot of money. And my small team 11:28.480 --> 11:34.240 was able to port a language to Asmgc on our small budget. And not only that we were able to implement 11:34.240 --> 11:40.400 Asmgc in our own interpreter. So this is not something that needs a team of 10 engineers over 11:40.400 --> 11:46.320 three years to do. You can do this with few resources. So consider that myth busted. I'm just going 11:47.120 --> 11:52.720 to say it. Another big one is that WebAssembly has no DOM access. And that's technically correct, 11:52.720 --> 11:57.920 the best kind of correct. And that's because WebAssembly has no IO access at all. As I said before, 11:57.920 --> 12:04.000 a module has no means to reach the outside world unless the host at instantiation time passes 12:04.000 --> 12:09.920 in some imported functions to do so. And so all IO access is granted and mediated by the host 12:09.920 --> 12:17.440 on the web that's JavaScript. So you can access the web, the DOM API, you just have to import it. 12:18.240 --> 12:23.360 And so just as proof, I won't show you the code right now. But this presentation is a WebAssembly 12:23.360 --> 12:29.040 program that's reaching out to construct these DOM nodes that you see that render these slides. 12:29.040 --> 12:33.600 So it's very much possible. I do this stuff all the time. You can do it today. And I think maybe 12:33.600 --> 12:37.760 what some of the detractors are really getting at is that there's no you do have to call into 12:37.760 --> 12:44.320 JavaScript from WebAssembly. And that's a cheap but not free cost. And so if there's any truth 12:44.320 --> 12:52.880 to this at all, it's that a fast path might be nice. But what is a webAssembly specific interface 12:52.880 --> 12:58.720 to the DOM look like? I certainly don't know. I think that's a hard not to crack. But maybe it 12:58.720 --> 13:02.960 will be at some point. There's other, they're called JS built-ins proposals that have been coming 13:02.960 --> 13:07.600 out. I could foresee some kind of optimization in the future for that. So anyway, I consider this 13:08.240 --> 13:14.160 mostly a myth with a negative trip. And then the final one is, you know, why don't you see it 13:14.160 --> 13:17.520 just for JavaScript haters? It's for people who just don't want to use JavaScript and they're being 13:17.520 --> 13:22.160 really stubborn. And they think that they could just use this. And completely replace JavaScript. And 13:22.160 --> 13:27.200 I'm not a hater, I swear. But I do like to use a non JavaScript by-ing fidget. And it's pretty nice 13:27.200 --> 13:32.800 that I can do so on the client-side web now. JavaScript does have good parts. And my Snarky's 13:32.800 --> 13:39.840 list comment is that the parts that it inherits from scheme mostly. And, you know, ES6 and beyond, 13:39.840 --> 13:45.760 the JavaScript is a pretty good language. Now, it's really not so bad. So it's not a matter of 13:45.760 --> 13:50.640 being a hater or anything like that. But even besides my own personal preferences, there's a clear 13:50.640 --> 13:55.120 desire to use non JavaScript languages on the web anyway. Just as a few example, people want 13:55.120 --> 14:00.080 gradual typing, static typing, and when you use textcript, maybe folks want to use closure 14:00.080 --> 14:04.480 because they use the JVM and they also want to have ship some of that code over to the client. 14:04.480 --> 14:08.800 You got closure script, which compiles JavaScript. You have JSX, which is you're still doing JavaScript, 14:08.800 --> 14:13.200 but then you're also embedding your HTML and stuff in it. And then there's a tool chain to 14:13.200 --> 14:19.200 build all that out. There is a compilation pass. So no matter, most people have some kind of 14:19.200 --> 14:23.200 tool chain involved generating their JavaScript. Even when you get to minification or whatever, 14:23.200 --> 14:27.840 it's like using JavaScript, you're working with some kind of thing that looks like a compiler. 14:28.160 --> 14:36.480 And so JavaScript is not intended to be a compilation target to begin with. And in doing so, 14:36.480 --> 14:40.160 when you compile to JavaScript, you're making a lot of compromises usually, especially if your 14:40.160 --> 14:45.920 source language is not JavaScript plus some extra stuff. TypeScript is JavaScript, but with 14:45.920 --> 14:50.320 the type system. If you want to compile a completely different language, JavaScript, you always 14:50.320 --> 14:56.000 have some compromises. And with WebAssembly, you have fewer. So why isn't you see as JavaScript 14:56.080 --> 15:00.880 replacement? It's more feasible than the common sections we'll need to leave. I think our 15:00.880 --> 15:06.240 project is proof that it can work. I like to say the dream of the 90s is alive because before 15:06.240 --> 15:12.160 JavaScript, JavaScript was the original vision to ship a net escape was a scheme that then became 15:12.160 --> 15:18.000 JavaScript. So it's been 30 years, but looks, schemes and the browser now finally. That's pretty cool. 15:19.200 --> 15:25.040 A hundred percent illumination of JavaScript is not possible because you do need to have some 15:25.120 --> 15:28.640 JavaScript as what boots your WebAssembly modules, what instantiates it. You need a little bit of 15:28.640 --> 15:33.680 JavaScript code, a bit minimum, to handle, to handle, you know, booting that part of the app. 15:34.400 --> 15:37.680 But it's also not really the point. It's not to completely get away from it. It's just to have, 15:37.680 --> 15:43.280 you know, to bring your preferred language into a chain there. So some other languages, 15:43.280 --> 15:48.000 why isn't you see a lot of JVM languages do it? Java, Kotlin, Scala, and then also some, 15:48.000 --> 15:52.000 if you're like a functional programming nerd, like I am, get a little camel there too. It's pretty 15:52.320 --> 15:59.600 great. And there are others, that's just a few. So let's see. There's next section. I just want to 15:59.600 --> 16:07.280 make some high-level comparisons to Blazon versus other things. So, you know, when you compile the 16:07.280 --> 16:11.840 JavaScript, there's some advantages of WebAssembly, and that it's easier to faithfully implement language features. 16:12.560 --> 16:16.880 You actually have a good set of, you know, basic numeric types, just as a simple example, 16:16.880 --> 16:21.120 you know, you actually have instant floats in WebAssembly rather than just having the number type 16:21.200 --> 16:28.080 in JavaScript, which is essentially, you know, a double. You know, if you have a language that's 16:28.080 --> 16:33.280 based a lot around recursive calls, which scheme is in some other functional programming languages, 16:33.840 --> 16:38.480 you have tail calls in WebAssembly, which you don't have in JavaScript. Some JavaScript languages 16:38.480 --> 16:44.400 have a tail call optimization thing built into them, but it's not a specified semantic of JavaScript. 16:44.400 --> 16:50.400 So you can't rely on it as a compiler builder. But you have it in Wazom. So it's easier to bring 16:50.560 --> 16:54.800 another language to Wazom than it is than a JavaScript. They have some similarities. 16:54.800 --> 16:58.320 Both have structured control flow, which means you don't have a go-to that you can use, 16:59.360 --> 17:02.880 which means, in either case, you're probably going to want to use something like the beyond 17:02.880 --> 17:07.600 re-luper algorithm. If you're into your immediate representation that you're compiling to 17:07.600 --> 17:12.240 JavaScript or WebAssembly, uses unstructured control flow, you need to do a pass to convert it to 17:12.240 --> 17:16.080 structured control flow so that you can emit your JavaScript or WebAssembly. So they're similar. 17:16.720 --> 17:25.040 In that regard, as much as I wish this weren't true, it's unlikely to be compiling JS on 17:25.040 --> 17:30.160 file size. I don't have solid numbers to give you on this, but the WebAssembly binary is 17:30.160 --> 17:36.320 tend to be bigger than you want, at least right now. It's much a lower level thing. So it's a 17:36.320 --> 17:40.880 compact binary format, but you need to do a lot of instructions to do things because it's lower level. 17:40.880 --> 17:46.080 So you just tend to still have your shipping more bytes over to your client, and that may 17:46.080 --> 17:48.880 be acceptable, or it might be too much depending on the devices you're targeting. 17:50.000 --> 17:55.840 And then there's WebAPI overhead. Crossing the Wwise and JS boundary is free, as I mentioned earlier, 17:56.560 --> 18:00.560 and you basically need something that resembles a foreign function interface to do it, 18:01.280 --> 18:07.440 and WebAssembly functions are statically types, and there's no like you don't have variable length 18:07.520 --> 18:13.360 argument lists. So a lot of JavaScript methods do operate on those. So you have to kind of 18:13.360 --> 18:18.080 figure out how you want to make your interface to various like JavaScript methods that way. 18:18.080 --> 18:23.120 So there's some translation you have to do. And finally debugging, 18:23.120 --> 18:28.640 WebAssembly really isn't great right now. Sorry to say. The developer tools are just 18:28.640 --> 18:32.320 immature compared to JavaScript. You know, JavaScript had a big headstart, and some of the 18:32.320 --> 18:36.400 JavaScript tools don't apply to WebAssembly. I find that like I like to use Firefox for 18:36.400 --> 18:39.760 a moment, but I often just, I try to look at the disassembly of a binary and Firefox, 18:39.760 --> 18:47.680 it usually just says loading. Nothing ever happens. I don't know. Chrome supports like dwarf, 18:47.680 --> 18:51.760 like a debugging format, but as far as I know other browsers don't, I haven't actually 18:51.760 --> 18:56.800 gotten around to having our tool chain admit dwarf, but whatever. But there's been some 18:56.800 --> 19:01.440 progress on like getting external debuggers linked into editors to kind of work around this, 19:01.440 --> 19:05.360 but I would like to see the dev tools and the browser get better. So JavaScript is a clear win 19:05.520 --> 19:10.400 there. So what if you don't use any language that compiles JavaScript, but if you just 19:10.400 --> 19:14.240 use plain old JavaScript, as I said, JavaScript is quite good these days, so I don't really 19:14.240 --> 19:19.040 see a reason to necessarily want to use WebAssembly for happy with JavaScript. It's hard to beat, 19:19.040 --> 19:23.520 you know, just guessing billion dollars of investment or whatever in the JavaScript ecosystem, 19:23.520 --> 19:27.440 excellent compilers and stuff like that, like WebAssembly's just turned 10 years old. 19:27.440 --> 19:33.680 It's got some catching up to do for those things. And, you know, JavaScript is a relatively 19:33.760 --> 19:38.800 small language, but schemes even smaller. And even with a language of small scheme, 19:38.800 --> 19:42.560 I still need to ship that runtime into the browser. And there's things like schemes, 19:42.560 --> 19:46.880 numeric tower, like rich set of numeric types. It's port IO interface and things like that. 19:46.880 --> 19:51.920 I've got a ship. And that's not free that cost bandwidth, you know, use JavaScript. All that stuff's 19:51.920 --> 19:57.280 already there on the client. The cost can be reduced by exporting, you're like your binary interface 19:57.280 --> 20:02.080 from one module and then importing it from all your other ones. So you can kind of pay the cost once, 20:02.480 --> 20:06.800 and then have everything share that. So that can reduce, but they can't eliminate, 20:07.600 --> 20:15.440 having to ship that runtime over. So, why doesn't the chance to issue NPM, get rid of NPM? 20:15.440 --> 20:21.600 I like JavaScript. I really don't like NPM. I'm not a JavaScript creator, but I am an NPM 20:21.600 --> 20:26.720 hater. Too many high profile security issues for my liking. I've never been happy with the 20:26.720 --> 20:30.880 massive dependency graphs of these like little micro dependencies. And I really don't like 20:30.880 --> 20:35.920 that it's hard, like nearly impossible to say package a self-hostible open source web app 20:35.920 --> 20:43.200 in a Linux distro, because the NPM dependency trees too big to hittle. So I like having a tool 20:43.200 --> 20:49.920 chain that doesn't even use it. Let's see. So, Web Assembly, it's got some room to grow. I think 20:49.920 --> 20:54.880 it's really nice. It's 10 years old, but it's still early days compared to JavaScript. There's just 20:54.880 --> 20:58.320 better tooling around JavaScript, the Web Assembly tooling is still trying to catch up. 20:59.280 --> 21:06.160 It's found. It's places that it's used. Big companies like Figma use it, and they do all sorts 21:06.160 --> 21:11.280 of interesting things. You have people compiling post-grace SQL to Web Assembly or SQL that 21:12.000 --> 21:16.880 this is really cool stuff, but it's niche has not been JavaScript for replacement, 21:16.880 --> 21:22.240 traditionally. Even though we have spread the use it that way, it's not the dominant use case for 21:22.240 --> 21:26.240 Web Assembly. So, I'd say it's not like a slam dunk yet. You've got your favorite language, 21:26.240 --> 21:31.040 you know, just compile it to Web Assembly and you're good to go. I will whatever be that, I'm not sure. 21:31.760 --> 21:36.000 I would like it to be, but all things considered, I'm more or less happy with Web Assembly, 21:36.000 --> 21:42.160 although I want to see some things improve. If you want to read more about this particular 21:42.160 --> 21:47.840 thing, like what are people using Web Assembly for my colleague and lead engineer on Hoot, 21:49.040 --> 21:54.800 Andy Wingo from Agalia. He wrote this article for ACMQ recently, Web Assembly, yes, but for what? 21:55.040 --> 22:01.120 Take a look, really good stuff now. I'm going to end with just looking at some what I think are 22:01.120 --> 22:06.320 promising proposals that are coming in the future of Web Assembly. So, I'm going to cover three 22:06.320 --> 22:12.320 really quick, stackswitching, multi-biter A access, and reference text strings. Stackswitching, 22:12.320 --> 22:17.280 there's no way to capture stack frames, and Wasm right now as specified, which means you can't 22:17.280 --> 22:22.480 really implement, as like a language implementer, you can't implement your own non-local control flow, 22:22.480 --> 22:27.200 if your language has co-retains, generators, unlimited continuations, can't use them. Easily. 22:28.240 --> 22:34.240 We do this in who our Gile uses delimited continuations for a lot of things. If you don't have them, 22:34.240 --> 22:39.440 you really don't have Gile, so we needed them. And so our workaround was to use an explicit stack, 22:39.440 --> 22:45.040 where we actually have Web Assembly tables and stuff that are holding our stack frames, and so that 22:45.040 --> 22:49.760 way we can capture continuations from them. One, it requires a really tricky compiler pass that 22:49.760 --> 22:55.680 took compiler genius Andy Wingo to write that I have a trouble working with when there's bugs in it. 22:56.560 --> 23:00.560 And it adds significant runtime overhead, because we're not using the Web, the Wasm stack, 23:00.560 --> 23:05.920 you're like reading and writing into Wasm tables and things like that. So, things could probably 23:05.920 --> 23:12.320 be like many times faster than they are now, if once we get stackswitching. So, stackswitching adds 23:12.320 --> 23:17.920 a continuation, heat type, and some instructions work with continuations. Multi-biter A access. 23:18.640 --> 23:22.800 If you're using Wasm linear memory, it's usually just like a single instruction to like get 23:24.000 --> 23:30.320 a float, a 32-bit float out of a chunk of memory. Not so if you use heat-balocated arrays. So, 23:31.120 --> 23:39.680 we like to use I8 arrays, like a bite arrays in Wasm Gc. But this code up top is how you get a 32-bit 23:40.240 --> 23:45.920 float out of it. You read four bytes, and you bitch if them in order them together, and then reinterpret 23:45.920 --> 23:51.680 them as a float. It's very inefficient, but there's a proposal to change it to just this 23:51.680 --> 23:57.040 F32.load instruction, which is the same instruction for using linear memory, except you specify 23:57.040 --> 24:01.520 that you want to load it from a heap array. So, that's going to make number crunching with 24:01.520 --> 24:08.400 heat-balocated arrays much faster. Finally, reference type strings. This one's a bit sad. 24:09.680 --> 24:14.560 There's really strings on WebAssembly or not as easy as they ought to be. You kind of have two 24:14.640 --> 24:21.040 main choices. You can work with UTF8 internally in your WebAssembly module, and then copy 24:21.040 --> 24:26.240 them to JavaScript strings at the boundary when you need to. That's what we do presently in 24:26.240 --> 24:30.720 hoot. It's not great, because every time you make an FFI call to JavaScript, you're in a string, 24:30.720 --> 24:35.600 you copy it, and so you're going to run your garbage collector more than you would like to. 24:36.240 --> 24:39.280 Your other option is to use something like the JS string built-ins proposals, 24:40.160 --> 24:46.640 proposal, sorry, which fundamentally works in 16-bit code units, and so you kind of have to 24:46.640 --> 24:52.960 accept the mistakes of the 90s and UTF16, and rather not do it. There's a proposal called string 24:52.960 --> 24:58.000 graph. It adds a string, reference type, and it has instructions to view strings as either 24:59.200 --> 25:05.520 WTF8 or WTF16, which are basically UTF8 and UTF16 with some other details to handle some 25:05.520 --> 25:10.960 of the crazy Unicode stuff, and it's not JS specific. You have one string type, and you can run it 25:10.960 --> 25:16.080 on any Wasm runtime, whether it's in the browser, like a JavaScript host or something else. 25:16.080 --> 25:21.200 Unfortunately, it's stuck at phase one. The Wasm CG community as a whole does not. 25:21.200 --> 25:26.960 Like it, but in hoot, we love it to the point where even though string graph has not been adopted, 25:26.960 --> 25:31.760 our compiler emits string graph, because it's such a useful set of instructions to use as like 25:32.720 --> 25:36.560 an intermediate representation that we emit Wasm in that way, and then we take a pass over it 25:36.560 --> 25:41.120 to strip out all the string graph and replace it with a bunch of stuff using byte arrays, 25:41.920 --> 25:47.280 and then copying when we have to go to JavaScript. My final wish is I haven't seen a proposal yet 25:47.280 --> 25:52.800 for this, but I want to do WebGPU on Wasm with heap allocated arrays. We need a way to view a Wasm 25:52.800 --> 25:58.000 array as a JavaScript type array. We don't have that yet, someone make the proposal, please, if you're 25:58.000 --> 26:03.520 viewing this or here. Yeah, anyway, in conclusion, do you want to meet Wasm in tool chain, 26:03.520 --> 26:08.080 or do you want to be scheme on the browser, try hoot? I think it's pretty great, and I'm very 26:08.080 --> 26:14.160 embarrassed about that. So thank you. Again, I'm a non-profit, I work on non-profit. We need money. 26:14.960 --> 26:16.800 Do you like our work? Please donate. Thank you. 26:21.760 --> 26:24.320 We have to type on default one question. Just one question? 26:24.960 --> 26:32.960 Okay, yeah. Well, Kristina can't be you. I'll be out in the hallway if you want to ask further questions. 26:35.040 --> 26:40.160 Kristina's the only asker, didn't she? Wow. No one else can. This is a completely 26:41.440 --> 26:51.520 non-astery terms question. So the, I guess, so hoot has this wonderful web assembly tool kit, 26:51.520 --> 26:56.880 it's not just for compiling schemes. Correct. G, if, if I have all these features, 26:56.880 --> 27:02.000 is there any reason if I wanted to develop a programming language that compiled to web assembly 27:02.000 --> 27:07.360 today, or operated on web assembly in any other way, that I would choose to use hoot as opposed 27:07.360 --> 27:12.240 to any of the other tool kit set exist, is there any advantage of doing so? Yeah, well, I think 27:12.240 --> 27:16.800 if you're a dynamic programming language minded, you will like that tool chain over the LLVM 27:16.800 --> 27:20.880 and script into a chain. If you like living programs rather than static ones, I think that's a 27:20.880 --> 27:25.200 good base, but also our tool chain has some interesting things. Like having the interpreter means 27:25.200 --> 27:31.840 that we can do things like, you know, have something built in. So with scheme, you have like a, 27:31.840 --> 27:35.200 you often develop from the repule. You have this redevelopment loop, giving you feedback. 27:35.920 --> 27:40.240 Well, you can run a Wazon binary from your repule, and then if there's an error, like a web 27:40.240 --> 27:45.120 assembly error, well, I can drop you into a web assembly debugger in your repule where you can then 27:45.200 --> 27:51.840 inspect function locals step through it, vowel like single web assembly instructions as you attempt 27:51.840 --> 27:58.480 to debug. So I think if you're, if you're at all list curious or dynamic language interested, 27:58.480 --> 28:03.040 it's a good, it's a good place to start. I think the OCaml folks also have their own tool chain, 28:03.040 --> 28:08.640 but I'm the one on stage. So you should use hoots. It's really good. Yeah. Thank you. 28:08.640 --> 28:10.640 Thanks.