I fear that this is one of those "I've heard someone make a metaphor and taken it too literally, then rebutted that literalism broadly."
I imagine 99% of the time that metaphor is made the author would be just as happy saying "JS is the new C", it simply doesn't roll off the tongue as well.
I agree with the first part, disagree with the second. "JavaScript is assembly" is, in my estimation, usually a rather blase metaphor for the idea of JavaScript as a compile target. People don't say "JavaScript is the new C" because generally you don't target C. (Generally you don't target assembly, either, but the distinction between assembly and machine code is academic to most people.)
And it's no surprise that we're getting lost in this; making arguments based on metaphors rather than the thing itself is a classic trap. We should make an effort where possible to talk about what JavaScript is rather than what it "is".
I guess it depends on how general you mean "generally" to be, but there is a history of people targeting C for new and experimental languages. It's a convenient target because we have a good idea of what kind of assembly will be created for a given chunk of C, and you can get architecture independence for free.
> and you can get architecture independence for free
And you target JavaScript for precisely the same reason :) Perhaps the better way to say it is this: C is a language which was once written by hand, but which is increasingly being used as a target for higher-level languages. The same thing is happening to JS, but at least to me "JavaScript is the new C" is not a particularly useful way to express that similarity.
> because generally you don't target C. (Generally you don't target assembly, either, but the distinction between assembly and machine code is academic to most people.)
You're excluding a large chunk of compilers with those two generalizations. Targeting assembly rather than directly emitting machine code is extremely common (gcc being one of the obvious examples), and targeting C is very common for new/experimental languages.
All I'm trying to say is that "a target for higher-level languages" is not a defining attribute of C in a way that makes "JavaScript is the new C" a helpful analogy.
"making arguments based on metaphors rather than the thing itself is a classic trap"
Well, yes and no. I do agree that it often goes completely wrong and can be very misleading. But the JavaScript/assembly argument is more an analogy than it is a metaphor, and analogies are a very important function of intelligence and a tool for making important discoveries.
That said, I like your generalization "compile target" a lot more than calling JavaScript assembly.
You really shouldn't try to use metaphors when making an argument. Someone says A is like B, another person disagrees that A is like C. But no, says another, A is like D. Finally, an internet troll points out A is like B and D, but definitely not like C. By then, everyone's brain gives up trying to figure it all out.
If you're gonna make a point, make a point, it's that simple.
Are you arguing that metaphors have no value when explaining a concept? I'm sure Shakespeare would be a whole lot more boring without the use of metaphor:
To be, or not to be: one could ponder:
Whether one's sense of self-worth increases
In direct proportion to one's ability to accept adversity,
Or to address challenges,
And in so doing solve said challenges?
Personally, I prefer the original:
To be, or not to be: that is the question:
Whether 'tis nobler in the mind to suffer
The slings and arrows of outrageous fortune,
Or to take arms against a sea of troubles,
And by opposing end them?
[Apologies in advance for the inevitably botched translation.]
Explaining a concept to a friendly listener is an entirely different challenge than convincing even an honest skeptic of something. Metaphors are good for the former, dangerous at best for the latter (but beware the continuum between them).
And of course entertainment is yet another game. Any sort of serious argument in a work of entertainment is probably trying to fly under the radar of skepticism anyway... Dang it. Point is, fiction is not usually a good model for rational discussion.
The comment I replied to said "You really shouldn't try to use metaphors when making an argument." Was Shakespeare not using his characters to present an argument for dramatic effect?
Shakespeare is entertaining and metaphors are fun. Do you disagree with a poem and bring up logical fallacies? Of course not, we read them for entertainment value and anything we learn is a bonus. That is separate from metaphors used when trying to discuss the nuances of an argument within the confines of trying to have a logical argument. Poems and Shakespeare aren't supposed to be logical all the time, that would be boring.
Which logical argument are you referring to? Scott Hanselman used an analogy to make an observation about javascript. It's a blog post, not a rigorous mathematical thesis. Who are you to say what rhetorical devices someone should or should not use?
It's not, in fact; it's a good extension and modification of the metaphor.
Not that the original metaphor is wrong or useless; but thinking of javascript as C provides some glimpse into the risks of what made C++ problematic.
The author picks Coffeescript as an example of a fairly sensible approach to the problem, but "the language-wank crazy" are taking a lot of risky approaches.
There is just so many holes in his comparison that even if it's broadly a good point. It's lost in the details.
His whole argument depends on the comparison between Javascript and generally "Assembly" but as he argues against the label "Web Assembly" the proper comparison is from Javascript and X Assembly, where X may be X86 for instance.
> If you are designing a language, compiling it to JavaScript is a pretty attractive option, for much the same reason that compiling C to machine code is an attractive option: running it in more places.
No, you compile C to machine code because that is it's execution model, or perhaps because of performance. You do not "compile C to machine code to run it in more places" This however is not central to his argument.
> They’re mostly backwards compatible with JavaScript
Not languages compiled through the emscriptn model.
> You still need to grok the DOM, or node, or whatever other platform your program is interacting with, and that’s probably documented in JavaScript.
The same is true for compiled languages. The fact that they are often documented in C is just an artifact.
> They break almost all of the tooling that exists for JavaScript debugging
Anyone who has ever worked on a new compiled language knows that this is also problems of compile-to-asm languages.
> CoffeeScript programs don’t vary any less across architectures than the JavaScript programs it creates.
Again, this is true in the C->X86 ASM also.
> CoffeeScript does not offer an order of magnitude difference in expressiveness
This is the strongest point of his argument, but just goes to show that he takes the metaphor much too strongly, and misses the whole point of it in the first place.
There is literally no other language you can write in that will run against the following, Oh multiplex for osx, linux, windows, ios, android, symbian, and windows phone, blackberry, etc whenever possible: IE, Firefox, Opera, Safari, Chrome, Old android browser, webkit derivitives, etc. JS is the only language available everywhere so everything targets it. That's that. No other reason.
Ideally a bytecode would be created with standard libraries and a browser extension and js fallback for a more efficient language that even js can be compiled to. But we have this not atm.
As for your idea of compiling to some bytecode, if one wants to minimize sandboxing overhead, the representation needs to carry along with it an efficiently machine-checkable proof that it is well behaved. There are other ways to do this, but a sound static type system is the most well researched way of doing this. On top of this, the semantics of JavaScript aren't very clean, so there's a tension between making the semantics of the representation a good target for JavaScript and making the semantics of the representation a good target for non-JavaScript languages.
A stack-based bytecode would likely yield the best code size (at least in the absence of compression). An SSA-based representation is most attractive from the standpoint translating to the most optimized native code. A register machine representation is a good happy medium for fast interpreters and pretty good tracing JITs. People also occasionally float the idea of shipping around compressed syntax trees to at least cut down on bandwidth usage and time taken to tokenize and parse JS, as a least disruptive option.
In the end, I think there are too many options and too many players with conflicting goals for a standards committee to come up with a solution that gets widely adopted, so we'll need the invisible hand of the market to sort out the competing ideas.
At present, I think the closest we've got to your ideal is LLVM bitcode via Google's PNaCl plugin. Emscripten can generate JavaScript from LLVM bitcode, closing the loop, but I'm not aware of any production systems that target PNaCl with an Emscripten fallback for browsers that don't understand PNaCl.
Edit: s/space usage/bandwidth usage/, note that compressed syntax trees are the least disruptive option. Those wishing to disrupt the browser language landscape probably don't want the least disruptive option, but it's probably preferable to a lower level representation that too closely matches the semantics of JS, as that would tend to force JS semantics deeper into the VM's implementation.
And that's the heart of it all. If we had a static low-level highly optimized language, im sure we'd all compile javascript or whatever to it, especially if we can add on type checking and other optimizations.
HOWEVER, we cannot. That's the issue. So JS is the web's most low-level language at the moment.
I always found it silly to compare an expensive language like JavaScript, that couldn't be further away from the machine, to assembly language. A language where data stuctures are hash maps with string keys, where numbers are boxed doubles on the heap, etc.
I think the point is something like this: Assembly is the only language your machine can run. Everything else your machine does must eventually be converted to a machine instruction. Javascript is the only client side DOM manipulation scripting language that all browsers can run. Everything else (CoffeeScript, for example) must eventually be converted to javascript.
I think that is the core of the analogy, and it is not talking about how high or low level each language is in an absolute sense but in a relative sense. It is talking about it being the "at the metal" language of machine instructions and browser "instructions" respectively.
Of course, there are other parallels, but they aren't as strong. Part of the reason for using CoffeeScript is because of a perceived increase in expressiveness, but that increase is very small compared to the improvement of C over assembly (as the author of this article points out).
"where numbers are boxed doubles on the heap, etc."
Actually, you don't know that. Since doubles are immutable, the runtime can (and does) cheat, including turning many of them into integers. It all boils down to predictable usage patterns.
That is not the only way to do it in Javascript though.
if you allocate an ArrayBuffer then you are dealing with a plain block of bytes that you can treat as points (or anything else).
These are the things that Javascript has been growing to facilitate the idea of js as asm. Emscripten uses ArrayBuffers to allow C to compile to JS without the messiness.
You really feel that JS "couldn't be further away from the machine?" What about languages that don't have a specified execution model? Haskell and other MLs, for example.
I believe that these languages do have a specified execution model (how would you execute them without one?), they just don't have any hard prescription as to how to map it onto hardware the same way that, for example, C does.
> JavaScript is not the Assembly of the Web. It’s the C of the web. The to-JS languages are lining up to become the C++ of the web.
that's just uninformed. both analogies are wrong. but yours is even more so.
c++ is usually compiled down to assembly w/o going through c (there have been a few but it has not been mainstream for _many_years). so coffeescript or any other to-js language is _not_ the c++ of the web! the author implies, that (say) coffeescript is to js as c++ is to c.
but before (s)he gives two reasons about c over assembly.
1. assembly is variable, c is a constant,
2. c is way more expressive.
there is some truth in the first on, that one does not hold for js. whether it really holds for assembly is debatable given how much porting is involved for arm devices. and if you think about asm.js you might think that's a different assembly (js to asm.js is like asm to simd instructions maybe?).
the second point might not hold for coffeescript, but look at closure, fay or elm. they are very distinct from javascript.
> The to-JS languages are lining up to become the C++ of the web.
What I find funny about this remark was that I think it was intended to be disparaging because the meme these days is that C++ sucks.
But C++ is actually wildly successful and is the bastion of many very large, complex, fast, applications that would be very challenging to write in vanilla. Yes, you can stick to just C, but many many programmers have profitably switched to C++ instead. Almost the entire game industry, most desktop applications that people use for their jobs, web browsers and even JavaScript engines themselves are all written in C++.
If the new crop of compile-to-JS languages are in a similar boat, then sign me up!
i tried to address the analogy which is implied by these two points. and it is true, that for coffeescript on javascript, coffeescript is not more constant and js is not more variable. but that's not the point of the argument javascript were the assembly of the web. the point is, that all these languages compile down to js. as c and c++ compile down to assembly.
and honestly the "c is constant" is not right some of the time either. consider small/big endianness, different libcs. heck, even the syntax changed (k&r surely looks and feels different).
my comment on simd instructions to assembly was an analogy to asm.js and javascript.
"CoffeeScript may require fewer tokens, sure, but not 10 to 1 fewer."
True, but I find that its real power is in not forcing me to remember all sorts of crazy-ass stuff that's only relevant because JavaScript, as a language, is just sort of batshit crazy.
Case in point: I'm doing some work right now that requires me to use JavaScript[1]. Today, I was writing your typical 'is this variable undefined or not?' if-clauses:
if (typeof foo !== 'undefined') { bar(); }
Obviously, I don't do this enough, because I ended up having to look the stupid thing up instead of just knowing it ("I know I have to use === for equality; is the equivalent 'not-equals' version only two equals signs or three?", and so forth).
In CoffeeScript, in comparison, I'd simply write:
bar() if not foo?
It takes a lot less mental energy for me to remember the second version than the first.
Also, if I had a nickel for every time I've had to write var that = this... Anyway, suffice it to say that CoffeeScript may not be an order of magnitude more expressive, but it's cheap enough to get up and running that its benefits are well, well worth it to me.
[1] It's an iOS app that has a critical component built into a UIWebView, and there is absolutely no way to make this stuff native, seeing how it's rendering HTML. I guess I could rig up some awful build phase voodoo that would compile my .coffee files, but that sounds ridiculous.
The author of this post misses the point of the expression completely. The expression has nothing to do with assembly language but it has to do with the fact that Javascript will be further and further abstracted away over time but yet, all these abstractions will compile down to Javascript. In due time no one will be programming in Javascript except for a few geeks. This is similar to what happened to assembly language and in that way Javascript compares to assembly language.
That seems like an odd prediction to make for an expressive, dynamic, C-like language. It's nice to have other options, but I suspect that large amounts of vanilla Javascript will be written for many years to come.
I'm sure that in the late 70's or early 80's people said the same thing about assembly language and guess what, even today there are still people programming in assembly. The point is that languages change faster than the platforms they run on. Why else would there be CoffeeScript or Haxe? It's just a natural evolution. To us Javascript might seem perfectly acceptable as a programming language but only time will tell if the next generation of programmers will feel the same about that.
Maybe it's most accurate to say that Javascript is the x86 of the web. Modern CPU's have a totally different internal semantics but emulate the x86 machine model externally. Seems pretty parallel to how asm.js works.
The analogy was getting at the fact that in asm.js, JavaScript is used almost as a byte code input to a compiler that has a very different underlying machine model, just as x86 is used as such by modern x86 CPUs. In both cases the somewhat strange dynamic has arisen from the pervasiveness of devices that understand x86, JavaScript. Whether JavaScript or x86 is more prevalent is really neither here nor there.
i think the "JS is assembly for the web" strictly refers to the fact that you cannot write closer-to-the-metal code than javascript. it'c certainly not the C-of-the-web either, but some combination of the two. i do agree that there are more parallels to C than to asm, but nit-picking the differences will lead to no adage at all :)
"Assembly varies wildly between architectures" - but javascript runs on a single architecture. it's just that browser vendors all implement the same one.
the other points are valid, but i dont think this was ever supposed to be that deep a comparison.
> i think the "JS is assembly for the web" strictly refers to the fact that you cannot write closer-to-the-metal code than javascript.
This exactly. JS is the lowest level of code you can reliably run through a browser. That makes it, by definition, the 'metal' of the web. And that will probably not change for a very long time.
That is, the C you get out of a language that is doing optimization of high level stuff into legal, portable C as a compile target is not the language you'd use if you, a human, were coding in C.
And this is very analogous to, for example, the code generated by a high level language targeting modern JS. It's going to allocate stuff on arrays, and use cryptic pointers, and do things the odd way around when it turns out to be faster. It's going to have unhelpfully named variables, and no unnecessary whitespace or comments, and it's going to operate silently on dangerous-looking assumptions that it's proven safe at a higher level.
Sure, generated C interops easily with manual C, just like generated JS interops easily with traditional hand coded JS, but they have little in common except their formal grammar.
I thought this was going to be about Emscripten, asm.js, compiled "desktop languages"? CoffeeScript and other to-js languages are not what people mean when talking "javascript is web assembly".
With all the interesting things going on right now on planet Earth, it amazes me that a post about "The Correctness of JavaScript Analogies" makes it to the top on HN.
I don't think equating languages that compile to javascript with C++ improves the analogy all that much. If anything a better analog would be a language that compiles to C like Chicken Scheme or Vala.
I also don't think that comparing one's language to C++ is necessarily a good way to advertise it. ;)
No it's not. There are a bunch of language implementations that compile to C, with semantics nothing like C++. Just as there are a bunch of language implementations that compile to JS but have semantics that differ from JS or whatever "JS++" would be.
He seems to be offended by people comparing JavaScript to assembly, but when people say "JavaScript is web assembly" they're usually making a specific point about how you can write languages that compile to JavaScript, not an overall judgement of the language.
Of course JavaScript has more in common with C than assembly, but context matters.
Far to many comments are coming across like they where from students fresh out of compilers 101 .. please guys; cool your engines, for the sake of the community.
> They break almost all of the tooling that exists for JavaScript debugging.
I just don't see the utility of pre-processors for JS or CSS. I know I'm in the minority here, are developers really working without debugging? I can't wrap my head around that workflow.
I code in CoffeeScript a fair bit, and I don't find it's that bad even without source maps[0] because of the similarity between CS source and JS output. I can put in debugger statements and breakpoints just as I would in vanilla JS.
this, the notion that CoffeeScript generated code resembles some kind of arcane binary like output is wrong. As knowing the basics of JavaScript is pretty much a requirement for working with CoffeScript I never ever encountered any problems when debugging generated code because is not obfuscated and easy to read and the compiler doesn't do anything you didn't specifically write in your CoffeeScript. I am going to go out on a limb here and say that I think compiled CoffeeScript is easier to read then most peoples hand written JS. What makes code unreadable is the Closure compiler which is completely different beast.
>I just don't see the utility of pre-processors for JS or CSS.
I'm not sure how CSS comes into the discussion, it isn't executed, and thus isn't debugged. And things like SASS and LESS are fairly simple, straightforward pre-processors.
>I know I'm in the minority here, are developers really working without debugging?
I don't think so. You couldn't pay me enough to write javascript. But I have to end up with some javascript because browsers don't support anything reasonable. So I use a haskell -> javascript compiler. I still have to read javascript to debug what is going wrong, but at least I don't have to write it.
There are far more meaningful reasons why JavaScript is not Web assembly than metaphor wrangling.
There are things that you simply cannot do in JavaScript that you can in assembly. Many of those are horrible practices with little use. In assembly, if the computer can do it you can do it. C retains most of those abilities because it compiles to Assembly/Machine code.
How does one even write the unix cat command in JavaScript?
The structure of while(read())write() does not go down well in JavaScript.
JavaScript needs to be able to fork, wait and preempt if it wants to be assembly.
I understand the different interpretations of the metaphor. That's the problem with metaphors, they are open to interpretation. With Javascript the term assembly for the web has been used seriously by people in a variety of contexts.
Brendan Eich has argued against a bytecode vm approach to a low level powerful system, saying that Javascript can provide that low level functionality. This is very much the viewpoint that the capability can be considered comparable to assembly.
I don't think that is correct but I recognise that that is what some people refer to as assembly for the web.
I really don't care what it is called and what metaphor is used, that is all trivial compared to the fact that Javascript is not up to performing all the tasks that it should be able to do if it wishes to be a comprehensive platform.
I think he misses one of the important points of comparing JS with assembly. Not only is assembly unportable, it's hard to read and hard to write for a human being. People use languages like Coffeescript not necessarily to deal with portability, but to avoid the quirks of JS that make it hard to read and write.
I'm sure the quirks can be dealt with given enough time and energy to climb the learning curve, but some people just don't want to spend energy on it when they can learn another language. I, for example, don't deal with JS daily and can't remember those quirks by heart.
I would appear to be Erik Meijer: JavaScript is an assembly language. The JavaScript + HTML generate is like a .NET assembly. The browser can execute it, but no human should really care what’s there.
"JavaScript is web assembly" is actually a bastardization of "JS is web bytecode." And really, that's just shortcut for saying it's the closest thing we have, but in many cases, it's good enough and it's certainly better than nothing.
This would be a lot more interesting if any of the conclusions it draws were remotely cogent, except that JavaScript is Not Web Assembly, and that it is (kind of) like C.
The to-JS languages are nothing like C++, you just don't need to compare in this way, these things are apples and oranges.
The JVM is more like the assembly target of the web, and it's a horrid failure in security and stability. Maybe some folks should start anew with something like LLVM as a target, with the first conversations about security. That would probably suck too, though.
Things don't have to be the Things of Things. That's what we should take away from this.
If JavaScript is more like the C of the web rather than the assembly of the web, then what can be considered as the assembly of the assembly of the web ? Or is this an invalid question to ask ?
In many languages, C is the output of the compiler. C's treated as portable assembler. I think that's the proper analogy here. Those languages don't have something lower-level than C.
His biggest argument is that CoffeeScript isn't run on "multiple architectures". However you could consider multiple browsers to be "multiple architectures". While this isn't super common, it's entirely possible to have CoffeeScript/Foo to compile to different "builds" of JS -- one that gets loaded in modern browsers, and another that gets loaded in older IE where built-in ES5 functions aren't available.
> If you are designing a language, compiling it to JavaScript is a pretty attractive option, for much the same reason that compiling C to machine code is an attractive option: running it in more places.
This sentence badly written. The point of the article is that Javascript is the C of the web, and if this sentence were put together correctly it would make the point.
The author claims that C has "an order of magnitude more expressiveness" than assembly with no basis for the statement, but ok. He then throws all the "compile-to-JS" languages together even specifically mentioning Sibilant which has macros.
If there is another 10x expressivity gain to be had by adding any language feature then surely macros are it.
Seem to be getting a lot of downvotes here, is there something in the article that I missed?
I don't see if there's any reason it would be impossible to build a compiler for a very high level expressive language like say Haskell and have it generate javascript code that would be well optimised for a particular runtime (maybe via asm.js).
The article seems to make the argument that javascript is not analogous to assembler because coffeescript is basically just syntactic sugar.
Argument 3, "You still need to grok the DOM, or node, or whatever other platform your program is interacting with, and that’s probably documented in JavaScript." is especially weird because I don't see how that isn't true with assembler also.
Asm written for Windows is going to be doing different stuff to asm written for Linux.
I don't think that's necessarily true.
Sure installation puts up a higher barrier but you can probably overcome that by making installation easy (app stores etc) and making sure you have plenty of videos & screenshots on your site to make the game look appealing.
I have a feeling that people place a higher value on games that they install anyway (I know I do) and may be more likely to replay it if it's in their Steam list or has an icon on their desktop. Whereas flash games are often seen as pretty disposable.
I imagine 99% of the time that metaphor is made the author would be just as happy saying "JS is the new C", it simply doesn't roll off the tongue as well.