[HN Gopher] Learn WebAssembly by writing small programs
___________________________________________________________________
Learn WebAssembly by writing small programs
Author : todsacerdoti
Score : 437 points
Date : 2023-09-05 16:13 UTC (1 days ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| ReleaseCandidat wrote:
| Because I've read it here and elsewhere quite often: What is
| missing from WASM in the browser isn't "just" DOM access, but
| "everything" else - including fetch or XMLHttpRequest - too. Here
| is a list of all web APIs supported by browsers and not supported
| by WASM, the DOM is just one of them:
| https://developer.mozilla.org/en-US/docs/Web/API
|
| But at least there is hope, that these interfaces will be
| available once GC is final and supported by browsers:
| Once GC is supported, WebAssembly code would be able to reference
| and access JavaScript, DOM, and general WebIDL-defined objects.
|
| Last paragraph at https://webassembly.org/docs/web/
| Hadriel wrote:
| I haven't been following webassembly, but as the former 'cure'
| for JS, why has it taken so long to get the basics?
| andsoitis wrote:
| GC proposal is from 2018:
| https://github.com/WebAssembly/proposals/issues/16 and there's
| code:
| https://github.com/WebAssembly/gc/blob/master/proposals/gc/O...
|
| Seems like an awefully long time for progress to be made, given
| all the possibilities it would unlock.
| ReleaseCandidat wrote:
| Yes, but it is now (for some months) supported by V8
| (browser, Node and Deno - hidden behind a flag) and Wasmedge
| and Wasmtime will both have implementations soon.
|
| But I wouldn't hold my breath to being able to call web APIs
| directly from WASM ;)
| 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.
| no_wizard wrote:
| What makes hand written WASM too "low level"?
|
| It isn't, really, what the Rust frameworks do is compile down
| to a specific interop, sure (JS + WASM, its not pure WASM due
| to lack of DOM access for starters).
|
| That said, no reason a hand written WASM app isn't feasible,
| with appropriate JS glue
| ozcanay wrote:
| Cool. Did anyone try targeting Qt applications for WebAssembly? I
| wonder how convenient it is to use.
| zdragnar wrote:
| There's an interesting write up here:
| https://www.linkedin.com/pulse/qt-wasm-nicholas-petreley-1c
|
| Personally, I didn't find the author's sample app to load very
| quickly- I think it was 10 seconds or so just to get something
| on the screen- and it was useless on my phone.
|
| That same app would easily perform better and have better
| device support were it written in js/html/css.
|
| I just don't see a place for things like QT or native gui stuff
| in real world WASM. Number crunching or fast data processing,
| sure, or maybe a game, but a standard UI is crap if the whole
| thing is in a big canvas.
| frithsun wrote:
| Very neat.
|
| As WebAssembly becomes the lingua franca of different ecosystems,
| having a strong grasp of how it works is worth the time
| investment. Thanks for this.
| eliben wrote:
| Cool project!
|
| I maintain a somewhat related repo here:
| https://github.com/eliben/wasm-wat-samples/
| emnudge wrote:
| That looks super useful! I wish I knew about this when first
| learning wat. This would make a great reference!
| 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.
| RagnarD wrote:
| I'm cheered by ongoing progress in adoption of WebAssembly. While
| Microsoft is often given minimal notice here, I urge anyone
| interested in WASM to experiment with Blazor WebAssembly. It's an
| incredibly powerful framework that lets you use C# and most .NET
| libraries (including NuGet packages) as compiled WASM in the
| browser.
| [deleted]
| hsbauauvhabzb wrote:
| Re 'most nuget packages' What's the limitation here? If it
| requires the ability to read a file on disk, does it straight
| up fail or does the file read interface push the action back
| into a server-side rendering type action?
| RagnarD wrote:
| The NuGet packages are zip files containing compiled binary
| and possibly other resources. They're referenced in the
| source code and included at compile time. Since they become
| integrated into the overall compile, there's no need to
| reference them in the final runtime product.
| hsbauauvhabzb wrote:
| Sorry that misses my point, blazor runs client side which
| means that it's sandboxed with the same permissions as
| JavaScript executed within a page - you can't use blazor to
| read a file client-side, but there's nothing to prevent
| wrapping what would be a server side library in a way where
| 'it executes on the client except when it can't, at which
| point it executes on the server'
|
| Doing so would almost always be a security risk, as
| validation would presumably still run client side, but that
| doesn't mean it's not possible to actually achieve such an
| engine.
| oefrha wrote:
| From reading about it, it seems to suffer the same problem as
| Go compiled to wasm: payload is huge, usually multi-MB after
| compression.
| 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
| raincole wrote:
| One thing I don't like about Exercism is that except for the
| most popular languages, the exercises are often not
| "sysematics".
|
| In other words, it's just a bunch of leetcode-like questions,
| ordered by difficulties.
|
| A proper course should order the exercises by language
| features. Exercism actually has built a fantastic interface for
| this[1], but not utiltized it for most langauges.
|
| [1]: https://exercism.org/tracks/csharp/concepts
| tietjens wrote:
| I completely agree with this. I love the platform, the
| mentors, and the enthusiasm for languages. They've done a
| great series every month this year on a new set of languages,
| and have great YouTube interviews.
|
| However, the problems they offer do not help you learn the
| syntax or quirks of specific languages and for me are only a
| place to practice leetcode/codewars style logic. Also
| important! But not what I need when I first begin a language.
| emnudge wrote:
| I really like Exercism! Unfortunately their exercise model is
| considerably more free-form where it teaches you considerably
| less and in much larger chunks. I think this is a great model
| for certain contexts, but the format I have in the repo is more
| similar to "rustlings" and "ziglings" where you're taught
| syntax and features alongside the code examples.
|
| I don't know that their Wasm module is necessarily "broken", so
| I'm unsure whether my contributions would be welcome.
| ysavir wrote:
| Very fair! It's been close to a decade since I used Exercism
| so I don't really know what their stuff is like nowadays.
| From what I remember, the focus was less on teaching you the
| language directly (via instructions) and was more on
| encouraging the user to reiterate on their code and
| experiment, and letting reviewers lead the direction of
| growth.
| 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.
| progmetaldev wrote:
| I do agree things like the GC are very large if we're
| comparing against standard JavaScript, so I don't believe
| the technology is ready for standard customer facing
| websites. For things like internal applications/extranet
| type applications, I think that the runtime download cost
| is minimal compared to the functionality that you are given
| with a proper framework (I can only speak of Microsoft
| Blazor, but that's just language ignorance, and I know
| there are other that fit the model as well). As a web
| developer that also writes utilities to run on the desktop,
| for things such as ETL or fixing bad data, being able to
| not switch to another language or even really framework is
| a huge boon for my time. I know JavaScript, but being able
| to rarely have to deal with it keeps my head in what I'm
| solving, rather than having to context switch between
| interface and server.
| 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/
| tyingq wrote:
| That uses Pyodide. From Pyodide's own pages:
|
| _" At present a first load of Pyodide requires a 6.4 MB
| download, and the environment initialization takes 4 to 5
| seconds."_
|
| So, yes, it works. But there's plenty of situations where
| a big download followed by a 5 second stall is a non-
| starter.
| 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.
| tcfhgj wrote:
| What would that change? DOM interaction can and is
| abstracted away by frameworks anyways and not performance
| critical
| 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.
| math_dandy wrote:
| The two language problem is, indeed, awkward.
|
| DOM bindings in WASM would be awesome. I would be a happy
| nerd if I could do all of my web dev in OCaml.
|
| In the meantime, WASM has real, just not for front end
| dev.
|
| The two language problem is hardly unique to web dev.
| It's also ubiquitous in the machine learning/data science
| space with Python and C/C++/CUDA playing the roles of JS
| and WASM, respectively.
| ReleaseCandidat wrote:
| > DOM bindings in WASM would be awesome. I would be a
| happy nerd if I could do all of my web dev in OCaml.
|
| DOM is not enough for that. You almost certainly would
| like to be able to communicate with your backend ;)
|
| Here is a list of the "usual" web APIs:
| https://developer.mozilla.org/en-US/docs/Web/API And
| everything that needs network access or access to local
| resources (file system in the worst case) will never
| happen to WASM because of security considerations.
| xigoi wrote:
| How is allowing WebAssembly to use the network any less
| secure than allowing JavaScript to use the network?
| ReleaseCandidat wrote:
| Don't ask me :).
|
| At least WASM will get DOM access (and hopefully access
| to similar web APIs) as soon as the GC is stable and
| usable. Once GC is supported,
| WebAssembly code would be able to reference and access
| JavaScript, DOM, and general WebIDL-defined objects.
|
| https://webassembly.org/docs/web/
| lxgr wrote:
| The issue here is the same-origin principle, which rules
| out most low-level networking (since you could just bring
| your own SOP-ignoring HTTP client).
|
| Personally I think that enforcing the SOP at all cost
| (and even when no cookies or other authentication headers
| are injected by the browser) is misguided at this point
| and holding back modern webapps.
| catlover76 wrote:
| > I would be a happy nerd if I could do all of my web dev
| in OCaml.
|
| You don't like Bonsai? Or do you just want something that
| doesn't "transpile" to JS at all?
| math_dandy wrote:
| I find that these compile-to-JS languages are great until
| you want to bring in other JS libraries. Then you're
| stuck writing bindings which is annoying, and often
| brittle if you're not really careful.
| catlover76 wrote:
| Oh I didn't even think of that--that sounds like a huge
| pain in the ass lol
| yieldcrv wrote:
| If it was the JavaScript killer it will attract
| JavaScript devs and they'll make it just like JavaScript
|
| not syntax-wise just community wise, where the package
| and package managers are a mess and why there is demand
| for a JavaScript killer
| zarzavat wrote:
| You can certainly bridge the DOM to WASM with a virtual
| DOM. The problems with WASM are not just
| interoperability.
|
| The biggest problem is tooling. You cannot build tooling
| for in-browser WASM because it runs in a browser sandbox.
| JS has the same problem but the difference is that JS has
| a known object model that the browser can provide good
| tooling for.
|
| Whereas with WASM the browser has little insight into
| what those opaque Memory objects contain. So you need to
| bring your own tooling and run it inside the sandbox, and
| the sandboxing does not make this easy.
|
| Let's say for example you want to pause execution,
| inspect the object tree, and run a REPL while it's
| paused.
___________________________________________________________________
(page generated 2023-09-06 20:02 UTC)