Ben Crowder

Blog: #learning-in-public

6 posts :: tag feed :: about the blog :: archive

Learning WebAssembly, part 2

Continuing on with the AssemblyScript concepts chapter.


No any or undefined — interesting. And good, I think. But no union types yet? A little sad.

Okay, so module imports and exports are the main way (possibly the only way) the host communicates with the Wasm script. I knew about exports but didn’t know about declare and module imports. Nice.

The tree-shaking approach to compiling is interesting — dead code doesn’t get type checked, for example.


Not as much type inference as TypeScript. Good to know.

Oh, interesting: WebAssembly has distinct operations for signed and unsigned comparisons. (gt_s vs. gt_u, for example.) Also, == === ===. (Couldn’t resist. But yes, given that the basic types aren’t nullable etc., makes sense that == is also doing strict equality.)

Standard library

I think the reason I like reading through standard library docs is the same reason I like reading through dictionaries — both open up a world of possibilities. And each time I go exploring, I find something new. Need to do more of both.

I like that the low-level WebAssembly instructions are available to AssemblyScript.

Nice, there’s manual memory management when you need it.

StaticArrays for C-like arrays with better performance, got it.

The string considerations section was interesting.

Implementation status

Some drama with WASI and the component model. I don’t know enough about the situation to comment, but I hope things get sorted out in a way that’s good for standards and the web platform.

Ah, there aren’t closures, Promises, exceptions, or rest parameters in AssemblyScript. That’s very good to know.

Using the runtime

A few different runtime options, including support for a custom runtime. Interesting.

Reading about the memory layout was fun. Reminds me of writing C twenty-some years ago. I need to come up with a low-level project to work on sometime.

And that’s a wrap on the documentation. I’ve decided that my learning project for AssemblyScript will be a small convex hull implementation. Notes on that coming soon!

Reply via email or office hours

Learning WebAssembly, part 1

I’m having so much fun learning Elixir that I’ve decided to do a similar thing with web technologies I haven’t used yet. Similar to the 12in23 posts, these will be long and informal and more stream-of-consciousness, and I will say “interesting” and “looks like” far too often.

First up: WebAssembly. Other things I’m looking forward to trying out afterwards: WebGPU, WebRTC, WebGL (I’ve used Three.js on several projects but haven’t used WebGL directly if I recall correctly), WebSockets, service workers, web components, and a number of smaller things (primarily CSS features I haven’t yet used).

So, Wasm. I’ve read bits and pieces about it over the years but haven’t yet actually tried it on anything. I’m going to start arbitrarily with AssemblyScript. Later on I’ll use Rust, and I want to try writing the Wasm text format manually, too.

To begin, I’m going through the AssemblyScript Book.

Getting started

I generated a new AS project with asinit and have been exploring the files it produced, starting with release.js (to get a feel for how the Wasm code gets pulled in). This sample project just adds two numbers together, by the way. The actual AssemblyScript source is straightforward.

In release.js, I initially wasn’t sure what compile meant (in this context) since the example is compiling release.wasm which is already a binary. Looked up the compile page, which explained that the Wasm binary needs to be compiled into a Module, which the MDN key concepts page tells me is executable machine code. And it’s stateless. Okay, that makes sense.

I also wasn’t sure what instantiate did in this particular context. Found the instantiate page, which said it turns a Module into a stateful Instance. That also makes sense now. I imagine the reason one might want to instantiate a Wasm module more than once would be splitting the work up across workers, but I haven’t verified that. Also, looks like instantiateStreaming is now preferred, which simplifies things a little, so you don’t need both compile and instantiate. (That won’t matter for this AssemblyScript experimentation since I’ll be writing AssemblyScript and not finagling with the final JS unless I really can’t resist.)

Looking now at release.wat, because I’m intrigued and I also sometimes like to go in blind and figure things out on my own.

I completely forgot that the Wasm text format is Lispy.

Hmm, I see the $i32_i32_=>_i32 type defined. (By the way, seeing a type defined in an assembly language that looks like Lisp is kind of trippy but also quite cool.) I don’t see that type being used anywhere, though. Must be implicit. I imagine it applies to the exported function. If there’s more than one exported function, maybe they apply in order?

There’s a memory being exported alongside the add function. Interesting. I imagine this gives access to the memory the Wasm script is being executed in (the sandbox), but I’m not entirely sure why — what the host would use it for, I mean. Something to look into when I get back to the text format later.

The function definition itself looks fairly straightforward. Arguments and result type followed by the body of the function. Based on the i32.add instruction not taking any arguments, I’m guessing local.get pushes things onto a stack which i32.add then pops from.

I’m excited to dive deeper into the text format! But back to AssemblyScript proper.

Using the compiler

Okay, looks like memory can be both imported and exported, and the size can be specified as well. Interesting that this is set here (where the AssemblyScript is being compiled into a Wasm binary) rather than in the host when the Wasm is instantiated. My mental model of WebAssembly is more patchy than I realized — it’s been a while since I read an intro — but I’m having fun figuring things out archaeologically right now, so I’ll keep going like this for a bit longer.

Looks like there are several small runtimes that can be compiled in, some with garbage collection. Interesting, didn’t know that. (Looks like it’s a WIP.) And there are threads now. Wow.

Ooh, the compiler API can be used programmatically. I guess I shouldn’t be surprised.

Looks like it’s still just low-level data types that can be passed across module boundaries. Nice that AssemblyScript generates bindings for strings, arrays, and objects, though. That makes it far more usable.

Transforms are intriguing. Probably not useful for most projects, but still intriguing.

I’m going to stop here for this post, to try to keep things from going on too long in any given post. Looking forward to working through the concepts chapter next!

Reply via email or office hours

Learning Elixir, part 1

As my first 12in23 language, here’s my initial foray into learning Elixir. These notes will be informal and more stream of consciousness than anything. I have no idea if anyone will get any benefit from reading this, but I’m sure going to have fun writing it.

I’m starting out by working my way through the Elixir introduction. Once I finish that, I’ll start on a real project.

Basic types

Interesting that string concatenation is <> (which I’m used to meaning != in SQL and Excel/Google Sheets).

The naming of the div and rem functions makes sense. It also amuses me from an HTML/CSS perspective. (You could pull <> into this as well.)

Being able to drop the parentheses in function calls is nice (in that it’s cleaner), but I think the legibility gain from including them is probably worth it.

Ah, I think I’ve seen this kind of function identification (name + arity) somewhere before (maybe Haskell?). It’s a little different and reminds me vaguely of man pages, but I like it — nice to be able to tell at a glance how many arguments a function takes.

The built-in help in iex seems nice, and I’m liking the arity identification more and more as I continue to see it. Looking through the h/0 list now for a brief detour. Interesting that you can compile a file and export bytecode from the REPL. And hot dang, introspection with i is great. I don’t know what PIDs and ports are (in context of Elixir, that is). Okay, from the processes page it looks like PIDs are related to processes which are a fundamental Elixir concept — and not the same as OS processes. Also looks this processes page is a later section of the introduction, so I’ll set it aside for now. (At this point, I’m curious as to why you can set PIDs from strings or atoms or three integers, as opposed to having the system auto-assign them. Also intrigued by ports and references — in the languages I’ve used, ports are almost always ints.)

It’s been a while since I used a language with atoms (Ruby). Intrigued by aliases, looking forward to learning more about them later.

Nice to see string interpolation works as expected. (And in another brief detour I’m now wondering about the different syntaxes across languages. I’ve seen `${...}` in JavaScript and f"{...}" in Python. The "#{...}" here is interesting.) One thing I’m noticing is that there doesn’t seem to be an uninterpolated string. (Both JS and Python have those.) I wonder how much of a performance hit there is in Elixir from having all strings support interpolation. Probably not enough to matter most of the time.

Up next: anonymous functions. The fn and end feel a little noisy syntactically, but with syntax highlighting it’s probably fine. Interesting that invocation needs the . before the parentheses — so variables and functions appear to be in separate namespaces. I wonder if that’s actually true, and if there are other namespaces as well. Glad to see closures. (It would be weird not to, to be honest.)

Ah, list concatenation with ++ and --. One of the reasons I think it’s good to have broad experience with programming languages, by the way, is so your brain can fill up with multiple meanings for almost every symbol. I jest.

Interesting that a list of ASCII numbers automatically returns a charlist. And interesting that charlists are not strings. (Maybe this is the answer to the earlier comment about all strings being interpolated. I wonder if charlists are limited to ASCII.)

I’m realizing that this is going to take forever if I keep commenting on every last little thing. Attempting now to be more selective with comments.

Okay, lists and tuples. At this point I’m wondering if there are structs/records/objects/etc. Update: I did a quick look ahead and yes, there are maps and structs.

I like that the names for size and linear tell you if the operation is O(1) or O(n).

Basic operators

Ooh, the distinction between or/and/not and ||/&&/! is interesting. And here’s === again. Looks like it’s not quite the same as in JavaScript but is conceptually similar (stricter than ==).

Cross-data-type sorting is interesting.

Pattern matching

Ah, I love pattern matching. (I’ve mostly seen it in Rust so far.)

Good to see tuple and list destructuring. And I like how you can match as part of the destructuring. I don’t think I’ve seen that before. (But it’s been a little while since I’ve used Rust — you could say I’m getting rusty (I am so sorry) — and I can’t remember if it has this.)

Ooh, I like the [head | tail] matching. That’s cool.

The pin operator is new (to me) and interesting. Kind of a different way of doing immutability. And in matching, I like how it lets you use a variable without having to overwrite what’s in the variable (which would happen without pinning). I’m also thinking about how it’s the same operator for pinning version numbers in npm.

case, cond, and if

I like case. And guards. (Guards in Elixir, I mean. I’m not making a statement about guards out in the real world.)

Oh, now that’s interesting — anonymous functions can have multiple clauses (which I think I’ve seen in Haskell) but they can also have guards. That seems like a potentially cleaner way to handle main branches of logic within a function, maybe, but I don’t know — food for thought. And interesting that it’s restricted by arity, though in Elixir it appears that functions with different arity are considered different functions entirely. (Which is quite different from variadic functions in, say, JavaScript or Python.)

cond feels (to a degree) like a more powerful switch. Except in this case you can change the condition (both left- and right-hand sides!) for each branch. That’s intriguing. (Actually, giving it a few seconds’ more thought, case is much closer to a switch than cond is. Both of them are more flexible, though.) Playing around with cond feels kind of like having a superpower.

Happy to see unless. I haven’t used an unless since Perl a long, long time ago. I know it’s just syntactic sugar but I like it.

I love that if can return a value (as in Rust). It’s something I often find myself missing when I’m writing, say, JavaScript. Ternaries are the next best thing but not as ideal, in my opinion.

Okay, this is long enough for today. Looking forward to continuing through the tutorial soon! I’m really enjoying this.

Reply via email or office hours

Links #25

Reply via email or office hours

Links #9

Reply via email or office hours

I recently came across Maggie Appleton’s article on digital gardens. Oh my goodness, this is delightful. I’m sure some small part of it is just nostalgia for the old days of the web, but the idea seems good and solid nonetheless. I love digital gardens. (See Mike Caulfield’s The Garden and the Stream and Swyx’s Digital Garden Terms of Service for more in this vein.)

Exploring some of these gardens led me to the idea of learning in public (also see Gift Egwuenu’s Learning in Public talk). Very closely related to digital gardens, of course, but a different angle to look at it from. It also nicely parallels the working in public idea I posted about recently.

I’m looking forward to adopting more of these practices myself. Not sure yet exactly what form that will take, but at the moment I’m thinking it’ll probably be the notes system I mentioned. While that would be doable with the website engine I have now, it wouldn’t be very ergonomic, so I’m probably going to retool. (And by probably I mean almost certainly, because I am an inveterate toolmaker at heart. I’ve written out plans for a new version of Slash, my blog engine, that will easily support notes as well as blog posts and web pages. More on that soon.)

Reply via email or office hours