Brian Kardell: Okay. Hi, I am Brian Kardell. I'm a developer advocate at Igalia.
Eric Meyer: And I'm Eric Meyer, also a developer advocate at Igalia. Welcome to this week's Igalia Chats. We have with us a special guest, Andy. Please introduce yourself, and let us know a little bit about what you do.
Andy Wingo: Oh, hi. Well, my name is Andy Wingo and I am a compiler engineer. I'm just into programming languages. I work for Igalia for the last 15 years or so. I'm excited to talk about Wasm today or Wasm, whichever one you all-
Eric Meyer: So the WebAssembly, W-A-S-M-
Andy Wingo: Yeah.
Eric Meyer: ... it's Wasm?
Andy Wingo: I'd say Wasm, it's not an acronym, it's just a shortened version of the name. And hence if you capitalize it, we know you're not a real one. So capital W, but all the other ones are lowercase.
Eric Meyer: Oh, okay.
Brian Kardell: That's interesting. That's like-
Andy Wingo: Drop the knowledge in the beginning.
Eric Meyer: Can I make a guess that the W-A-S-M is supposed to look like an assembly instruction? Is that-
Andy Wingo: I've never thought about that before.
Eric Meyer: Okay.
Andy Wingo: But I think it's supposed to remind you of assembly, yes.
Eric Meyer: Okay. For listeners who may have heard about WebAssembly but don't really know what it is, what's the deal? What is WebAssembly?
Andy Wingo: I would take maybe a historical... There are a number of ways to come at this, but one of them is to come at it from time.
Eric Meyer: Yeah. Well, we love history on this podcast, so go for it.
Brian Kardell: We love it. Yeah.
Andy Wingo: About 10 years ago or so, a little bit more than 10 years ago even, people were trying to squeak out the best in performance in JavaScript. And if you remember, I think that was on the tail end of some of the real performance wars of... And V8 came out in, what was that, 2007 or '08 or something. And then as the compiler architecture started to get more and more optimized, you start to look more towards getting native-level performance out of JavaScript and people are running against a bit of a wall for some applications. JavaScript wasn't very predictable. It can go extraordinarily fast. But if you just give it a lot of code, it's a bit of a crapshoot as to what actually ends up going fast. It doesn't give predictable performance, and so people were looking to find some predictable performance out of JavaScript. So people, they reduced a subset of JavaScript that could be statically typed and it was amenable to being emitted from LVM essentially, which is a weird thing to do to JavaScript. People probably remember this, it's called A-S-M.J-S, Asm.js, And it was using-
Brian Kardell: This came from Mozilla Labs, right?
Andy Wingo: Exactly, like so many good things.
Brian Kardell: Yeah, right. There were really a lot of great things that came out of that.
Andy Wingo: And then I think as people who work on compilers and language runtimes, this was a very neat hack, Asm.js. One of the common demos back then was Brendan Eich would go on at all the conferences showing off Unreal-based games compiled to Asm.js. There would be sort of these 3D shoot-em-ups all running on the CPU, but using WebGPU from the DOM. So already, from the very beginning, the idea of compiling things from C++ to the web and then using the web platform was a pretty important use case.
Brian Kardell: If I remember correctly, wasn't Asm actually just JavaScript, but it had sort of comment-oriented annotations in it? If your compiler understood Asm, it could do fast things with it. Or is that a complete misremembering of what it was?
Andy Wingo: No, that is an accurate memory. For Firefox, it would shift Firefox into a mode where it would eagerly compile the function that contains the 'use asm' declaration at the top, which was just a string, the literal string at the very beginning, kind of like 'use strict' or Google's attempt at 'use strong' and a number of these proposals. But the semantics of what was compiled is exactly JavaScript. So it really was JavaScript, but just a subset that could be compiled well.
Brian Kardell: But was there type hints on it too or something like that?
Andy Wingo: No. Now, there were inline patterns of JavaScript use, which exactly constrain the values to have the semantics of low-level instructions. For example, if a value is zero then that says it's an n=32.
Brian Kardell: Right, that's what I was thinking of. Yeah. I remember Dave Herman showing me some of this stuff I thought was interesting.
Andy Wingo: Like prefixing things with plus to make a-
Brian Kardell: Mm-hmm. Yeah.
Andy Wingo: ... number often floating point.
Brian Kardell: Yeah.
Andy Wingo: , disgusting to anyone-
Eric Meyer: Oh, the best kind of hack.
Andy Wingo: ... with a sense of aesthetics.
Eric Meyer: Yeah.
Andy Wingo: Programming language people, we have a sense of aesthetics. Whether it's good or not, I don't know. But it's very strong, and this is not a common aesthetic which is appreciated in this community. That's actually I think why WebAssembly arose. It was the implementers of the various JavaScript engines saying, 'This is a really weird way to get what you want. Why don't we design something that does exactly what Asm.js does, but more fit for purpose and maybe reusable in other contexts?' That was 10 years ago. There have been a number of extensions since then. And recently, some more interesting qualitative changes in WebAssembly and in its use domains. One context for this talk is ACM Queue, the industry-focused publication from ACM. Just published an issue on WebAssembly with a few different authors, myself among them. My article took a look back. If you just go to queue.acm.org, you'll find these ones right now.
Eric Meyer: Is that Q-U-E-U-E.acm.org?
Andy Wingo: Yes, right. Try them of, Q and then U, E, U, E.
Eric Meyer: U, E, U, E.
Brian Kardell: We'll link the article. You're talking about WebAssembly? Yes. But for what, right?
Andy Wingo: Yeah.
Brian Kardell: That was a great post actually. I think that there are probably a lot of people who write JavaScript and they know something about Wasm, and they were kind of intimidated to dig into it or whatever, but it's very accessible. I think the title even is great because I think a lot of people have exactly that question like, 'Sure. Yeah, we like it. But for what? Is it actually being used? Is it making a difference?' And you answered a lot of those questions.
Andy Wingo: Yeah. It's a funny question because... I love WebAssembly. Like many programming language people, I feel there a strong affinity towards it. But the web part has mixed success.
Brian Kardell: How so?
Andy Wingo: Well, in the sense that if you go to WordPress or Reddit or CNN, or whatever page you go to on the internet, I don't think there's any WebAssembly. It's not replacing anything on the web to a first and very large approximation. So it's like, 'What are we doing guys? Is it actually a thing on the web?', and it is to an extent. In the article, I take a look at where things have succeeded, where things have failed a bit on the web, and it's mixed, I would say, in a web context. We have things like SQLite for example. Did you know there's Web SQL? Probably you all have worked with this at some point.
Brian Kardell: Mm-hmm. Yeah.
Eric Meyer: Yeah.
Andy Wingo: My understanding is this is just completely gone from... This is offered SQL to SQL to JavaScript developers in the browser, and this is no longer a thing. It used to be shipped as part of Chrome for example. Now, what people do is they just ship SQlite, S-Q-Lite, to compile the WebAssembly, and it's faster and it works great. In some areas, it is finding some success, but it seems to be limited to some of these add-on components which themselves are compiled from languages like C and Rust. But people who are writing JavaScript right now are also writing WebAssembly.
Eric Meyer: Okay. So you say languages that are targeting WebAssembly, Rust, I assume, from a thing that you just said. But others?
Andy Wingo: Yeah, there are a number... The thing is that the first version of WebAssembly, what it gives you is the ability for... It's a compiler target, first of all. It's not something that's designed to be written by yourself. You should be writing in a source language, and that source language's tool change should produce WebAssembly. The facilities that WebAssembly has are instructions that operate on a byte array, and this is kind of Turing tape level stuff. And notably, you can provide functions. This code that you generate is broken up into functions and those can be exported to JavaScript if you're in a web environment, and you can import functions from JavaScript, for example, DOM functions, into the WebAssembly environment. That's one of the interesting things about WebAssembly is that it doesn't have anything that it can do on its own. You have to provide all of these capabilities to it in the form of imports, which is also a very attractive property as a programming language person. But the way that the set of primitives that it has, meaning this byte array and imports from the host, means that it's really appropriate to languages whose toolchains already target byte arrays, meaning C, C++, Rust, and that's about it. GO, to an extent... I mean, but Go has a garbage collector.
Brian Kardell: I think that's an important distinction if you could go into that a little bit, because I don't know that everybody is sort of a language engine nerd. What does having a garbage collector have to do with-
Eric Meyer: Right.
Andy Wingo: Yeah, let me give that a go. In a programming language, you have control flow and you have values. And in somewhat languages, those values, for example, a JavaScript object in the context of JavaScript, when you create it, you don't know how long it's going to be around. There's nothing that guarantees that it's going to not outlive the current function call. There's nothing that guarantees that it will only be used by one caller at a time. When you mutate a value on it, there's no guarantee that somebody else doesn't have a value. Values exist in this kind of soup, and it's not clear when it is that a given value is not needed anymore. To determine that, you have to trace all of the links between all the data structures in your whole program, and then any object which is not traversed on that trace then becomes reclaimable. That's garbage collection. Right? But that's not the only way that you can build a language. You can build a language such that, by default, the values you create, a structure containing a string and a name and a handle on some sort of resource, it has a sort of statically delimited lifetime. So you create it in this function call, and there's something about the programming language that proves that that value will be unneeded after the function call is finished. And in a language like that, like Rust for example, even like C and C++ when they're used conventionally, you can use a different strategy for representing values. You can, for example, use a stack in that. As your control flow goes deeper into a function, you can allocate values in linear memory. And then when the control flow returns, you just have to reset the stack pointer and everything is freed and available for the next call. You don't have to do garbage collection. So WebAssembly with this linear memory was appropriate for languages like C and C++ and Rust. But for language that needed garbage collection, that needed the engine to determine when a value is live or not, like JavaScript itself, WebAssembly was missing this facility, which it just got last year, a year before actually. As programming language nerds, we're super excited about this. It's almost like a new chapter of, 'What's going to happen with WebAssembly?' Are languages like C# and Dart/Flutter... I wrote a scheme compiler also to WebAssembly with GC, garbage collection, last year. Are these languages going to have success now that they're possible?
Eric Meyer: What does it take to write a compiler like that? I'm just curious.
Andy Wingo: For me, the challenge of targeting the web is binary size. Right?
Eric Meyer: Mm-hmm.
Andy Wingo: You can do many things. But if you want to make a good user experience, you need for that delivered artifact to be less than a megabyte and hopefully less. You need to be able to produce tiny binaries. And for that, you need a compiler that's able to do a lot of tree shaking in the same way that JavaScript, the toolchains, their bundlers, can remove excess code. You need a compiler that's really oriented towards not including things that you don't need. Types help to an extent. If you can prove that this addition is not going to C strings, for example, if your addition operator can work on strings, then you can emit less code. You can make things smaller. But also, the structure of your language's standard library is such that the toolchain can know when something is not in use and can produce a small binary. I have found in my work that you need to spend some special effort on the web to get this.
Eric Meyer: Huh.
Andy Wingo: There's a faster strategy, which is you take the Canonical-Python implementation, for example, which is written in C. You just compile that C implementation of Python to WebAssembly using the standard C-to-WebAssembly toolchains. And then you use that to interpret Python inside. It's compiling an interpreter instead of compiling a program directly. The result is a bigger binary that runs slower, but it does give you Python on the web. And I think that's valuable, but it's not going to replace JavaScript.
Eric Meyer: Right. So in that case, you basically people are creating the ability to run Python natively, maybe air quotes or the air quotes appropriate here, in the browser. So that rather than writing JavaScript, that's equivalent to whatever Python you want. If you know Python much better and you have this Python-Wasm thing, then you can just run that and then throw Python at the browser and the Wasm does stuff with it.
Andy Wingo: That's right. There are some ways you can improve on that. This is going to go a bit nerdy. But if you take an interpreter and you specialize it against a program to be interpreted, that is a compiler. Right?
Eric Meyer: Oh.
Andy Wingo: So if you take a Python interpreter and you specialize it against a particular Python program, then you can get an optimized WebAssembly program for that Python program. There are limits, but people do this. There's interesting work called Weval, W-E-V-A-L, out from Chris Fallin a year and a half ago or so. There's a lot of interesting work on this. You can also get an implementation of an interpreter to produce WebAssembly code just in time. Me and my colleague, Dmitry Bezhetskov, did this for SpiderMonkey about a year ago or so. So instead of emitting x86 or ARM code, we would get SpiderMonkey's macro assembler back in to emit WebAssembly, which would then be linked into the process and you would have somewhat optimized JavaScript on top of JavaScript, because you had the SpiderMonkey imitation compile the WebAssembly, which could then run on top of SpiderMonkey itself.
Eric Meyer: Wow. We do a lot with ones and zeros, don't we?
Brian Kardell: I live in Pittsburgh and a number of years ago, we used to run this event here and it was to explain web standards and to engage developers. There are a few web-oriented people in Pittsburgh, like Brad Frost is here, Val Head is here, I'm here. At least at the time, Lin Clark was here and Lynn Clark was working on this. If you remember Lin Clark, I haven't seen her in a while, she did the web comics for this. We'll link them up. Are they still accurate? I assume that they are. But that's probably the last time I got very into something about Wasm. There's a question that is persistent in my head that I would like to see if maybe you can help me understand and answer, from that era, which is basically... It's a bit like it's something that runs in a worker in that you can't have access to any of the stuff that makes browser stuff happen. You don't get access to the DOM, you can't access local storage or indexedDB. Or can you do those things now?
Andy Wingo: The answer is nuanced. On the basic level, you could always access DOM functionality by importing functions from the DOM. You don't have them directly, but when you call out to your host, when WebAssembly calls out to one of these imported functions, then the host can access indexedDB. So when you write your WebAssembly program in Rust, or whatever, you would import indexedDB bindings. And then when you instantiate that module, on the client side, you would provide it links to the indexedDB functionality so it could link out there.
Brian Kardell: How does it do that in practice? Is that like a userland thing? It's a thing provided by the browsers or-
Andy Wingo: The low-level mechanism is pretty simple actually. A WebAssembly module have some set of imports. This is static, it's an attribute of the module. Let's say it has 20 imports. Each of those imports can be a function or it can be value or it can be... there are a couple of other internal things. But mostly, you want functions. Right? Each of those functions has a type, and the module itself declares, 'This import number 19, I'm going to import it from a module called...' N is a common name that the compiler toolchains produce, 'And then inside of that module I'm going to import the function indexedDB new.' There's no semantics associated with this. And this function has a type, it has two arguments. It's going to return this value. There's no semantics associated with the import in and of itself. But the toolchains, when they produce WebAssembly, Emscripten, it will also produce a bit of JavaScript on the side that wraps that module and you use that JavaScript to instantiate the module. And when you call that JavaScript, that JavaScript is going to fetch the indexedDB functions and the WebGL functions, and all the ones that your module needs, and pass it as imports 1, 2, 3, 4, 5, and 6-
Brian Kardell: Oh, interesting.
Andy Wingo: .. into your module. So inside the module, 'It needs something from WebGL. I know that my WebGL function is slot six on my imports. I'm going to call this function with the right number of arguments. Control will be passed directly to JavaScript.' It's a very low-cost boundary. The engineering there, on the part of the browser makers, is very good. So if you're calling out to DOM facilities from WebAssembly, the actual fact of calling out is cheap and is often inlined.
Brian Kardell: Nice.
Andy Wingo: There's a line running through your program between the WebAssembly side and the JavaScript side, but the runtime makes it as cheap as possible. And that's a general characteristic of WebAssembly is that it's good at making lines through systems and lines through programs, where one side is one thing and the other is the other, but the cost from going from one side to the other is relatively low. Okay. All that said, I have to provide a little bit more detail though because values going across this boundary aren't just integers, because WebAssembly's fundamental data types are integers, floating point numbers. That's it, right? So you have a string, what do you do? It's horrible. The WebAssembly module, when it wants a string, has to pass an offset into the linear array of bytes. And then the imported function on the JavaScript side has to write those bytes into that typed array, corresponding to the value of the string. You don't get to pass a string by reference, you copy its value out. And then to get the value back into JavaScript land, or whatever the host language is, you have to copy the string back out from the bytes to the array. And that's the case for any composite value. If you have just an opaque resource, like an indexedDB database or something, those can remain opaque and they don't have to be copied. They effectively sit in a side table and they have a reference account associated with them. But for anything is more complicated, getting data in and out of WebAssembly is a bunch of copying. Until this facility recently, to allow WebAssembly to make values whose lifetime is managed automatically by the garbage collector. That allows JavaScript values to flow into WebAssembly to be stored in local variables passed as function parameters, and exist in WebAssembly without being copied out. Now, things aren't as nice and fluid as they could be because the standards body wants WebAssembly to be appropriate not just for the browser. If it were made just for the browser, I think things would be more tightly coupled between WebAssembly and JavaScript, but that's not how it's. But the GC facility gives a possibility of having less value copying and making that line a bit lower costs.
Eric Meyer: I don't know. I feel a little lost sometimes. It's like there's all these things that are talking to each other and I'm like, 'How does it even all work?' But once you get down into the weeds and make sure all the weeds are lined up correctly, then you get what you want. But you mentioned about the standards body, what standards body is working on this?
Andy Wingo: It's the W3C, to cut it short.
Eric Meyer: Okay.
Brian Kardell: That's strange a little bit to me. I would have thought it would be ECMA, but it winds up being W3C.
Andy Wingo: I can't say why. I actually don't know why that is. I think it was maybe related to royalty-free membership.
Eric Meyer: Okay.
Andy Wingo: But that's worth diving into a little bit more. In practice, there is a working group which formally ratifies standards, and there is a community group that does all of the work. The community group is relatively open, kind of a rough consensus-based model with phases as in JavaScript land. Then once you reach phase 4, then you are blessed and incorporated into the standard. It's a multi-stakeholder process, and there are two sociological sub-communities there. There's the browser manufacturers, people who are focused on WebAssembly in the browser, and then there are the people who are focused on WebAssembly elsewhere, which is largely these days a server side thing.
Brian Kardell: Yeah. I like your article about this. I am pleased you're going to talk about this because some of that was fascinating to me.
Andy Wingo: In the browser, I think we can measure a bit of WebAssembly's success. It's been around long enough, it's filled a space, but it's not growing and stampeding over everything. But on the server side, I think we can't quite do that yet because people haven't been running it on the server-side long enough. But it's still expanding and it's interesting. So there, the idea is there's a system user split on the cloud. You have the cloud operators that run the system, and then you have everybody like us who upload our programs to a virtual machine, or what have you. We are the users, and there needs to be a dividing line in between those. A long time ago, obviously, we had managed machines and we went to virtual machines and containers, and now function as a service. And WebAssembly is another step in this line of making the unit of computation smaller and cheaper, and increasing tenancy on these services by having very small instances.
Brian Kardell: Just in case people don't know, tenancy is like-
Andy Wingo: Yeah. It's that multiple people share physical resources. And obviously, if you are running a cloud infrastructure, the more the merrier for your bottom line.
Brian Kardell: Just offering that as we're throwing around a lot of terminology in this episode. And I feel like the more we throw out without getting some kind of definition, the more lost people will feel. So just in case-
Andy Wingo: For robustness, it would be nice if you could completely spin up a fresh virtual machine, for example, for every web connection you make to google.com. You spin up your virtual machine, you get your search results, and that virtual machine gets torn down. It doesn't work that way because it's too expensive to start a virtual machine, both in the amount of memory it ultimately consumes, but also in the time it takes to do so. You have a couple of milliseconds in which to do this. And especially, edge deployments. Let's say you have... This is not in a main data center, for example, but like Cloudflare or Fastly or one of these services, Akamai, that have data centers all around the world, very close to where people are. Let's say you have a Black Friday sale or something, to take a capitalist example, and you have a load transient, a lot of interest in something. They're going to be starting up a lot of instances everywhere. But this could actually lead to overloading the entire system as the latency of each little virtual machine effectively starting up. Everybody's doing the same thing and so everybody's waiting the 100 milliseconds, all of your queues completely fill up and the whole system falls down. With WebAssembly, you can start a virtual machine, I put this in air quotes here, in between 100 microseconds or 2 milliseconds or something very small. So the idea is that you can scale up and scale down very quickly. These are very simple units of computation. And the low cost line between the kernel space and user space, again in quotes, that is established by WebAssembly, allows it to produce systems that scale horizontally a bit better. On the server side space, there is a kind of... Everybody's heard of Kubernetes. Whether or not it's positively or negatively, it's just out there everywhere. We're still in the kind of growing a Kubernetes moment for WebAssembly. There are a number of companies that have offerings out there in this space of providing scalable virtualization based on WebAssembly units of compute. There's still space to go, I think, to fill the niche. So there's still a bit of runway in this area.
Brian Kardell: Yeah. That's amazing to me when I read that, that you're measuring startup time in microseconds. You can imagine that being a really big deal for edge computing especially. Yeah, it makes sense. I had a question about usage and getting at some of the, 'What is being adopted? Why isn't being adopted?' I really thought that maybe the access to DOM and things like that would be one reason, but it turns out that that's not a reason. I wonder if people just don't know that. One of the things that we've seen with standards a lot... Eric and I both have done stuff with the HP Archive and the Web Almanac. Just about every year, we study a lot what people are adopting, what they're not adopting. We do these surveys with the WebDX group and we do this interop project where people ask for things, and then we also help boost lots of other developer advocates saying, 'Hey, what can we give for you?' It turns out that a lot of people want things that turns out we already have, and they just don't know it yet. When you look at the adoption curve for a lot of things, not everything but a lot of things, it really takes a long time for you to see it in the data. Unless, for example, like Wix or WordPress, or one of these core systems that's used by maybe a quarter of the internet or something like that were to adopt it, then you see it ripple through. And then the interesting thing there is how to interpret that because it's not that people individually made choices to choose Wasm, it's that Wasm was chosen by the invisible hand of capitalism. They bought a product and that product used it. And that might be the good part or it might be the bad part of the project, but we don't really know. But when we look at that data, that data has a lot of biases. And I'm curious, like you said, we know on the web, how are you getting that data that we know about adoption on the web? Is it from HP Archive and Chrome status and stuff or-
Andy Wingo: I don't have a good... My data is annotated. I don't have the data, disregard.
Brian Kardell: Yeah, okay. This would be interesting to look at, if you're interested. I would be interested in looking. But I expect that it would be low because the biases of the HP Archive are toward homepages. Even on the Chrome status, it's sometimes difficult to get things where you're behind a login or a firewall or something. So I expect that on a lot of things that you might use that for, like gaming. I think that's actually one of the reasons that took off in the first place. You can correct me if I'm wrong. But I think that there was people saying, 'We need this for gaming,' and some of the first uses were Unity and stuff like that-
Andy Wingo: Well, a couple of thoughts on that. I think for gaming, it was a really interesting technology demo. It surprised a lot of people 12, 14 years ago when there were those demos using an Unreal Engine. But it hasn't worked out. I suspect it's not simply a technological issue. I think it's more economics of AAA game production, how do you ship them, and maybe Steam is better somehow. But Wasm has not been a big success in games. Some people do games in Wasm. I'm not saying... And they're great now, all of them.
Eric Meyer: I actually did-
Andy Wingo: Yeah.
Eric Meyer: ... strangely enough.
Andy Wingo: Yeah.
Eric Meyer: It's the only Wasm that I think I have ever produced.
Andy Wingo: Oh, wonderful.
Eric Meyer: A couple of years ago, I was messing around with Godot, the game development engine. I made a lunar lander clone because it's a simple project to do, and it had compile for web and I was like, 'Okay.' It produced 20 megabytes of Wasm, which then ran in the browser, and I could play lunar lander, my terrible copy of it, in the browser. But given that AAA games that are not in Wasm are 500 megabytes or sometimes gigabytes, depending on what they're doing, I can't imagine that what Wasm is going to make that somehow smaller.
Andy Wingo: Yeah. I'm happy to hear that your toolchain experience was good though with Godot-
Eric Meyer: Godot made it easy, basically.
Andy Wingo: That's great.
Eric Meyer: I don't remember the exact command, but it was basically publish... Because Godot has publish for Mac, publish for Windows, publish for Linux, and then there was publisher for web, whatever the phraseology is. So yeah, it spat out a big Wasm blob.
Andy Wingo: Well, Unreal, the current version, I don't remember if I said this, it doesn't even include this publish-to-web thing anymore. That's a data point. But, I don't want to be negative on Wasm because I love it, Wasm has had some success besides games. Google Sheets is a pretty funny one, I think. The Google G Suite apps, the Docs and Sheets and all these things, they're very large industrial artifacts. They're single producer, even if multi-team, inside artifacts. One of the parts of Google Sheets used to be compiled from Java, of all languages, to JavaScript and it is now compiled to WebAssembly using the new garbage collection integration. So the ability to pass values by reference back and forth between the different parts. And that, I think, has been deemed a success. I think to really evaluate it, we would need to look at it for another three years and see if it stuck. But it rolled out and deployed.
Brian Kardell: Yeah.
Eric Meyer: Doesn't Adobe have a bunch of Wasm stuff too?
Andy Wingo: Yeah, also. And that is another case of a legacy application compiled to the web. So they effectively compiled Photoshop, for example, to the web. Had to do a bunch of investments on the toolchain, but they got it working. I understand that it's really not a web port of Photoshop. And even if it integrates with web facilities, it really is the Photoshop application compiled for the web target. Whereas if you were going to make Photoshop from the web from scratch, as if making Photoshop from scratch is a thing, you would make it in a completely different way. The only reason it's targeting WebAssembly is because there is this large legacy code base written in C++. So if you have one of these things that you need to get on the web, then WebAssembly is an absolute win. There's just a limited number of such things. When I think about the web and WebAssembly, there is this narrative that we have, publicly, among WebAssembly partisans, which is that WebAssembly is a complement to the web. And that's true to an extent with SQLite, for example. Whereas I think in our hearts of hearts, that WebAssembly is in competition with JavaScript. Somebody who loves WebAssembly does not want to write their web page in JavaScript. I think it shows in the sense that somebody who loves JavaScript is not going to go and write a little part of their web page in WebAssembly. To an extent, there is a desire to replace the messiness of the web platform as it is with something clean room, like WebAssembly, and I think it's an aesthetic exercise that falls flat.
Brian Kardell: This is kind of a perfect segue to a question that I've wanted to ask for a while too, which is I think when you take a really large JavaScript application and you send it down, one of the larger things is parsing. Because you parse it and it builds a kind of internal bytecode and stuff, because it's a virtual machine. A really long time ago, I was Java developer. But it had bytecode and you would send this. It's not text that you interpret, it's this kind of in-between thing. A lot of people proposed for a long time like, 'Hey, why don't we just have where you can compile your JavaScript to bytecode and you send your bytecode down?' It seems a little bit to me like that's what Wasm is. And I'm wondering, do you gain performance boosts from it? Also, I literally don't know the answer to this question, has anybody worked to the toolchain so that it could sort of work that way? I expect probably not since some of the things you were saying are new, but-
Andy Wingo: Yeah.
Brian Kardell: ... And I would like to, like I was able to with Java, not debug bytecode, but debug my JavaScript code.
Andy Wingo: Well, I think it makes sense to deliver WebAssembly and write TypeScript. Right?
Brian Kardell: Okay.
Andy Wingo: But the full dynamicity of JavaScript is best served by the JavaScript implementations as they are. So first of all, on the parsing side, text and bytecode are similar in size and parsing the text is not. It's not actually a blocker. The JavaScript parsers in the implementations are very, very fast. And they can operate off the main thread and they can scan for function boundaries, so they don't actually have to build up an AST maybe even initially at all. It's been a year since I've gone deep into the JS side of things, but a bytecode for JS was never a win from a startup perspective. WebAssembly does have some facilities that can lead to low latency, but it's also very low level. And that means that to get a given task done in WebAssembly, it will require more instructions than JavaScript. It would be nice to be able to have a good compiler from JavaScript to WebAssembly. The current ones are... A lot of people use QuickJS, which is an interpreter. Some people use SpiderMonkey, which is also run in interpretation mode with some specialization. The binaries are still a little bit large, I find. There's not a really good compiler for TypeScript yet to WebAssembly with GC that I know of, but that is actually an open space. The other question is, 'Do you want to do this to your system?' WebAssembly, what it does, it draws a line down your program where you have the two sides, your host and your guest. Often, these correspond to something approaching kernel space and user space, and it's great when you need that line. If you're a cloud provider, you provide the OS and the user provides the function that runs in the OS. If you're a browser vendor, you provide the browser implementation. The user provides the JavaScript that goes on top. If you provide a website, you don't need a line down the middle of it. So if you divide your website into JavaScript and WebAssembly parts, you're going to have to divide your team into a JavaScript team and a WebAssembly team. And this technical boundary, it's a reverse Conway's law sort of thing, is going to put a lot of organizational friction such that the cost to communicate across this boundary is going to replicate itself in the number of people they're going to have to deal with these problems. For me, the winning deployments are either all WebAssembly, like Flutter, for example, Flutter compiled to WasmGC, or all JavaScript, or JavaScript with one of these very reusable modules like SQLite or something like that. Looking at a web deployment scenario, I don't see a good plan for implementing Facebook and WebAssembly, for example. It just doesn't make sense.
Brian Kardell: Yeah. So in that framing, it's hard to imagine it overtaking JavaScript or really catching up to JavaScript because a lot of things that you need to do are webby by nature. Flutter also has additional interesting challenges and things because I think it doesn't really provide you with the same native things. Like games, they like it. They want to recreate all their own controls and everything, but then that's tricky. That's why we had things like QT and that's why we have toolkits, because it's really difficult to build a good UI that is accessible and all that kind of stuff-
Andy Wingo: But maybe they could with more investment. I could see it maybe being a thing.
Brian Kardell: Sure.
Andy Wingo: But yeah, I agree it's a tricky proposition.
Brian Kardell: I think the things that attract it is maybe the problem. The things that attract it, like Flutter and things like that, they genuinely want to build their own stuff. So it's a little bit hostile to building the common thing. Not hostile, it's not conducive to encouraging a common thing, I guess.
Andy Wingo: Yeah.
Brian Kardell: Yeah. It's a fascinating topic. I also am interested a little bit about... you mentioned SQLite. Does this mean that you're sending down a database engine when you want to use that one component? It's a small database engine, but you're sending down a database engine. And I guess, probably, that must back with something. Right? It must back with something local, like it's using indexedDB behind the scenes or something-
Andy Wingo: No, I don't remember the details for how it keeps its local state. But yes, it does seem silly to send a database from the server to the client.
Brian Kardell: Yeah. Well, this is a common tension that I'm a little bit curious actually for you, because you do like some of these things and you probably have a lot more insight into some of them than me. But from my engineering career, it's always been this tension between... You can build a nice app with Electron, and then you know exactly what you're sending. But it means that you don't get the free security updates that come with the browser. It means that, 'We have 380 copies of Chrome on our desktop.' Every app is their own copy of Chrome, and each one maybe has their own security problems. I don't know. It's a tricky balance-
Andy Wingo: To be fair, JavaScript is like that. Right?
Brian Kardell: I was going to say, I was going to draw an analogy to, 'There are a billion copies of jQuery in my cache.' It just didn't make any sense when we were really fighting for every bit of cache storage that we could get on these really finite devices. And I know there were a lot of efforts, still are, to how we can avoid that like, 'Is there a secure way to do that?' Even the things that we had, like loading them off a CDN so that they shared a cache, they don't anymore because they multi-hash the caches-
Andy Wingo: Well, let me take this in a slightly different direction, which is off the browser and more towards the page that you receive. When you go to Amazon, for example, you can't cache that result, because there's your name up there in the corner and there's your recommendations here or there. The page which gets shipped to you over the wire is not really compatible with the HTTP 1.1 caching architecture, and it's all over HTTPS and everything else. But a lot of the page is the same. You have a number of blocks that aren't going to change every minute. At least, you can cache that. So that's one thing that WebAssembly is being used for now is taking parts of a page, like amazon.com, I understand that that was one of the ones recently, and stitching them together on the edge with customer specific information. So you take a block of this and a block of that and a block of that and some customer information, do some logic and produce the HTML and JavaScript that's shipped over the pipeline to the user. In that way, you minimize the total latency of the operation because the data center connections are very good. You also allow those core servers, that produce the page, to focus on what they're doing and then scale the part that's very dumb. It's just the stitching together the parts of a page. So maybe to an extent, I know it's only tangentially related to having 17,000 copies of jQuery around, it's a form of prayer or something that WebAssembly allows us to decrease the total number of bytes being sent from core data centers and allows things to scale in a cheaper way. It's not a counter argument. But maybe more intelligent caching can be made of data plus a bit of logic, and WebAssembly could be a cheap form of logic.
Brian Kardell: Yeah. There have been a lot of approaches to this. Mark Nottingham, when he was with I believe Akamai, and he is... Mark Nottingham, if you don't know, was the chair of the HTTP Working Group. He had a proposal, that I can't think of the name of it, but it kind of never took off. But it was a standard way to do this at the edge, that you could stitch things together. I still think that's a pretty good idea. I also built something like that at my last employer and, yeah, it's a very good idea. I don't know if you have followed our last chat-
Andy Wingo: I read the transcript, but I wouldn't be able to listen to it.
Brian Kardell: A number of people have suggested, 'Hey, can we just transpile XSLT? There are modern XSLT engines, can we just transpile them?' And I'm curious, is there anything preventing us from doing that?
Andy Wingo: We can. We can do many, many things. I know you're wondering, when you load an XML document, you kind of have a DOM representation and it would make sense to be able to just move around parts from that DOM implementation using XSLT. I think with WebAssembly it really wouldn't work like that, unless the particular XSLT implementation is designed for the XML being stored in a kind of DOM and a third-party resource that manipulate it by handle. I think the way it would probably work would be more textual, 'XML in, XML out,' or whatever out on the back end-
Brian Kardell: Right. But as a string, so like HTML, for example.
Andy Wingo: Yeah, exactly.
Brian Kardell: Yeah. So you have kind of multiple parses happening there? Less efficient at runtime probably-
Andy Wingo: It probably doesn't matter though for all the use cases that people are looking at it for and... I don't know. I don't know why people would do that instead of using a different programming language, because XSLT 1.0 is not a great programming language.
Brian Kardell: Yeah. They want to compile a more recent, like XSLT 3. But that means also updating, again, the dependencies and everything. So XSLT requires XPath, the browser's XPath engine is also not up to snuff, so you need to compile that as a modern one. And then, 'Oh, it also works on JSON,' so you have to figure out how to take the JavaScript engine's JSON parser as a reference? Or again, it's string in, string out? It just feels Doable, but more as a... I don't know. Maybe it's kind of a beautiful Rube Goldberg machine?
Andy Wingo: Sticking on the WebAssembly side and without my programming language edge on, yes, it is totally possible. And there is an interesting thing... WebAssembly is a boundary. It doesn't have to be implemented by interpretation or compilation. One of the ways that you can use WebAssembly, which is a way that Firefox does... I can't remember which library. I think it's actually libxml that they do something called RLBox, which takes the libxml source code, which is written in C, and surely has memory vulnerabilities for example. They use a standard toolchain to compile it to WebAssembly, and then compile that WebAssembly back to C. And what you get is an artifact that has no undefined behavior and which by construction cannot alias memory from the rest of Firefox and cannot invalidate any of the invariants in its host, which is Firefox, besides what Firefox provides to it in the form of import functions. So it provides a useful security boundary inside Firefox between two pieces of C code, ultimately. In this case, this is C code, which is produced from compilation from WebAssembly to C. So in a place where you need a boundary, WebAssembly I think is a very, very interesting technology to take a look at. I was talking with a colleague just yesterday, he was saying, 'I would like to have some mobile code. There are all these co-processors and embedded devices that run Zephyr these days. And sometimes these co-processors are just doing nothing, but they're taking power. Maybe they're plugged in, they don't need to save battery. How do I get mobile code?' I'm like, 'WebAssembly. WebAssembly is the way to do this. It provides you this cheap boundary between the trusted runner of programs and the untrusted program that does interesting things.' I think it's a good general strategy. For browser, obviously, this would mean shipping more code and more facilities, to ship the XSLT as either compiled back to C or interpreted or what have you. That's a decision from a browser maker if that's worth it or not. And I am very sympathetic to the desire to remove things.
Brian Kardell: Is there anything that we didn't cover about Wasm that we should cover, that you would like to cover?
Andy Wingo: Well, I think my big pitch with Wasm is that, 'Is this drawing a line in your program?' And that it's a pattern that we can recognize in a number of deployments, on the web to a degree, where you have a line between SQLite and the rest of your JavaScript application, on the cloud where you have the cloud provider and then the function that is being run on the cloud. But wherever you find this kind of line is an interesting potential development niche for WebAssembly. So I think people should be writing kernel drivers in WebAssembly. This is not quite a thing yet, but it could be. Operating systems can be built using WebAssembly as the boundary, and this is kind of back to the Destroy All Software with Gary... What's his name? Bernhardt? When Asm.js was a huge thing, he gave a talk, which is a history of computing. And then ended up with Asm.js, like JavaScript being the future of computing, because it will be the boundary between kernel space and user space using Asm.js as the abstraction layer between them. Anywhere you find this line, it's a potential deployment area. And in the article, I had a fun time, I predicted that, in AI context, when you have agents doing things, doing logic on your behalf, on your data, this is another line. And then a month later, Microsoft comes out with Wasm agents operating on your data within a security sandbox. So I think we have room in a non-web context. And then on the web, I'm interested in looking towards the future of this new GC facility, the garbage collection facility, and see where it goes.
Eric Meyer: All right. Well, this has all been really interesting, and especially for me who has been afraid of assembly ever since I failed the course in college. My failing really was that we had lab partners, and I was partnered with the one student in the class who probably should have been teaching it. So they just turned in their assignments the day that they were issued, and I went off to do other things. Anyway, Andy, thank you so much for joining us and giving us some enlightenment on Wasm.
Andy Wingo: It was a real pleasure. Thank you for having me on-