asm.js came about because it was a very optimizable subset of JavaScript, then it was superseded by WebAssembly, then the proposal in TFA is basically asking for asm.js back, but perhaps the better answer is to make WebAssembly fully support all of what JS could originally do.
This is perhaps why as I get older I sometimes feel like I want to get out of software development and become a goose farmer like that dude on LinkedIn - lots of times feels more like spiraling in circles than actually advancing.
Additionally we already have LLVM all over the place, alongside JVM and CLR, it is the most deployed compiler infrastructure with contributions at the same level as the Linux kernel.
Javagator / Jazilla!
https://www.cnet.com/tech/tech-industry/javagator-down-not-o...
Look at the stronghold grip of C/C++ and how long it’s taken Rust to gain a meaningful foothold in those realms for example.
Google wanted to flat replace JS once already, that was the entire origin of Dart. They only pivoted to the cross platform mobile framework as its primary target after it failed to gain traction as a standard
Dartium was cancelled and AdWords team, having just migrated from GWT to AngularDart, saved the Dart team.
Eventually many left the team.
Somewhere at Google, Flutter started and when they decided to replace JavaScript on their original design, they decided to reach out to the Dart team.
So Dart got a new purpose in life, being Flutter's language.
In this process it was rebooted from dynamic language, into a static type one, having JIT and AOT toolchains.
How long Flutter, and by association Dart, remain relevant remains to be seen.
It was actually really fortunate in that for a long time it didn’t have a big community behind it and they just put a lot of very smart language designers on the team where they had ten years to try various approaches and learn from the mistakes of not only themselves but others without a lot of outside noise.
But there’s no other language I would prefer to write applications in. It’s just a really nice mix of ergonomic, expressive and powerful.
I feel like the WASM fervor has more to do with the fact people don’t enjoy using Frontend tools or JavaScript etc. vs looking at the actual utility tradeoffs
>> WASM isn’t the silver bullet everyone seems to cling to.
And it isn’t the silver bullet exactly for the reason that it's horribly complicated to access normal JS objects including strings. Copy from JavaScript to WebAssembly:
Use TextEncoder to convert a JS String to Uint8Array
Copy the bytes from the Uint8Array to WemAssembly.Memory
Copy from WebAssembly to JavaScript:
Copy the bytes from WebAssembly.Memory into a Uint8Array
Use TextDecoder to convert from Uint8Array to JS String
JS Strings are pretty much always going to be "rope data structures". Trying to provide anything other than copy-in and copy-out is going to expose implementation details that are complicated as fuck and not portable between browsers.https://github.com/WebAssembly/js-string-builtins/blob/main/...
"the overhead of importing glue code is prohibitive for primitives such as String, ArrayBuffer, RegExp, Map, and BigInt where the desired overhead of operations is a tight sequence of inline instructions, not an indirect function call"
I guess the more elegant and universal stringref proposal is DEAD now !?
https://github.com/WebAssembly/stringref/blob/main/proposals...
I don't really mind, as it keeps the wasm bytecode cleaner.
We don’t yet have consensus on this proposal in the Wasm standardization group, and we may never reach there, although I think it’s still possible. As I understand them, the objections are two-fold:
WebAssembly is an instruction set, like AArch64 or x86. Strings are too high-level, and should be built on top, for example with (array i8).
The requirement to support fast WTF-16 code unit access will mean that we are effectively standardizing JavaScript strings.
I really like stringref and hope the detractors can be convinced of its usefulness. Dealing with strings is not fun right now.And dealing with strings isn't fun in many other languages or runtimes or OSes.
e.g.1. C# "Strings in .NET are stored using UTF-16 encoding. UTF-8 is the standard for Web protocols and other important libraries. Beginning in C# 11, you can add the u8 suffix to a string literal to specify UTF-8 encoding. UTF-8 literals are stored as ReadOnlySpan<byte> objects" - https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...
e.g.2. Erlang/BEAM/Elixir: "The Erlang string type is implemented as a single-linked-list of unicode code points. That is, if we write “Hello” in the language, this is represented as [$H, $e, $l, $l, $o]". The overhead of this representation is massive. Each Cons-cell use 8 bytes for the code point and 8 bytes for the pointer to the next value. This means that the 5-byte ASCII-representation of “Hello” is 5*16 = 80 bytes in the Erlang representation." - https://medium.com/@jlouis666/erlang-string-handling-7588daa...
This refers just to Erlang's string() type, not BEAM strings in general; it's just a bad default. If you're not using binaries, you're doing it wrong, and that's exactly why Elixir's strings are UTF-8 binaries.
I agree about keeping wasm bytecode cleaner. The code plus simd stuff is such a great generalization of the ARM and X86 CPUs we mostly use. The idea of gunking it all up with DOM related stuff is distasteful.
It supports nearly arbitrary imports of anything you want. How much more flexibility do you need? You could provide an `eval` function to run arbitrary code with a small amount of effort.
Is the problem that Emscripten and/or Rust haven't laid it all out on a platter?
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.
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.
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.
Thanks for confirming that WebAssembly still cannot manipulate DOM in 2024.
It can only call userland 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.
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.
You can lead a horse to water, but you can't make it drink. Funny how he touts his ignorance of WebAssembly by describing the WebAssembly Text Format that he does not recognize for what it obviously is as "some arcane function signature language". ;)
So arcane that it's just a standard s-expression syntax that you can manipulate and process and generate in any Lisp-like language (like Racket, mentioned below)!
If you'd like to see some beautifully hand written WebAssembly Text Format code that implements a Forth compiler/interpreter that uses dynamic linking to dynamically compile and run the Forth words it interactively compiles, and also uses Racket as a macro pre-processor, check out WAForth:
https://news.ycombinator.com/item?id=34374057
DonHopkins on Jan 13, 2023 | parent | context | favorite | on: What the hell is Forth? (2019)
This is a great article! I love his description of Forth as "a weird backwards lisp with no parentheses". Reading the source code of "WAForth" (Forth for WebAssembly) really helped me learn about how WebAssembly works deep down, from the ground up.
It demonstrates the first step of what the article says about bootstrapping a Forth system, and it has some beautiful hand written WebAssembly code implementing the primitives and even the compiler and JavaScript interop plumbing. We discussed the possibility of developing a metacompiler in the reddit discussion.
I posted this stuff about WAForth and a link to a reddit discussion with its author in the hn discussion of "Ten influential programming languages (2020)":
https://news.ycombinator.com/item?id=34056735
Yes, I agree FORTH should be probably be on the list, at least if the list was a few languages longer, for as influential as it's been.
WAForth for WebAssembly is beautiful and modern!
https://github.com/remko/waforth
It's a lovingly crafted and hand written in well commented WebAssembly code, using Racket as a WebAssembly macro pre-processor.
I learned so much about WebAssembly by reading this and the supporting JavaScript plumbing.
The amazing thing is that the FORTH compiler dynamically compiles FORTH words into WebAssembly byte codes, and creates lots of tiny little WebAssembly modules dynamically that can call each other, by calling back to JavaScript to dynamically create and link modules, which it links together in the same memory and symbol address space on the fly! A real eye opener to me that it was possible to do that kind of stuff with dynamically generated WebAssembly code! It has many exciting and useful applications in other languages than FORTH, too.
Lots more discussion and links in the reddit article.
But here's the beef, jump right in:
https://github.com/remko/waforth/blob/master/src/waforth.wat
Reddit /r/Forth discussion of WAForth:
https://www.reddit.com/r/Forth/comments/zmb4eb/waforth_wasmb...
remko:
Author here
If you can't be bothered to install VS Code, you can have a look at a standalone version of the example notebook (in a 26kB self-contained page).
And if you're planning to go to FOSDEM 2023, come say hi: I'll be giving a talk there on WebAssembly and Forth in the Declarative and Minimalistic Computing devroom.
DonHopkins:
I really love your tour-de-force design and implementation of WAForth, and I have learned a lot about WebAssembly by reading it. Never before have I seen such beautiful meticulously hand written and commented WebAssembly code.
Especially the compiler and runtime plumbing you've implemented that dynamically assembles bytecode and creates WebAssembly modules for every FORTH word definition, by calling back to JavaScript code that pulls the binary bytecode of compiled FORTH words out of memory and creates a new module with it pointing to the same function table and memory.
WebAssembly is a well designed open standard that's taking over the world in a good way, and it also runs efficiently not just in most browsers and mobile smartphones and pads, but also on the desktop, servers, cloud edge nodes, and embedded devices. And those are perfect target environments for FORTH!
What you've done with FORTH and WebAssembly is original, brilliant, audacious, and eye-opening!
I'd read the WebAssembly spec before, and used and studied the Unity3D WebAssembly runtime and compiler to integrate Unity3D with JavaScript, and I also studied the AssemblyScript subset of TypeScript targeting WebAssembly and its runtime, and also Aaron Turner's awesome wasmboy WebAssembly GameBoy emulator .
I first saw your project a few years ago and linked to it in this Hacker News discussion about Thoughts on Forth Programming because I thought it was cool, but it's come a long way in three years, and I'm glad I finally took the time to read some of your code, which was well worth the investment of time.
Until reading your code, I didn't grasp that it was possible to integrate WebAssembly with JavaScript like that, and use it to dynamically generate code the way you have!
Also, the way you used Racket as a macro assembler for WebAssembly was a practical and beautiful solution to the difficult problem of writing maintainable WebAssembly code by hand.
Even for people not planning on using FORTH, WAForth is an enlightening and useful example for learning about WebAssembly and its runtime, and a solid proof of concept that it's possible to dynamically generate and run WebAssembly code on the fly, and integrate a whole bunch of tiny little WebAssembly modules together.
Playing with and reading through your well commented code has really helped me understand WebAssembly and TypeScript and the surface between them at a much deeper level. Thank you for implementing and sharing it, and continuing to improve it too!
remco:
Wow, thanks a lot, I really appreciate that! It makes me very happy that I was able to get someone to learn something about WebAssembly by reading the source code, which is exactly what I was going for.
[More links and discussion of WAForth, WebAssembly, and Forth Metacompilers:]
https://www.reddit.com/r/Forth/comments/zmb4eb/waforth_wasmb...
DonHopkins on Jan 13, 2023 [–]
Here's the author's blog post about WAForth:
A Dynamic Forth Compiler for WebAssembly
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.
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
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
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
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
Comparison of PostScript with Forth and Lisp:
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
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
[...]
There was a language called "V" a while back, different than a more recent language called V. It was basically a Forth where quoting was done with square brackets. This replaced the colon-semi notation for defining words, and it was also nice for nested data structures. This language seems to have fallen off the web though.
You mentioned FExprs. I never looked at Mock Lisp, and it sounds like Gosling doesn't think I should! However, I'm sure you're aware of Kernel. I think of Scheme as the "prettiest programming language I don't want to use", and I think the vau stuff in Kernel makes it even prettier. (But I still don't want to use it.)
For homoiconicity, I've also considered something like Tcl or Rebol/Red. The latter two blur the lines between lexer and parser in a way that I'd like to learn more about.
But really, I always come back to wanting static typing. Both for compile time error checking, and to give the compiler a leg up in runtime performance. Instead of using separate declarations like you see in Typed Racket and some others, I wonder if a Lisp with the addition of one "colon operator" to build typed-pairs would do it. Just one step down the slippery slope of infix syntax sugar. In the context of WebAssembly, something like this:
(import (foo a:i32 b:f64):())
(export (bar x:i64 y:f32):(i32 i32)
(code goes here)
)
Using colons to specify the types of the parameters and return result(s). It'd also be nice to have colon pairs like this for key:value in hash tables, or as cond:code in switch/conditional constructs.I.e. they are correct that it is arcane. What percentage of programmers today do you think have ever seen code written in any Lisp dialect, let alone understand it?
That seems like an easy question, but there a lot of choices which complicate it. I'm sure people have compiled CPython to WebAssembly, but I think you only get the WebAssembly imports they (or Emscripten) have chosen for you. I can't use that as an example of what I was trying to show.
It looks like py2wasm is aiming for a true Python to WASM compiler, rather than compiling an interpreter. However, I don't think it supports user-defined imports/exports yet. There's a recent issue thread about this (https://github.com/wasmerio/py2wasm/issues/5).
> how would it compare with non-wasm javascript?
I'm not sure I understand the question. If you're just using JavaScript, it just looks like JavaScript.
for the second question the example you gave is equivalent to what in plain html/js?
No. It means you only get what the person who ported CPython or py2wasm gave you. It's not a limitation in WebAssembly, and maybe they have some other (hopefully better) API than the `easy(123)` example I was trying to show.
> for the second question the example you gave is equivalent to what in plain html/js?
If I understand what you're asking, it's just:
<!doctype html><title>plain jane</title>
<script type="module">
function easy(arg) {
const div = document.createElement("div");
div.textContent = "DOM this: " + String(arg);
document.body.appendChild(div);
}
easy(123);
easy(456);
</script>that's what i meant. it's not possible until someone adds the necessary features to the wasm port of the language. makes sense of course, like any feature of a new architecture.
If I understand what you're asking
exactly that, thank you. it is easier to understand the example if there is no doubt as to what is the js part and what is wasm (it also didn't help that the code was not easy to read on a phone)
Flaunting your ignorant anti-intellectualism isn't a good look.
You do know this is 2024, you have Internet access, and you can just look shit up or ask ChatGPT to learn new things, instead of cultivating ignorance and pointlessly criticising programmers trying to raise awareness and educate themselves and other people.
In case you didn't realize it, JavaScript is essentially a dialect of Lisp, and LOTS of people know it.
If you’re trying to raise awareness of something, don’t act like the reader is stupid if they don’t already understand. Insisting that something is obvious, especially when it is not, means any reader who does not understand it will likely perceive the comment as snobby. As does including snide remarks such as “in case you’ve been living under a rock”.
> Flaunting your ignorant anti-intellectualism isn’t a good look.
Why do you assume that I personally don’t know what s-expressions are just because I agree that they’re arcane? Labelling someone as an ignorant anti-intellectual just because they disagree with something you said isn’t a good look either.
I, like most devs, know what Lisp is.
I, like most devs, just don't care.
There's no point in trying to make other people stop talking about Lisp by complaining about how proudly ignorant you are, and how you want to remain that way, so you don't want anyone else to talk about it. This really isn't the place for that, since you always have the option of not reading, shutting up, and not replying and interrupting and derailing the discussion, so other more knowledgeable and curious people can have interesting discussions without you purposefully harassing them like a childish troll.
Infantile language tribalism though, have no place in engineering and is blatant ignorance when coming from a supposed adult.
Implementations of Lisp are no more niche than other languages with managed run-times.
Lisp has been used for even operating system development: Lisp code taking interrupts, and driving ethernet cards and disks and so on.
Which member of the Lisp family are you talking about, and what do you think is the niche?
No more niche than Java, C# .NET and Python? Right...
> Which member of the Lisp family are you talking about, and what do you think is the niche?
You can combine all of the Lisp family together and still it wouldn't scratch the popularity, demand or job positions of any of the top languages.
Look, nobody denies Lisp'like languages are being used. Just like Fortran. :)
Fortran has a niche: numeric computing in scientific areas. However, even Fortran is not your grandfather's Fortran 66 or 77 any more. I had a semester of the latter once, as part of an engineering curriculum before switching to CS.
It supposedly has OOP programming in it, and operator overloading and such.
I don't know modern Fortran, so I wouldn't want to look ignorant spreading decades-old misinformation about Fortran.
Nobody is trying to make you stop talking about it. We’re trying to make you understand that the way you’re talking about it is elitist. When someone said they were confused by the syntax, you could have just explained it without judgement. Instead, you felt compelled to flaunt your membership of the in-group who understands Lisp, and try to make others feel stupid by implying that people who don’t understand it aren’t good programmers, or are anti-intellectual.
You’re doubling down on it in this comment, too, still insistent on making people feel like they’re “less than” because they don’t know Lisp:
> so other more knowledgeable and curious people
If I didn’t know Lisp, and my first exposure to it was from someone who sees this kind of toxicity as a reasonable way to speak to people, would I want to join their community?
Wouldn't (didn't!) faze me. Every community has it. The most popular languages, platforms and tools in fact bring out unbridled hostility. Probably, hostility finds a peak in the second most popular camps. :)
We have already lost people who are influenced by this sort of fluff, because those people will be turned away from Lisp by the anti-Lisp trolling about parentheses, niches and slow processing over everything being a list, and so on. There aren't enough Lisp people around to counter it.
I knew Lisp the way I know that that guy walking down the street is my neighbor Bob. But since I've never had a conversation with Bob, I actually have no idea who he is.
When I see Korean writing in hangeul, I know it is Korean writing, but can't read a letter of it (nor speak a word of Korean).
These examples are like knowing what Lisp is.
The thing I had not expected was how the knowledge in the Lisp world and its perspectives are very informative about a whole lot of non-Lisp!
Why don't you just go away and let other people have their interesting discussions without you, instead of bitterly complaining about things you purposefully know nothing about and refuse to learn? How does it hurt your delicate feelings to just shut up and not bitch and whine about discussions you're not interested in?
I think you’re assuming that all of the comments you’re talking about are written by the same person, when they’re not. I haven’t been attacking anyone, and I don’t think I’ve replied to anyone who’s tried to explain it.
> things you purposefully know nothing about and refuse to learn
Why do you still assume I don’t know what they are? I’ve already pointed out that my belief that s-expressions are arcane doesn’t mean I don’t know what they are.
As another illustration of my point, I just stumbled across this comment on another post:
> But maybe the whole "ease of use" budget is blown by using a Lisp in the first place.[0]
The fact is that Lisp syntax is understood by relatively few programmers, which meets the definition of arcane. You immediately flying off the handle when someone calmly points this out will not help your goal.
They just don't care enough to invest time in it because it is niche. And proponents tend to tirelessly spam about it from their ivory towers like it's flawless and everyone who didn't learn it is somehow inferior, somehow justifying personal attacks like yours. Classy as usual.
Online discussions always fall apart this way, and it sucks. Having had some time to think, I'm sorry for my part of it.
However, the interesting thing to me, and maybe to you is that you can create a WebAssembly binary in a lot of different programming languages. I don't know what languages you like, but Rust has a more conventional syntax, and comparable code could've looked like this:
#[wasm_bindgen]
extern {
fn easy(s: &i32);
}
#[wasm_bindgen]
pub fn run() {
easy(123);
easy(456);
}
Short examples like this always leave something out. The easy() function isn't very interesting, but it does "manipulate the DOM" by creating a new DIV and appending it to the body. Also, languages like C and Rust have a "shadow stack" and memory allocators, so dealing with memory isn't shown here.The point I was trying to make was that WebAssembly can easily cause changes to the DOM by calling imported functions. That leaves a lot of freedom to design functions that do what you want. You could make your own graphics library, audio library, text output, DOM manipulation, and so on... And it all works today. The downside is that you do need to make your own set of functions, and designing good APIs is hard. Clearly the easy() function is not a good API.
When people complain about WebAssembly not having direct access to the DOM, I'm not even sure what they mean. Most things in the DOM are done by assigning attributes or creating elements. Would having `getElementByName()`, `createElement()` and `setAttribute()` functions scratch the itch? Because you could do that today (with some clever glue code in JavaScript). What do they (you) actually want?
People can argue about how fast the transitions are between WebAssembly and the JavaScript functions, but you can work around that by packing more work per call and passing large data or strings in or out of the memory.
ps: WebAssembly's Text format (WAT) is also a bit arcane to me, not because of the Lisp syntax, but because there are multiple ways to do almost anything, and it's hard to find good examples which do things cleanly. Even since writing that post last night, DonHopkins' comments on WAForth showed me that I could've written it like this:
(module
(import "env" "easy" (func $easy (param i32)))
(func (export "run") (param) (result)
(call $easy (i32.const 123))
(call $easy (i32.const 456))
)
(memory (export "mem") 1)
)
Which is nearly the same thing as the Rust snippet above.We’re becoming annoyed not because people are trying to talk about something interesting, but because they are being intentionally insulting and condescending and then using bad faith arguments like this one when they’re called out on it.
Which of these quotes represent the commenter “trying to talk about something interesting”?
> flaunting your ignorance and your anti-intellectualism
> The point is that anyone who's distracted by the arcanity of Web Assembly Text Format obviously doesn't understand the first thing about WASM
> You do know this is 2024, you have Internet access, and you can just look shit up
> In case you've been living under a rock and didn't realize it
> but you're whining, lashing out, and attacking people who are trying to explain it, and trying to police and derail discussions between other people who are more knowledgeable and interested in it, which makes you a rude anti-intellectual asshole… Why don't you just go away and let other people have their interesting discussions without you, instead of bitterly complaining about things you purposefully know nothing about and refuse to learn? How does it hurt your delicate feelings to just shut up and not bitch and whine about discussions you're not interested in?
> And that proves my point that you're flaunting your ignorance and your anti-intellectualism. But you be you. There's no point in trying to make other people stop talking about Lisp by complaining about how proudly ignorant you are, and how you want to remain that way, so you don't want anyone else to talk about it. This really isn't the place for that, since you always have the option of not reading, shutting up, and not replying and interrupting and derailing the discussion, so other more knowledgeable and curious people can have interesting discussions without you purposefully harassing them like a childish troll.
> Look, it's pretty clear I stepped on some insecurity.
Only the last quote is mine, and I stand by it.
- I said WebAssembly can already manipulate the DOM with functions.
- He asked for an ergonomic example because StackOverflow told him it can't be done. The "we can have DOM access at home" bit seems like the start of things to come.
- I provided a concise example, and expressed skepticism that this would settle the discussion.
- He responded with sarcasm, and weirdly accused me of sarcasm.
- I reacted poorly to his bitchy and ungrateful reply.
My best guess is that the WAT format confused him. He didn't know it was a programming language, and he didn't know you could do it with other programming languages, so he got insecure and lashed out.
Do you have a better explanation for the weird transition from technical discussion to flame war and hurt feelings?
Around 10 years ago, I was having lunch in a food court and overheard "Luckily I don't have to use javascript, just jquery".
Around 5 years ago, a co-worker admitted he still had issues distinguishing what functionality was python and what came from Django (web framework), despite having used them both daily for years. He thought it was because he learned both at the same time.
I wouldn't be surprised if this was more of the same, and just getting worse as we pile more and more abstractions on top.
but what bothers me a bit is that this example still uses custom javascript code.
i tried to find and answer but essentially what appears to be missing is the ability to access js objects from wasm. to access the document object it looks like i need a wrapper function in js:
jsdocument(prop, arg){
document[prop](arg)
}
so far so good, i can import this jsdocument() function and use it to all any property on the document object, but if document[fun](arg) returns another DOM object, then what?maybe more elaborate:
callDOMobj(prop, arg, prop2, arg2){
document[prop](arg)[prop2](arg2)
}
i can call this function with the arguments ("getElementById", "foo", "append", "<div>more foo</div>") in any WASM language and it will result in calling document.getElementById("foo").append("<div>more foo</div>"); which allows some basic DOM manipulation already. but then i want to continue with that object so maybe i can do this: getDOMobj(prop, arg){
var len = objlist.push(document[prop](arg))
return len-1;
}
callDOMobj(pos, prop, arg){
objlist[pos]["prop"](arg)
}
can you see what i am getting at here? building up some kind of API that allows me to access and manipulate any DOM object via a set of functions that i can import into WASM to work around the fact that i can't access document and other objects directly. it looks like this is similar to this answer here: https://stackoverflow.com/a/53958939solving this problem is what i mean when i ask for direct access to the DOM. i believe such an interface should be written only once so that everyone can use it without having to reinvent it like it appears to be necessary at the moment.
It's nice of you to say so. Thank you.
> can you see what i am getting at here?
I mostly can, but I'm not sure we're clear what we're talking about yet.
I see a lot of people who repeat something about "WebAssembly isn't usable because it can't manipulate the DOM". Ok, so I show an example of WebAssembly manipulating the DOM. That should put that to rest, right? If not, I'm curious what they meant.
> building up some kind of API that allows me to access and manipulate any DOM object via a set of functions that i can import into WASM to work around the fact that i can't access document and other objects directly,
This is a shortcoming in the language implementation, or the library for the language. The machinery is already there at the WebAssembly level. If your language is low level (Rust, C, or C++), and doesn't have what you want, you could roll your own. If your language is high level (Python or Lua), you're at the mercy of the person who built your version of Python.
The core of WebAssembly is a lot like a CPU. It's analogous to AMD64 or AArch64. It'd be weird to say you need changes to your CPU just to use a function called `getElementByName()` or `setAttribute()`. Some WebAssembly extensions have added features to make that "CPU" more like a Java style virtual machine. There are (or will be) garbage collected references to strings, arrays, and structs. This might make it better for implementing Go and Java style languages, and it could help with a fresh implementation of Python or Pike too. And maybe some of those changes will give controlled access to JavaScript style objects.
There's a last discussion to be had about performance. Maybe the bridge between WebAssembly imports and exports is too slow for intensive use. That's a debate that should be backed up with benchmarks of creative solutions. Maybe accessing JavaScript strings is so common, so important, and so slow that it really does require an enhancement to the standard.
The current active proposal for it is the Component Model: https://component-model.bytecodealliance.org/design/why-comp....