[HN Gopher] Learn WebAssembly by writing small programs
       ___________________________________________________________________
        
       Learn WebAssembly by writing small programs
        
       Author : todsacerdoti
       Score  : 250 points
       Date   : 2023-09-05 16:13 UTC (6 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | ducktective wrote:
       | Is there a WA UI framework for web similar to Svelte or Vue?
        
         | RetiredRichard wrote:
         | Technically Blazor
         | 
         | https://learn.microsoft.com/en-us/aspnet/core/blazor/host-an...
        
         | Kennnan wrote:
         | Hand written wasm is too low level to use a UI framework with,
         | but there are rust frameworks that compile to wasm for web. For
         | example, Yew and Leptos are both web-first frameworks, and
         | there are a few such as Dioxus or wgpu that are native-first
         | and work on web.
        
       | syndicatedjelly wrote:
       | Gave WASM a try and ran into problems exposing connections to a
       | SQLite database I wanted to connect to locally. Has anyone done
       | something like that before and can point to good resources?
        
         | yebyen wrote:
         | Check out Spin! It includes sqlite support natively in the
         | runtime since 1.4:
         | 
         | https://www.fermyon.com/blog/spin-v14
        
           | syndicatedjelly wrote:
           | Looks like it's only available for Python, I was hoping for a
           | more language agnostic solution. Thanks though!
        
             | yebyen wrote:
             | It is? The docs example shows support for Rust, TypeScript,
             | and Python:
             | 
             | https://developer.fermyon.com/spin/sqlite-api-guide#using-
             | sq...
             | 
             | I'm not sure what holds back from being a completely
             | language agnostic solution, but I know when I tried binding
             | functions into my Ruby app with wasmer I had nothing but
             | problems, I wound up using WASI exclusively to communicate
             | with my WASM modules. I don't honestly know how good the
             | WASM language agnostic story is today. I gave a talk with
             | my perspective as a Rubyist at OSS Summit and
             | CDCon/GitOpsCon a few months ago in Vancouver. The talk
             | (and lightning talk variant) are called "Exotic Runtime
             | Targets: Ruby and Wasm on Kubernetes and GitOps Delivery
             | Pipelines"
        
       | ReleaseCandidat wrote:
       | Just a remark: if you want to play with WASM features like GC,
       | use Binaryen's `wasm-opt` instead of WABT, as `wasm-opt` supports
       | way more WASM extensions.
        
       | brundolf wrote:
       | It's super interesting to me how much WebAssembly resembles a
       | "real language" that's sorta writable by-hand. I bet it lowers
       | the bar quite a bit when targeting it
        
       | mdswanson wrote:
       | Is it just me, or does "WebAssembly" seem like an oxymoron? Maybe
       | it's because I've been involved with the web since its earliest
       | beginnings.
        
         | teddyh wrote:
         | You might like this bit of speculative history:
         | <https://www.destroyallsoftware.com/talks/the-birth-and-
         | death...>
        
           | mdswanson wrote:
           | Thanks! That was fun. I hadn't seen it. There's the problem
           | of bootstrapping METAL, but perhaps left for a different
           | lecture! ;-)
        
         | [deleted]
        
         | patmorgan23 wrote:
         | I mean technically it's browser VM bytecode by it's semantics.
        
       | ysavir wrote:
       | Looks very similar to the Exercism model, which also has a free
       | WASM course filled with small exercises[1]. I wonder if the
       | author considered contributing to that course or working together
       | with them, it might get their work to a broader audience and
       | leverage the existing toolset Exercism has to offer.
       | 
       | [1]https://exercism.org/tracks/wasm
        
       | imiric wrote:
       | This is great, thanks!
       | 
       | One of my favorite ways to learn a new language or framework is
       | via "koans"[1], which this reminds me of. It's a gentle ramp up
       | from basic to advanced features, and the TDD-like workflow of
       | seeing a test fail, understanding why, and fixing it, is really
       | conducive to learning, while giving you that dopamine jolt from
       | "a-ha!".
       | 
       | [1]: https://github.com/ahmdrefat/awesome-
       | koans/blob/master/koans...
        
         | dfee wrote:
         | sounds like a great way to learn a language "on your own".
         | unfortunately, Rust is missing. can anyone propose a link?
        
           | billti wrote:
           | It credits Rustlings at the end of the page linked to
           | (https://github.com/EmNudge/watlings#credits).
        
           | Kalq wrote:
           | Isn't that basically Rustlings?
        
             | dfee wrote:
             | i think you've found what i'm looking for!
             | https://github.com/rust-lang/rustlings
        
       | [deleted]
        
       | Joker_vD wrote:
       | While it's an interesting (and effective) approach to learn
       | something, what is the point of learning WebAssembly? After all,
       | I thought that WASM was supposed to be something like "LLVM for
       | web", a low-level IR for webdev languages to target and for
       | browsers to execute efficiently, and not something that you'd
       | write manually. Or am I wrong?
        
         | hoten wrote:
         | Some reasons to understand the textual representation, besides
         | curiousity:
         | 
         | You are embedding a WASM engine and want to better grok how the
         | import or exporting works.
         | 
         | You are writing a compiler that targets WASM.
        
         | emnudge wrote:
         | Author here!
         | 
         | My initial motivation to learn WASM (as someone from a
         | primarily web background) was that I had a pretty poor
         | understanding of WASM in general and so I had a lot of
         | difficulty working with WASM builds in just about any capacity
         | other than a heavy JS wrapper.
         | 
         | There are aspects to how WASM works that are quite different
         | from other kinds of assembly formats that make learning the
         | basics pretty important. e.g. how memory is requested,
         | provided, grown. How functions are received and exported.
         | Capabilities of tables.
         | 
         | A lot of this might be abstracted by massive wrappers, but
         | you're losing a lot in perf and debugability when using them.
        
           | wanderlust123 wrote:
           | Thanks for putting this together, I too learn best by doing,
           | and this looks very helpful!
        
         | [deleted]
        
         | chrisco255 wrote:
         | Sometimes you may need to debug the actual wasm code or
         | understand what the compiler is outputting. Depending on the
         | flags you set during compilation, you may want to optimize for
         | size of binary or for performance. You may also want to compare
         | the wasm produced by two different languages or different
         | versions of the language compiler. Maybe you want to verify
         | what libraries are actually getting bundled with your wasm.
        
           | thamer wrote:
           | Understanding what the compiler outputs is also essential to
           | debug the inevitable issues that come up when porting an
           | existing program to WASM. Since it's a different platform
           | with significant limitations, it's important to know how to
           | replace some core APIs and capabilities and how to interface
           | with these alternatives.
           | 
           | By limitations I mean things that a POSIX program would
           | expect that aren't generally available from WASM, like
           | network programming, file system access, processes and
           | threads, pipes and signals. Emscripten and WASI help to some
           | extent, but the replacement APIs are rarely fully compatible.
        
         | ReleaseCandidat wrote:
         | Actually it is quite high level (with the GC extension even
         | "higher" than C), not comparable to "real" assembler. It has
         | types. It isn't fun writing WAT, but for small stuff it's
         | perfectly doable.
         | 
         | That's a record with 3 fields, its constructor and getters
         | using the GC extension:                   ;; A `struct` with 3
         | fields, all immutable.         (type $testStruct
         | (struct             (field $first i64)             (field $foo
         | f32)             (field $baz f64)))               ;;
         | Constructor. `ref` is a reference          (func $mkTestStruct
         | (param $a i64) (param $b f32) (param $c f64) (result (ref
         | $testStruct))             (struct.new $testStruct (local.get
         | $a) (local.get $b) (local.get $c)))          (export
         | "mkTestStruct" (func $mkTestStruct))               ;; Getter
         | function for the three fields:               (func
         | $getTestStruct1 (param $rs (ref $testStruct)) (result i64)
         | (struct.get $testStruct 0 (local.get $rs)))          (export
         | "getTestStruct1" (func $getTestStruct1))               (func
         | $getTestStruct2 (param $rs (ref $testStruct)) (result f32)
         | (struct.get $testStruct 1 (local.get $rs)))          (export
         | "getTestStruct2" (func $getTestStruct2))               (func
         | $getTestStruct3 (param $rs (ref $testStruct)) (result f64)
         | (struct.get $testStruct 2 (local.get $rs)))          (export
         | "getTestStruct3" (func $getTestStruct3))
        
         | __s wrote:
         | For awhile I was using a raw wasm program for a game engine's
         | random number generator. Stored all the state in global
         | variables, so no heap necessary
         | 
         | Eventually I moved the whole game engine into wasm & at that
         | point it all got ported to Rust
         | 
         | https://github.com/serprex/openEtG/blob/8b7069cc52ec8db3406a...
        
       | arek_nawo wrote:
       | Pretty cool.
       | 
       | I haven't really explored WASM hands-on (I'll give this guide a
       | try) but, given that it's already been a few years, I think it's
       | been hugely beneficial for web development.
       | 
       | Not the "JavaScript killer" some where hoping for, though it was
       | never meant to be one. Instead it integrates pretty nicely within
       | the existing ecosystem, optimizing existing use-cases and
       | allowing new ones when heavy computations are required. Net
       | benefit for all web devs - faster libraries, impressive dev tools
       | and more portable node binaries.
        
         | danielvaughn wrote:
         | I've been watching WASM from afar, and it's my understanding
         | that it's not a JS killer because it doesn't have direct access
         | to the DOM or to most DOM APIs. I'm curious if there's another
         | reason I'm missing?
        
           | ReleaseCandidat wrote:
           | It doesn't have access to _anything_ (in the browser, in
           | other runtimes there is WASI with POSIX functions).
           | Everything has to be imported from or exported to JS.
           | 
           | And currently using anything but C, C++ or Rust isn't
           | feasible, as the runtime needed for a GC is way too big. A
           | Haskell "Hello World" for example is about 1MB (even after
           | running `wasm-opt` on the generated WASM binary).
        
             | titzer wrote:
             | Virgil compiles to Wasm and brings its own GC as well, and
             | the runtime is on the order of about 4KB. The GC is a
             | simple semi-space copying collector and the compiler prunes
             | away dead code from libraries, so binaries are pretty
             | small. So overall I don't think this is a Wasm issue as it
             | is mostly a language runtime size issue.
        
             | dragonwriter wrote:
             | > And currently using anything but C, C++ or Rust isn't
             | feasible
             | 
             | Someone should tell Anaconda that they can't do this, then:
             | https://pyscript.net/
        
             | plopz wrote:
             | In the browser, can it integrate with SharedArrayBuffer,
             | worker's postMessage or transferrable offscreen canvas?
        
               | connicpu wrote:
               | WASM essentially can call javascript functions that were
               | imported, and I believe javascript is able to read WASM's
               | memory (a big help for transferring strings). If you're
               | using something like Rust, all the glue code to call any
               | JS APIs can be automatically generated for you with wasm-
               | bindgen, so it really isn't a huge problem usability
               | wise. It's just not great for performance.
        
               | ReleaseCandidat wrote:
               | Depends what you mean by "integrate". It always has to
               | import or export JS functions or memory. WASM (without
               | WASI) has no direct connection to "the outside World",
               | everything has to be routed via JS FFI. So you can import
               | or export a SharedArrayBuffer to communicate with JS.
               | https://developer.mozilla.org/en-
               | US/docs/WebAssembly/JavaScr...
               | 
               | But you need the WASM thread extension (for atomic access
               | to the shared memory) to be able to use shared memory.
        
             | patmorgan23 wrote:
             | I mean Microsofts Blazor framework can use WASM to run
             | C#(and its runtime) in the browser.
        
             | yebyen wrote:
             | > isn't feasible
             | 
             | This is kind of subjective, and in the context of "is this
             | a JS killer" which is what you're answering, I'd agree, it
             | makes sending the Wasm to the browser a bit of a non-
             | starter that it requires a large bundle most of which is
             | simply boilerplate for whatever runtime, without some type
             | of local storage and persistent cache it's difficult to
             | imagine using Ruby in a Wasm for example. If you're
             | deploying to a container, where you're able to use a cache
             | warmer to ensure the wasm is ready before it's called, then
             | a 1mb binary might not be such a big issue.
             | 
             | (I mean, it is still a big issue because the point was fast
             | cold starts, and big assemblies mean no fast cold starts,
             | but again, subjective value judgments... 1mb isn't too big
             | in many cases and I'd wager most of the cases that I'd
             | really care about. But in a browser...)
             | 
             | But if you're not trying to run the Wasm in a browser then
             | it's still potentially quite useful. You might not be
             | running all of your Wasm in a browser and it might still be
             | a JS killer, and all of those might not be in conflict.
        
               | ReleaseCandidat wrote:
               | Well, the main reason why I'm taking a deeper look at
               | WASM is because I'm creating a language and compiler that
               | is optimized to compile to WASM. While I don't think that
               | my compiler will be the JS killer, I do think that WASM
               | languages using a (the WASM) GC have a future.
        
           | lenkite wrote:
           | Yep. Give access to the DOM - perhaps via a batch
           | update/fragment mechanism and watch as it becomes a JS
           | killer. But WASM is currently a starved prisoner locked up in
           | a room only allowed to view the goodies outside the cell
           | door.
        
           | math_dandy wrote:
           | Is being a "JS killer" even a goal of WASM? From what I
           | understand, WASM's goal is to allow computationally heavy
           | workloads (e.g., image and audio processing) to the browser
           | by providing a compilation target for C code. This is how we
           | get nice things like Figma or MS Office running in the
           | browser.
           | 
           | Let WASM do the number crunching, let JS do the UI.
        
             | Philip-J-Fry wrote:
             | It's not the goal from what it seems. But it's definitely
             | what would make it the most interesting to a lot of people,
             | and it's what I think most people expected at some point.
             | 
             | For a lot of companies the only place JavaScript is ever
             | used is on their website frontend. And it makes you wonder,
             | why does it even still need to be JavaScript? With the rise
             | of SPAs and the fall of normal document based websites,
             | browsers are basically just becoming their own platform
             | like Windows Desktop, Mac, Linux, Android, iOS, etc. You
             | could say it's been that way for a long time, but more and
             | more apps are becoming web based only because the browser
             | is now powerful enough to run what used to be a desktop
             | application.
             | 
             | Browsers are literally just a VM with an address bar. We go
             | to a URL and run a program, except right now there's
             | basically the limitation that the program has to be written
             | at least partly in JavaScript. Being able to deploy an
             | entire website as WASM is just the next logical step from
             | what I see.
        
       ___________________________________________________________________
       (page generated 2023-09-05 23:00 UTC)