Hacker News new | past | comments | ask | show | jobs | submit login

> 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.




> I don't even know what he's on about with Preact/React...

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.


(your example becomes a lot easier to read on a computer instead of a phone) but i'd also like to thank you for patiently answering all the questions (esp here: https://news.ycombinator.com/item?id=41961489 and https://news.ycombinator.com/item?id=41964500 (unfortunately the latter comment has been flagged. turn on showdead to read it)).

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/53958939

solving 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.


> i'd also like to thank you for patiently answering all the questions

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.


i am talking about a js library of generic functions that can be imported from wasm to make DOM access easier. handling of string arguments still needs to be solved (i am guessing the shared memory access is the right place for that) and the respective functions on the wasm side need to be implemented for each target language so that DOM access in the target language becomes natural and easy to use.


If you picked a language that gave you low level control, and if you had strong opinions about what you wanted, you could probably write that JS library in a weekend or two. Strings and arrays through shared memory. Maybe use a JS Map of integers to act as handles mapping to JS Objects.


Is 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.


> 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.


[flagged]


> 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.


PostScript 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-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

[...]


Yeah, I've never used Postscript except as a document format created by LaTeX :-)

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.


> it’s just a standard s-expression syntax

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?


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 or its potential use cases. The poster could just have easily have used a regular programming language and compiled that down to a WASM binary. However, for the purposes of a minimal example to be pasted in a text box, this might have led to a much larger Uint8Array.


I wonder what the response would've been if I had left the WAT source code out and just claimed, "this WASM binary was built with a compiler", and not specified the language.


i would have liked to see the source. how would the example look like when written in python for example? and how would it compare with non-wasm javascript?


> how would the example look like when written in python for example?

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.


so does that mean accessing the DOM from python is not possible yet?

for the second question the example you gave is equivalent to what in plain html/js?


> so does that mean accessing the DOM from python is not possible yet?

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>


It means you only get what the person who ported CPython or py2wasm gave you

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)


What percentage of programmers on Hacker News haven't?

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, share their experiences, and educate themselves and other people.

In case you've been living under a rock and didn't realize it, JavaScript, the topic of this discussion, is essentially a dialect of Lisp, with garbage collection, first class functional closures, polymorphic JSON structures instead of s-expressions, a hell of a lot more like and inspired by Lisp and Scheme than C++, and LOTS of people know it.


My point is that if someone says something is arcane, “it’s not, it’s just [something that you’ve potentially never heard of and almost definitely don’t understand even if you have heard of it]” doesn’t help your case. They could look it up, but the fact that they would have to do so proves the commenter’s point - relatively few programmers understand Lisp syntax, i.e. it is arcane.

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.


There's nothing "arcane" about WebAssembly Text format. The fact that you don't recognize it just means you don't know much about WebAssembly, which is fine, 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?


> you’re whining, lashing out, and attacking people who are trying to explain it

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.

[0] https://news.ycombinator.com/item?id=41965178


Exactly.

I, like most devs, know what Lisp is.

I, like most devs, just don't care.


I had a basic idea of what Lisp was before getting into it some 25 years ago. It soon became obvious that, no, I actually had no idea. It's not that what I thought had been wrong, but it had no content.

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!


[flagged]


> There's no point in trying to make other people stop talking about Lisp

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?


> 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.


Sorry to bust your minuscule lisp bubble but just because someone ignored your favorite niche language in an educated career choice, it doesn't mean they are ignorant.

Infantile language tribalism though, have no place in engineering and is blatant ignorance when coming from a supposed adult.


Lisp is a family of languages, most of which are suited for many purposes.

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?


> Implementations of Lisp are no more niche than other languages with managed run-times."

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. :)


So what you mean by niche is actually popularity, and not a specific application area?

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.


If it's about career choices, people skills and charisma will get you further than any technical decisions you might make.


Most devs do know what Lisp'ish languages are because you just can't forget how weird a bunch of nested parenthesis look.

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.


[flagged]


If you think people who chose not to learn a language you like are insecure it tells more about you than about them.


[flagged]


> people who become hostile when you try to talk about something interesting

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.


Are you replying to the correct person(s)? :-)

Only the last quote is mine, and I stand by it.


I listed those quotes to rebut your assertions that we’re being hostile towards a group of people who are merely trying to talk about something interesting, not to imply attribution of all of the quotes to you. I chose the general phrase “the commenter” because it would not have been correct to say “you”, as I was aware you were not the source of many of them.


I can see where you're coming from, but my intent was to talk about the very first interaction that started all of this nonsense:

- 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?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: