Responding to the OP, since there is no comment section on the site.
First off, this rant gets the history of Wasm wrong and the facts of Wasm wrong. I wouldn't unload on a random person on the internet generally, but I would like to point a sentence like:
> Not only that, but for the most part the WebAssembly specification team were flying blind.
It's an ad hominem. This really just impugns people and invites an argument. It might be cathartic, but generally it doesn't advance the conversation to cast aspersion like this.
And it's not true. I can tell you from first hand experience that a baseline compiler was absolutely on our minds, and Mozilla already had a baseline compiler in development throughout design. The Liftoff design that V8 shipped didn't look too different from the picture in our collective heads at the time. And all of us had considerable experience with JIT designs of all kinds.
As for the history. The history is wrong. The first iteration of Wasm was in fact a pre-order encoded AST. No stack. The second iteration was a post-order encoded AST, which we found through microbenchmarks, actually decoded considerably faster. The rub was how to support multi-value returns of function calls, since multi-value local constructs can be flattened by a producer. We considered a number of alternatives that preserved the AST-like structure before settling on that a structured stack machine is actually the best design solution, since it allowed the straightforward extension to multi-values that is there now (and will ship by default when we reach the two-engine implementation status).
As for the present. Wasm blocks and loops absolutely can take parameters; it's part of the multi-value extension which V8 implemented already a year ago. Block and loop parameters subsume SSA form and make locals wholly unnecessary (if that's your thing). Locals make no difference to an optimizing compiler like TurboFan or IonMonkey. And SSA form as an intermediate representation is not as compact as the stack machine with block and loop parameters which is the current design, as those extra moves take space and add an additional verification burden.
A final point. Calling Wasm "not a stack machine" is just a misunderstanding. All operators that work on values operate on the implicit operand stack. This is the very the definition of a stack machine. The fact that there is additional mutable local storage doesn't make it not a stack machine. Similarly, the JVM has mutable typed locals and yet is a stack machine as well. The JVM (prior to 6) allowed completely unstructured control flow and use of the stack, leading to a number of problems, including a potentially cubic verification time. We fixed that.
All that said, there might be a design mistake in Wasm bytecode. Personally, I think we should have implicitly loaded arguments to a function onto the operand stack, which would have made inlining even more like syntactic substitution and further shortened the bodies of very tiny functions. But this is a small thing and we didn't think about it at the time.
[edit: Perhaps "ad hominem" is a bit strong. It feels different to be on the receiving of a comment like "flying blind"--it doesn't mean the same thing to the sender and receiver--especially when this was really not the case, as I state here.]
Ignoring any factual incorrectness, I can not see how the author could have made his point in a more respectful way. He clearly has great enthusiasm for WASM and respect for it's authors, I am struggling to see how anyone could have interpreted it as cathartic...
The paragraph in which your excerpt originated makes this pretty clear:
> The developers of the WebAssembly spec aren’t dumb. For the most part it’s an extremely well-designed specification [...] I considered WebAssembly’s design to be utterly rock-solid, and in fact I still strongly believe that most of the decisions made were the right ones. Although it has problems, it’s incredible how much the WebAssembly working group got right considering it was such relatively unknown territory at the time of the specification’s writing.
: I understand that the comment author has other concerns besides the phrasing, but I'm only focusing on the phrasing right now.
Maybe in the future don't accuse engineers of 'flying blind' if you aren't inviting return fire.
From context there was a lot of conjecture going on, but the big challenge with building something new is what order to build the bits in to give you the most useful information fastest. As the number of people goes above 2 the odds that everyone agrees or that 'everyone' is right drop rapidly toward zero. You do the best you can, and hope it's good enough that you still have time to react to the worst of the decisions you made earlier. But it's not 'flying blind'.
Maybe you would have a point if it were a Linus-style "only a fucking idiot would" rant. But responding to a sincere attempt to defend a design decision as if it were an insult is some prima donna behavior.
It is not an ad hominem in any sense! For one thing, this part isn't even an attack - here the author is trying to explain and essentially forgive why the (allegedly) sub-optimal design was chosen: that there wasn't enough information at the time to make a fully informed decision! He's saying "it wasn't their fault they designed it like so, at the time it probably seemed like the best decision".
Second, even if it were some form of attack - it wouldn't be an ad hominem because it is not an _irrelavant_ personal attack. It is directly relevant whether some group made decisions based on sufficient existing information etc. The author might be totally wrong about the facts, but at least he believes and offers evidence regarding the situation at the outset of development.
It hurts to have your work criticized, and I can't comment on the factual accuracy of the timeline and other claims, but the piece does not come off at all badly-intentioned, personal or otherwise unreasonable: it comes off mostly as purely technical criticism.
An example of an ad hominem: saying that someone must have cheated on their taxes, because they have some depraved sexual kink. Whether or not the assertion (“X is a fetishist”) is true, it is obviously irrelevant to ascertaining the truth of whether X cheats on their taxes.
An example of a not-ad-hominem: saying that someone is more likely to have cheated on their taxes, because they are an old rich white man. This might be stereotyping (i.e. inductive reasoning), it might be a “personal attack”, and it might be disallowed in a debate for any number of other reasons, but it’s not an ad hominem: being in the relevant class really does have some correlation (however small) with cheating on one’s taxes (mostly because all groups other than the relevant group consist of people with less access to the resources that would allow them to get away with cheating on their taxes.) Therefore, the truth-value of the assertion is not entirely irrelevant to the syllogism—so it’s not an ad hominem.
To be clear that particular phrase wasn't direct technical criticism - but it was embedded in an article that was largely technical and it was in direct support of the technical arguments (essentially "it ended up like that because no compilers, streaming or not, existed yet").
I think you should look carefully at the definition of ad hominem. You say that the author couldn't have known what he was asserting. Maybe, sure! That doesn't relate to it being an ad hominem though (it would make it simply false). You say the worse are deprecating. I don't really agree, but even if they were that doesn't by itself make it an ad-hominem.
Ad hominem needs all three factors: _personal_, _irrelevant_ and _an attack_.
I think you can make very good arguments that it was not an attack and certainly that it was not irrelevant. I would even argue it's not personal, since it is not an about a personal characteristic of any person, but simply an observation about what point in time an event took place. Like if I said "you were FLYING BLIND because you had to decide whether to take you umbrella before knowing the weather at your destination", it is not even a personal thing: just observing that you had to decide before you had all the information.
>It's an ad hominem.
I didn't read that as a criticism at all. He was just saying that the Wasm team didn't have all the information that they would ideally have wanted to have. No idea if that's true or not, but I think you're misreading it if you take it as some kind of ad hominem attack.
It's generally used to indicate operating without information that's really required, but historically it's used when that information is missing because someone else should have provided it and didn't do so, leaving those doing the work without information they need. Without that context it sounds like someone is choosing to make a poor choice and work without knowledge they should have. The responsibility for the problem in those interpretations falls on different people, which can make the phrase tricky to use without ruffling some feathers, as it seems to have done here.
If that's an extension, and it's only implemented in V8 but not in some of the other main WebAssembly platforms, then I guess it's fair to call it out as not being part of WebAssembly.
Phase 4 requires a second implementation, and then we will ship it.
The "flying blind" idiom just means that you were operating on intuitions developed from experience, but without much guidance from directly relevant factors (post mentions a working compiler with which you could run experiments to see what would and would not work).
I don't see how it could be interpreted as a dig in this context.
> It's an ad hominem.
Er, no, it's not. It's not a an attack on the designers as bad people, nor does it serve the role in an argument it would need to serve to be part of an ad hominem argument even if it was.
It may be inaccurate, misleading, , deceptive, uninformed, or a million other kinds of wrong, but it's not ad hominem.
I'm sorry that you felt attacked by that line, I really tried my hardest to phrase it in a way that didn't assign any blame. I wasn't trying to imply that the team wasn't thinking about these issues, just that real-world implementations of this kind of VM didn't exist yet and so many of the practical issues were difficult to see in advance.
Many of your other issues I directly address in the article itself, for example that optimising compilers can recalculate the information lost when using locals (tl;dr: why recalculate this information when you could include it in the format) and that Wasm started as an AST machine. The JVM works similarly to Wasm, true, but it is generally considered a hybrid stack/register machine. I'd define Wasm as a similar hybrid.
As for the multi-value extension, although that improves codegen for streaming compilers it doesn't reduce complexity unless locals are also deprecated. Something that I don't talk about in the article but that seems like it may be a problem going forward is that Wasm seems to have no mechanism in the format for major version bumps/breaking changes. Unnecessary things like locals and structured control flow (see the second article in the series) cannot be removed even when they are subsumed by more-general features.
Agree with all you wrote. With my own implementation, I'm hesitant to include these extensions until they are "standardized" (I have a one-man toy project, bleeding edge is unreasonable). I understand and have watched as going through the phases seems like quite a slow process (not that it's a bad thing). I think, to avoid fragmentation, it is reasonable for someone targeting WASM at this point to assume the multi value extension is not available. I know there are proposals about runtime capabilities and the like, but with so few of these extensions reaching full spec adoption yet, I don't think they're viable features to leverage even if implemented in the most popular runtimes.
I.e. just change the one word “WebAssembly” to “asm.js” in the sentence you quoted. Consider it a typo. Does the history now read correctly?
To me, it broke down as:
(1) SSA form would allow for substantially simpler compilers. Adding block/loop parameters while maintaining support for locals as an extension doesn't address that, as compilers would then still have to implement full support for both modes of operation.
(2) The magnitude of the performance impact of this design decision.
I have some limited experience in compiler design but not enough to really have an understanding of the implications.
Inlining is likely important for performance. Any chance this will be corrected?