 and we'll just get it going. There we go. Can you all see my screen? Perfect. Excellent. Okay. I want to make it just a little bit bigger because I knew a few people are watching at 360. Yeah. This is as big as it's going to get for the slides. It's 1080p. Welcome, let me talk. It's an introduction to WebAssembly. My name is Guy Royce. I'm a developer advocate at Redis Labs. The only really important thing, because we've got a small window here for the talk, so I'm going to go a little fast. The only important thing on the slide is my Twitter account. I'll announce other than the Redis logo, I suppose, but is the Twitter account there because if you want to follow what I'm talking about what I'm doing, or you want to make fun of me while I'm giving the talk, that is the place to do it. Go out to Twitter and give me a follow if you will be so kind. GitHub.com slash Guy Royce, there will be slides, all these slides and stuff are actually already out there. So you can check that out there as well. So what the heck is WebAssembly? That's probably the first question you would ask, right? What's WebAssembly? Well, in true SpongeBob fashion, I asked my computer wife, Karen. That'd be the SpongeBob Karen, not the internet Karen. And she told me that it was 50% web and 50% assembly, which is kind of funny, not really, but it's kind of a weak joke, but it's also kind of true, right? Because it is assembly language for the web browser. It's also kind of not true because it's moving beyond the web to command line tools and it's not actually assembly, it's bytecode. Assembly is a language that renders down the machine code or bytecode. And so it's both true and false at the same time. But more than anything, WebAssembly is a solution to a problem like any good technology, right? And that problem is JavaScript. What the hell JavaScript? I mean, look, I mean, okay. So before I sit here and disk JavaScript, I wanna say that I'm a fan of JavaScript. I run the Columbus JavaScript user group. I like JavaScript. I like it unironically, but it's got some really challenged corners, right? Look at some of these examples. Numberbot.minvalue is greater than zero. Wow. I wish that was true of my bank account, right? My favorite here is parse int fire truck. This is actually a very reasonable statement. Fire truck, it turns out, it's not a number. And so that's what it returns. If you say parse int fire truck comma 16, well, then that's 15, which is not a fire truck. What's going on here, of course, is that when you say comma 16 for parse int, you're saying, make this hex based. Make this, this is a hexadecimal number. So, you know, JavaScript dutifully goes and starts parsing the string fire truck, finds the digit F, which is 15, finds the digit I, which is not a number. And so it says, oh, I'll just stop here and 15's good. You might also be wondering why I chose the word fire truck here. And it's because my son, my oldest son who's 19 now, but at the time he was about six or seven. He tells me this joke. He says, dad, I'm thinking of a word and it starts with a letter F and it ends in U C K. And he's kind of smiling and he's like fire truck. So, so I thought that was a fun example, right? It's not, totally not a passive way of me explaining my frustration with JavaScript sometime. So, the nice thing about JavaScript though is if you don't like it, you can pick a different language as long as it's JavaScript. Now, I know there's things like TypeScript and there's TypeScript and you've got these tools that will transpile JavaScript, non-JavaScript languages into JavaScript. But that's not really picking another language because it's still JavaScript under the covers. In the previous talk, Mike was kind of talking about how we need to compile that JavaScript. He's right, compiling is what we want. We don't want to transpile it. I think the fact that we made up a word, made up the word transpile to describe what we're doing when we're converting ES6 JavaScript to something we'll run on Internet Explorer is a hint that we're doing something weird. But we can transpile it and use different languages. We're not stuck with JavaScript, although our errors often come back to us in JavaScript. But there's actually kind of another flaw with JavaScript. Aside from it's weird syntax, not weird syntax, but it's weird edge cases and the lack of linguistic diversity that you can have for front-end work. And that's fundamentally a scripting language. For JavaScript, we have to download the JavaScript file and we can minify that in that hell but they're still kind of big. We have to tokenize that. We got to find all the syntactical tokens in there. Then we got to take those tokens and parse them into an abstract syntax tree. And then once we have that, we can execute it. And we got to do that every time. Now there is caching that happens there and V8 does provide as much capabilities as it can but this is an expensive process and it just affects the performance of JavaScript and browsers. But what if there was some way that we could compile code to run in the browser? If we could compile code to run in the browser, we could pick whatever language we wanted and so we wouldn't be stuck with JavaScript. We could make it small and tight and compiled into some sort of byte code and so we wouldn't have this parsing problem, this performance issue. And that is what WebAssembly is. WebAssembly is code that has been compiled for the browser. And it's kind of cool. It's a virtual machine that runs in your browser, runs a WebAssembly byte code. So I thought it might be to really kind of make it crystal the idea behind what WebAssembly is, is we might want to talk a little bit about the run up that gets us to WebAssembly. How did we, you know, what does WebAssembly work? And so I'm gonna, how does WebAssembly do what it does? How does it fit into the bigger picture? And in order to do that, I'm gonna start all the way back at the beginning with microprocessors. So with microprocessors that we all know, you've got, you know, a series of bits, so ones and zeros, high voltage and low voltage that represent instructions that come in. And so an instructor might say to move this value from, you know, register X to register Y or put this value in a particular register. So we've got these instructions that come in. And early on, this is how you programmed computers. You just wrote machine code that represented these instructions. And very early on, this is flipping switches and hitting a button and hitting a button, very, very tedious. And to make that problem, make programming these microprocessors less painful, we came up with the idea of assembly language. So here I've got on the left, we've got, you know, just an arbitrary address and memory. We've got the binary representation, the bits that represent this short machine language instruction, a machine language for a 6502 microprocessor actually. This was the code for my first machine language work, the first code I ever wrote in machine language back in the 80s. We've got that, those same numbers translated hex. You can see hex is a little easier to work with but you still got A-000, what does that mean? But in assembly, you can write a little text document and use mnemonics, things that make it easy for humans to understand. So you can see the like L-D-Y for load Y and then 00 for the value zero. So load zero into the Y register. And then the assembler would go through this code and turn it into byte for byte, you know, this symbol means this hex code and this symbol means this hex code. So there's a one-to-one correlation from the assembly to the machine code. And that was a great innovation that made programming much easier but it did mean that you had to learn a different assembly language for every species of microprocessor. And it was also kind of hard to work with. And so we introduced higher level languages like C. This is, you know, some sample C code here. It does the same thing that assembly code does but it's in C. And with C, we can take that code and compile it as opposed to assembling it and we'll get a binary that's similar to the binary that we, you know, coded in assembly. And then we can run that on our 6502 microprocessor and life is grand. But there's a problem with this. I write it in C and I compile it for this processor but there's a lot of processors. And so I need to compile it for all the processors. And sometimes I can't take advantage of all the processors capabilities because I want to preserve backwards compatibility. I want to make sure my code will run on the most number of machines because I'm selling my software, right? And so we solve this problem the way that we solve all the problems in computer science, which is we added a layer of abstraction. We added a virtual microprocessor. And so instead of having a physical microprocessor we got a virtual microprocessor that has a byte code. It has an assembly language of its own. And we can compile to that byte code and then it will in turn interpret the code into something that the microprocessor can see. So here we've got, it's no longer C code, it's Java code and you can tell it's Java code because it's identical. Actually you can tell it's Java code because it's got that cafe babe at the very beginning of it. And then that Java code runs on the virtual machine and then the virtual machine hands off instructions to the microprocessor in an interpreted fashion. And these can get smarter and more sophisticated for performance and you can actually get faster performance out of these virtual machines than you can the physical ones because you can optimize, you can do just in time compilation and optimize it for exactly the specific hardware you have. So you can crank a lot of power out of these things. It's actually pretty cool. WebAssembly is exactly the same idea for the browser. So now we can take the C code or whatever language you want, compile it to byte code, to WebAssembly byte code and then create a file that all the major browsers can read and work with. So that's what WebAssembly is. It's this idea of a virtual microprocessor in the browser. Pretty cool, I think it's cool. So let's get into the nuts and bolts of WebAssembly and see how we can actually do this. And I'm going a little fast because I want to have time for my demo because I kind of want to show off that this stuff is real and you can actually use it today. A WebAssembly module is literally just a file. It's a .wasm file specifically. And I kind of think of them as like DLLs if you've got a Windows background at all, if you did any early Windows development because they're basically a bag of functions. And so here we've got, say a simple calculator module that has five functions for doing basic mathematics, for doing basic arithmetic. And so that's all a WebAssembly module is, is byte code in a file with a wasm extension. It's just a binary file but that exposes these functions. In the browser, it becomes just another file that you download. So on the left here, we have our site CSS or index.html and our app.js. And these are sort of the classic trifecta of front end web development, and get your wonderful site to CSS as this effort does display none. Got a really basic HTML. We got some an app.js. And then WebAssembly is just another file that the web browser can download. And we got some little code here that shows you how that works but I got better slides for that. The interesting part here is the arrows. So your app.js of course can interact with your DOM and manipulate it, right? That's the essence of web apps. But it can also interact with WebAssembly and WebAssembly can interact with it. So my JavaScript code on the front end becomes something that WebAssembly can talk to and it can talk to WebAssembly. Now you'll notice there's not an arrow connecting WebAssembly to the DOM right up here, right? Right up here. I'm pointing on the wrong screen. And that's true. WebAssembly cannot talk to the DOM yet. It's being worked on. It's a hard problem. But it can talk to JavaScript, which can talk to the DOM so you can write and go do code to solve that problem. But this is just sort of the ecosystem these modules live in. To use it from JavaScript, we've got a really simple bit of code here that includes a callback and everything. The key thing here is to create a WebAssembly module that you call fetch and then just the path to the file. And then you feed that fetch call into instantiate streaming and that will asynchronously retrieve your module. Once you have the module, you can just call methods on it. The module has an instance, the instance has exports, the exports are where all your functions are at. And you just call them and use them like you would any JavaScript function. It's actually really easy to use it once you have one. If you want to import some functions that WebAssembly can call back against, then you can create this little object structure up here that has all your callback functions in it and pass that in all when you instantiate the WebAssembly module. And so that provides functions that WebAssembly can then use to call back. The idea here is this, perhaps when we call add, subtract and multiply, it also calls a callback reporting the value in addition to returning it. So that's the idea here. And so that would allow us to like log out all our answers in addition to having code to it. It creates sort of an event model in a way. From the WebAssembly side of things, I'm gonna show you WebAssembly text format, which is the assembly language for WebAssembly. And WebAssembly text formats looks like this. It has a module. The module declares, everything starts with a module. It's the container for everything. If you want to declare some functions, you just declare them using the syntax here, funk dollar add. You give it a couple of parameters if you need them. You give it a return value if you need it. These are both 32-bit integers and it returns a 32-bit integer. And then you've got your implementation of that function. And then same thing for subtract and other functions. To export those functions, you just have to add an export statement and give it a string right here. Then, you know, it's an externally facing alias to the internal function. So you can affect have private functions in WebAssembly by not exporting them. To import, to access that math callback that I showed you on the JavaScript side, you just use this import syntax here and you just use those two keywords that were there in that object hierarchy and you just give it a name internal. So this is just mapping it internally. WebAssembly is stack-based. So it's a stack-based virtual machine. So what that means is that when you call a function, there are no intermediate variables. You just use the stack instead. So local.get$a means get the first parameter that was passed into this function and put it on the stack. $b means get the second one. So now we have two items on our stack, five and 10. When we call add, add will pop those two values off the stack because add wants two values. If they're not there, then it'll error. And then it will add them together and push the answer back onto the stack. Then when we're at the end of the function, well, then there's one item on the stack. That's the return value. So that's how these work. This is how a stack-based assembly language works. Here's a slightly fancier example that shows the callbacks in action. And this is interesting because you gotta be mindful of how the stack works here. So after we, I define a local variable up here, you can actually define locals. And then after we add them, I set that local. And then in order to return, in order to call the callback, I gotta put something on the stack for its arguments. So I get the local that I created. And then in order to have a return value, I gotta get that again. So I ended up having to get that local value a couple of times in order to return it and do the callback. So the stack's a little clunky and weird sometimes. However, you can use S expressions to clean up your code and it makes your WebAssembly text format look a little more lispy, shall we say. And so that's kind of fun too. It makes it actually a little more pleasant to program it. There are a lot of other stuff in the syntax here. You've got shared memory, which means it's a shared block of memory that JavaScript and WebAssembly can both see. You've got globals which are like shared memory, but they're just an individual value that JavaScript and WebAssembly can again both see. And you've got tables which are, again, JavaScript and WebAssembly can both see those, but tables are a way of doing like lists of functions so that you can dynamically bind functions in languages like for polymorphism and C++ and stuff like that. So this is a motherboard advanced stuff that I'm not gonna go into. If you want to program WebAssembly in something other than WebAssembly text format, which you might want to do, these are the two go-to languages that have the deepest support at C and C++ and Rust. And I think of the two, Rust actually has the better support. Rust out of the box, just install Rust and you have WebAssembly support, it just works. I mean, you have to do stuff, but there's nothing extra that you have to install other than a particular target. And there's a lot of others, go out to this link here at Awesome Wasm Languages. I was looking at it the other day and Cobal was even on the list of all things. So there's a lot of stuff happening in the WebAssembly space. Coming down the pike, I've just been showing stuff with numbers and there's a reason for that. And that's because WebAssembly doesn't know what a string is. And that's because what is a string, right? What does C mean when it says a string? What does Rust mean when it says a string? Is that UTF-8 encoded? Is that, what's the encoding on that? And so one of the things that are coming down the pike is interface types that allow you to create some common types that WebAssembly modules can export and that's like the browser would understand how to make use of. They're super bleeding edge. There's some polyfills that make them work. I was playing with them and then newer code says we've turned that off for the time being until the standard stabilizes. So it's super bleeding edge, but this will solve this problem. Threads are, I believe threads work in Firefox now. I haven't looked at them yet. But the thing I think is particularly interesting is WASI or WASI. This is the WebAssembly systems interface. And that allows you to do a file IO and network IO outside of the browser. So if you're doing something with a command line tool like with a WASM time, then you could use WASI. And I'm actually gonna demo that along with some other things here really quick. So excuse me, let me grab a drink here really quick. Okay, it's water, but it had root beer in it and now it tastes kind of root beer-like. So let's get on with the demo here. So I didn't want to do that, but that's okay. So I've got, I've created fizzbuzz in WebAssembly. And I've created it three different ways. I've created it for the browser. Once in WebAssembly text format, once in Rust and once I created a fizzbuzz that runs on the command line. The two that run on the browser, I'm using Jasmine because it's convenient, embeddable, sort of testing framework. I just had to drop some files in there. I didn't have to install anything. And it runs and hits, looks for the fizzbuzz.wazm and the Rust fizzbuzz.wazm and tests them both. And I have this up and running now. So if we bring this up and I hit refresh, you see that it does indeed run all the test pass. Now I want to prove that this is real, not vaporware. So I am going to actually compile something here. So here we have fizzbuzz.watt. And so this is the code that does fizzbuzz. It returns minus one for fizz, minus two for buzz and minus three for fizzbuzz. And so I'm not going to go over the code too much here, but I'm going to go and change the constants. So for fizzbuzz, I'm going to return 30, 20 and 10 instead. Negative versions of those. And then I'm going to compile it using WebAssembly binary toolkits. WebAssembly binary toolkits or Wabbit has a tool called Watt2wazm. So Wabbit has Watt2wazm, which is kind of funny. And then I pass it to my Watt file. So Watt2wazm fizzbuzz.watt and that will spit out a new Wazm file for me. And if we do a little LS here, you'll see that the timestamps change to 205, which is my local time. And if we do a hex dump on the fizzbuzz.wazm, you'll see that that is the entire file. It is 111 bytes. That is compact AF, isn't it? So I've changed this. It does different things. Let's see it fail. Whoops, wrong key combination. There we go. Now all of them failed. Well, not all of them, but almost all of them failed. And the rust one I didn't touch, so it didn't fail. And I can actually go out and pull these from the console here. So let's say let m for module equal a weight. And I got a little helper function that we wrote called loadWazm. And let's say loadWatt slash fizzbuzz.wazm. And then I've got a function m.fizzbuzz. It even auto detects it. And let's pass it like 15. It returns minus 30. Let's pass it 10. So that broken version is there. I can also go out and get the rust version, which I'm not gonna show the rust version, type in the rust version because the path's long and complicated. But you can see that it's actually doing things. The rust version here is a lot simpler because it's rust and it's a higher level language. And so I'm just doing a modulus and doing some matching and returning it here. But if I wanna build it, I can just do, I can do, I've got a cargoTomel setup for this. I can do cargoBuild slash slash target. And then I gotta say wasm32 unknownuncanone. And then I wanna do a releaseBuild because that will make it about 200 bytes. If I do a debugBuild, I'll get like one and a half megabytes because like everything from rust will be in there. So that creates the new file. If I do an LS target wasm32release, we can see that we have the fizzbuzz.wazm that is 258 bytes. If I do a hex dump, you can see that that is, yeah, I gotta get an actual file, don't I? You can see that it's very, very short. And that of course will run as well. The really cool thing is, I think is the fizzbuzzio.watt. And here I have written a fully string running everything using the sort of temporary version of WebAssembly interface types. So here we're importing something from wasm time from wasm unstable and a write. So we can write out the standard IO. And this is actually a lot of code that's defined strings and does the fizzbuzz calculation and writes new lines. And then in order to take numbers and turn them into strings, we had to, or take strings and turn numbers, turn them into strings. We had to do loops and all kinds of crazy stuff. And all this code is out in GitHub for you to explore. But the cool thing is, is that I can do wasm fizzbuzzio.watt and it just compiles it, it just works. And so here we see that all of that code is 609 bytes. And when you do wasm time, which is the command line tool, this code loops from one to 50 and computes fizzbuzz for everything. And if it's not a number, and then it just skips it. And so this is a little command line version of fizzbuzz. So kind of cool. It's real stuff. You can do real things with it. I think wasm time is kind of like Node.js to WebAssembly. That's sort of, I think a proper analogy for it. So yeah, that's pretty much what I got. Here's a good little list of resources here to check out WebAssembly or github.com slash WebAssemblies, that's the official stuff. Mozilla Developer Network has great documentation on using the WebAssembly JavaScript side stuff in the browser. The WebAssembly binary toolkit, Wabbit is here. Wasm times the command line tool you just saw me use. It's great. There's another thing similar to it called Wasmr, which even has a package manager called Wapm. Wazze, the Wazze specs are at wazze.dev. If you wanna build something big, Rust is probably the best language to choose at the moment. And of course, there's the link to awesome Wasm languages. Here's a link to the code and slides so you can hit that QR code and that will take you out to my github and you can go get all that stuff. And worth noting, I work for Redis Labs, so please go check out our stuff. We've got a Discord server and some community forums and if you wanna sign up for a free class at Redis University, we'd love to have you. And that's pretty much all I got. Thanks a lot for listening to my talk. Give me a follow and are there any questions or do we have time for questions? Thank you so much, Guy. That was very interesting stuff. And we've had some comments saying that you've convinced them to find some time to invest in the WebAssembly. I can see that now. I can actually see all the comments again. Perfect. If you have any questions, feel free to post them in here or in Slack. I will also monitor Slack. And I posted your Twitter just earlier so people can follow you there. And if you can just put in the link for your slides because I didn't have the chance to write it down. Yeah, the link, I'll put it on Twitter. I'll throw it in here too. I don't have it super handy, but... No worries. I'll throw it in here too. There's a question that just came in. What are the best WASM games? Well, there's one. I don't know if this is the best one, but it's kind of fun. A gentleman whose name I don't remember. Implemented the Game of Life, Conway's Game of Life, in WebAssembly text format. So in this kind of syntax here, to run in a browser. And so that was kind of impressive. I don't know if it was a fun game, but I was impressed that he had ridden it. But it is actually, I think it has some enormous potential for browser-based games because you just got to write some glue-click code from your WebAssembly to Canvas and then it can do all the heavy lifting. And it performs a lot better. I've seen benchmarks as low as 30% faster and as high as 20 times faster. So it's probably about twice as fast, maybe, split the difference. Yeah, you could definitely see a performance game. I'm pretty sure by using WebAssembly there. Which is totally faster. There's also, yeah. And that's also been the main topic during the whole day. Like it's all about a JavaScript footprint and how it takes up a lot of bandwidth and how can we reduce it and how can we find ways to reduce the bandwidth of our JavaScript applications. So I thought it was very interesting. I think it'd be interesting to see if Mike's previous talk was talking about compiling to vanilla.js and it's like, well, you could take that one step further. That would be really great. Yeah, exactly. Svelte to Wasm, right? And also I love all the acronyms in... Oh, they're fun to say. Wasm, Wavi, Wabbit. Watt to Wasm is part of Wabbit. Wabbit to Wabbit. Cool. Thank you so much.