6 ms·
I’ve been hearing about access to DOM APIs from WASM for years now. Does anyone know why this is such a difficult problem?
by dmart 2y ago
I’ve been hearing about access to DOM APIs from WASM for years now. Does anyone know why this is such a difficult problem?
- xscott 2y agoBecause it's already solved from day one and people keep repeating that it's a problem anyways. Anything you can do in JavaScript, including access to the DOM, can be put into a JavaScript function. You can import that function into a WebAssembly Module, and you can use WebAssembly Memory to transfer large or complicated data as an efficient side channel. It all works.
- hu3 2y agoCould you link an ergonomic example? I have cemented in my memory that DOM access in WebAssembly is not trivial and I suspect others too. This is what StackOverflow tells me (2020): > Unfortunately, the DOM can only be accessed within the browser's main JavaScript thread. Service Workers, Web Workers, and Web Assembly modules would not have DOM access. The closest manipulation you'll get from WASM is to manipulate state objects that are passed to and rendered by the main thread with state-based UI components like Preact/React. > JSON serialization is most often used to pass state with postMessage() or Broadcast Channels. Bitpacking or binary objects could be used with Transferrable ArrayBuffers for more performant messages that avoid the JSON serialization/deserialization overhead. This feels like "we can have DOM access at home" meme.
- xscott 2y ago> This is what StackOverflow tells me (2020) Web Workers can't directly access the DOM in JavaScript either. This is not a WebAssembly problem. If you want a Web Worker to manipulate your document, you're going to post events back and forth to the main thread, and Web Assembly could call imported functions to do that too. I don't even know what he's on about with Preact/React... Save the following as "ergonomic.html" and you'll see that WebAssembly is manipulating the DOM. <!doctype html><title>Not that hard</title> <script type="module"> document.addEventListener('DOMContentLoaded', () => { /* Compile this module with wat2wasm to make the binary below: (module (import "env" "easy" (func $easy (param i32))) (func $run (param) (result) (call $easy (i32.const 123)) (call $easy (i32.const 456)) ) (memory $mem 1) (export "run" (func $run)) (export "mem" (memory $mem)) ) */ const binary = new Uint8Array([ 0, 97, 115, 109, 1, 0, 0, 0, 1, 8, 2, 96, 1, 127, 0, 96, 0, 0, 2, 12, 1, 3, 101, 110, 118, 4, 101, 97, 115, 121, 0, 0, 3, 2, 1, 1, 5, 3, 1, 0, 1, 7, 13, 2, 3, 114, 117, 110, 0, 1, 3, 109, 101, 109, 2, 0, 10, 14, 1, 12, 0, 65, 251, 0, 16, 0, 65, 200, 3, 16, 0, 11, ]); const imports = { easy(arg) { const div = document.createElement("div"); div.textContent = "DOM this: " + String(arg); document.body.appendChild(div); } }; const module = new WebAssembly.Module(binary); const instance = new WebAssembly.Instance(module, { env: imports }); instance.exports.run(); }); </script> That `easy(arg)` function could do much more elaborate things, and you could pass lots of data in and out using the memory export. I'd like to believe a simple standalone example like this would be enough to get people to shutup about the DOM thing, but I know better. It'll be the same people who think you need to link with all of SDL in an Emscripten project in order to draw a line on a canvas. > This feels like "we can have DOM access at home" meme. And I'm sure somebody (maybe you) will try to move the goal posts and claim some other meme applies.
- hu3 2y agoIs this sarcasm I might be missing? Thanks for confirming that WebAssembly still cannot manipulate DOM in 2024. It can only call custom javascript functions that manipulate DOM AND I need to write some arcane function signature language for every DOM manipulating function I want to call. I'll give another 4 years and see if they fixed this.
- xscott 2y ago> I need to write some arcane function signature language for every DOM manipulating function You really don't know that you can create WebAssembly in other languages?!? I used WAT to keep the example short, but that's clearly lost on you. > I'll give another 4 years and see if they fixed this. In that time, there are lot of things you could be learning. Embracing ignorance and belligerence isn't like to serve you well in the long term.
- DonHopkins 2y ago[flagged]
- xscott 2y ago> Thanks for your simple concrete examples and explanations! I'm glad someone liked it :-) > I love his description of Forth as "a weird backwards lisp with no parentheses" I've been interested in that duality between Forth and Lisp before, but my progression always seems to following this path: - Since Forth is just Lisp done backwards and without parens, and since it's not hard to write an sexpr parser, I might as well do Lisp to check the arity on function calls. - But in addition to arity errors, I'd really like the compiler to catch my type errors too. - And since I've never seen an attractive syntax for Lisp with types, I might as well have a real grammar... And then I've talked myself out of Forth and Lisp! Oh well.
- DonHopkins 2y agoPostScript is kind of like a cross between Forth and Lisp, but a lot more like Lisp actually. And its data structures, which also represent its code, are essentially s-expressions or JSON (polymorphic dicts, arrays, numbers, booleans, nulls, strings, names (interned strings), operators (internal primitives), etc.) https://donhopkins.medium.com/the-shape-of-psiber-space-october-1989-19e2dfa4d91e https://donhopkins.medium.com/the-shape-of-psiber-space-octo... Not coincidentally, James Gosling designed the NeWS window system and implemented its PostScript interpreter, years before designing and implementing Java. And before that he designed and implemented "MockLisp" in his Unix version of Emacs, which he self effacingly described like: "The primary (some would say only) resemblance between Mock Lisp and any real Lisp is the general syntax of a program, which many feel is Lisp's weakest point." https://news.ycombinator.com/item?id=29954778 https://news.ycombinator.com/item?id=29954778 James Gosling's Emacs Mocklisp was like FEXPRs on PCP, with support for prompting the user to supply omitted arguments. https://news.ycombinator.com/item?id=14312249 https://news.ycombinator.com/item?id=14312249 DonHopkins on May 10, 2017 | parent | context | favorite | on: Emacs is sexy Hey at least Elisp wasn't ever as bad as Mock Lisp, the extension language in Gosling (aka UniPress aka Evil Software Hoarder) Emacs. It had ultra-dynamic lazy scoping: It would defer evaluating the function parameters until they were actually needed by the callee (((or a function it called))), at which time it would evaluate the parameters in the CALLEE's scope. James Gosling honestly copped to how terrible a language MockLisp was in the 1981 Unix Emacs release notes: https://archive.org/stream/bitsavers_cmuGosling_4195808/Gosl https://archive.org/stream/bitsavers_cmuGosling_4195808/Gosl 12.2. MLisp - Mock Lisp Unix Emacs contains an interpreter for a language that in many respects resembles Lisp. The primary (some would say only) resemblance between Mock Lisp and any real Lisp is the general syntax of a program, which many feel is Lisp's weakest point. The differences include such things as the lack of a cons function and a rather peculiar method of passing parameters. "Rather peculiar" is an understatement. More info, links and code examples: https://news.ycombinator.com/item?id=8727085 https://news.ycombinator.com/item?id=8727085 Comparison of PostScript with Forth and Lisp: https://news.ycombinator.com/item?id=22456471 https://news.ycombinator.com/item?id=22456471 [...] PostScript is much higher level than Forth, and a lot more like Lisp than Forth, and has much better data structures than Forth, like polymorphic arrays (that can be used as code), dictionaries (that can be used as objects), strings, floating point numbers, and NeWS "magic dictionaries" that can represent built-in objects like canvases, processes, events, fonts, etc. Yet Forth doesn't even have dynamically allocated memory, although in a few pages of code you can implement it, but it's not standard and very few Forth libraries use it, and instead use the linear Forth dictionary memory (which is terribly limited and can't be freed without FORGETting everything defined after you allocated it): https://donhopkins.com/home/archive/forth/alloc.f https://donhopkins.com/home/archive/forth/alloc.f PostScript is homoiconic. Like Lisp, PostScript code IS first class PostScript data, and you can pass functions around as first class objects and call them later. https://en.wikipedia.org/wiki/Homoiconicity https://en.wikipedia.org/wiki/Homoiconicity [...]
- Deukhoofd 2y agoThey wanted to implement a typing system first so they could transfer complex types with a strict contract first, as large parts of DOM management would benefit enormously from that, and it would be far better to design an API around. This system has been stuck in different iterations for years. The current active proposal for it is the Component Model: https://component-model.bytecodealliance.org/design/why-component-model.html https://component-model.bytecodealliance.org/design/why-comp....