Mr. Schlueter is right on -- C++ is a much more accurate comparison, and especially so because it was originally implemented as a cross-compiler into C source code (circa 1983-1990).
That said, saying that the desire to compile into JavaScript is (to paraphrase the post) pathological language-wank craziness, is a bit extreme.
I'd like to think that the reason why CoffeeScript has caught on like wildfire, when there are so many other AltJS languages out there (https://github.com/jashkenas/coffee-script/wiki/List-of-lang...) is that we're trying to take the deeply pragmatic approach.
Mr. Schlueter writes "you don’t compile it to target a given platform," as if this would be an advantage or a justification for existing ... when it's really quite the opposite. JavaScript is plagued with libraries that will only ever run on certain platforms because they opt-in to platform specific features. I can't use your simple pluralization library to turn "bit" into "bits", because it was only written to run on Node.js, and is riddled with `forEach` and `require`, or because it was only written for the browser, and hides data in the DOM.
CoffeeScript tries very hard to compile into efficient, lowest-common-denominator JavaScript (read avoid Internet Explorer bugs) because that's how your library can be used widely across devices and runtimes, while being reasonably future proof.
I don't know when "order of magnitude difference" became a synonym for "worthwhile difference", but ... how much easier does a program have to be to read and write before it becomes a worthwhile choice to make the change? 2x? 1.3x?
In any case, CoffeeScript is a little thought experiment -- not a corporate project, or a Dart-like browser takeover. If it suits your fancy, use it, and if it itches you the wrong way, by all means leave it out.
The desire to compile into JavaScript is not what's being criticized here; it's the "blah is to JS as C is to Assembly" analogy: "That’s not to say that any of these systems are bad, just that the “blah is to JS as C is to Assembly” analogy is wildly wrongheaded."
Trying to treat JavaScript as assembly is silly because it doesn't vary too much between browsers- it is palatable to write, by hand, cross-browser JS programs, whereas it is literally impossible to do so in assembly because different assembly languages, as human-readable machine code, have virtually nothing in common at that level.
Treating JavaScript as C is the reality, because JavaScript is what gets run in different browsers (the analogy to compiling C to different platforms).
CoffeeScript is more like C++ than C because the language it's replacing/augmenting/etc. is very similar semantics-wise- it's just trying to make the same basic idea nicer to work with. The 10x difference thing is pointing out that C->assembly is a massive translation, whereas C++->C, while still a worthwhile difference, is much smaller.
Again, this is not a value judgement of CoffeeScript or GWT or anything. It's pointing out a flawed analogy. This is useful because when we think of JS as C rather than Assembly, it becomes clear that it shouldn't be the only option. It would be an improvement if, in the future, more mature language compilers could bypass JS to some form of bytecode (be it browser-specific, which would be a much bigger problem in the browser world, or a standardized one like the JVM does for the non-browser world... this is where the analogy breaks down a little).
A compiler that did an 'identity compilation' on a strict subset of real JavaScript, and rejected any problematic or confusing constructs would have value.
CoffeeScript goes further than that and provides different syntax.
One of the things that complicates C++ is the requirement for source code compatibility with C. This necessarily requires preservation of confusing quirks.
CoffeeScript is not source code compatible with JavaScript.
A compiler that did an 'identity compilation' on a strict
subset of real JavaScript, and rejected any problematic
or confusing constructs would have value.
It would. But it would be a linter, not a compiler.
It would only be a linter if it weren't a compiler. If it compiles language X to language X, it's a compiler. Because it compiles. Rule of thumb: if it compiles, it's a compiler, not a linter. Simple. Like ducks.
Correct. That doesn't make CoffeeScript->JavaScript like C->assembly. In fact, it supports the idea that it's like C++->C. C++ provides stronger type checking than C and provides different syntax for things like constructors, heap allocation, etc.
Mr. Schlueter writes "you don’t compile it to target a given platform," as if this would be an advantage or a justification for existing ... when it's really quite the opposite.
I don't know when "order of magnitude difference" became a synonym for "worthwhile difference"
I didn't see Schlueter arguing either of these things, but we may have read the post differently. Both points, in my view, seemed only to illustrate that the JS-Assembly analogy is wrong, not to argue against to-JS languages.
Okay, I'll give you #2 after that. And I'll point out that asking for a 10:1 difference in expressiveness from JS is, let's face it, ridiculous. (Except in specialized domain applications perhaps.)
If I recall correctly, Scott Hanselman raised the Assembly analogy in a post linked from this thread: http://news.ycombinator.com/item?id=2783060 . While discussing the unreadable JavaScript behind Google+ and similarly large-scale sites, Erik Meijer said
"JavaScript is an assembly language. The JavaScript + HTML generated is like a .NET assembly. The browser can execute it, but no human should really care what's there."
JavaScript generated by CoffeeScript is very readable and thus does not exactly correspond to that concept of JS-as-Assembly.
I don't think creating a new language just to compile the source to Javascript is a good move, especially when Javascript is being under heavily supervised & supported by a huge web development community. If Javascript isn't that expressive or weird, fine, why don't we just fix it or find another replacement? I find myself is comfortable to work on a language that's close to the platform than fancy languages that try to hide/fix trivial problems and take away other good aspects of the language. There are enough languages to learn already and CoffeeScript is probably fade away once these[1] kind[2] of stuffs[3] become stronger.
Regarding performance, have you considered CoffeeScript that generates JavaScript with (@JSDoc) type annotations that would allow Google's "Closure" compiler to further optimize and type-check the generated JavaScript?
CoffeeScript has its own optimizations and error checking, but type annotations would allow you to also leverage Google's continuing improvements to the Closure compiler.
ClojureScript supports a feature called Browser REPL. The compiler REPL compiles your code to JS and sends it to the browser for evaluation which sends the result back. This means you can develop w/o restarting the browser or ever leaving your source file while incrementally developing your project.
At the moment it works best in Emacs, but people are starting to add support for other development environments.
After developing JS this way going back is simply painful.
Is the only difference between the ClojureScript REPL and Firebug/WebInspector (for JS) that I get to keep using my editor? I mean, you can already do JS at the REPL without reloading the page.
fwiw, I'm an Emacs user, Lisp geek, and huge Clojure fan. I see the benefit of this, I'm just curious if not leaving my editor is the only advantage or if I'm missing something else.
I think you misunderstood. I can already pull up a REPL (that's running code on the current page) and write/paste as much JS as I like into it without ever refreshing.
So is the fact that you get to stay in Emacs the main selling point? Like I said, I'm just trying to understand.
Yeah, I think you're right, the REPL itself isn't revolutionary, although I felt as enthusiastic as the op when I discovered it existed. Then I tried to use it.
It's alpha quality, breaks and has to be restarted quite often. And a large part of webapp dev is testing code that is inaccessible from the global scope because of architecture (module pattern, etc). There is some magic however for dynamically loading Google Closure Library code that it wasn't compiled with, but I found setting up correct paths to include my own ClojureScript files to be tricky, especially doing so when targetting platforms with their own particular architectures (eg CouchDB/Couchapps).
That said, I think the op made a very good point about ClojureScript producing code that one would never write by hand. It's really the Clojure/Lisp idioms that are the win. The REPL an accessory, and a nice one, even moreso once the rough edges have been smoothed over.
You can switch namespaces by eval'ing the ns form in your file after starting the REPL. Agreed there are lots of rough edges. But even with those I am able to code / test faster than w/ plain JavaScript or CoffeeScript.
There are definitely rough edges, but the potential is immense. By the way, a recent patch stops alot of the break->restart issues (specifically, syntax errors don't boot you out anymore).
He was also comparing to CoffeeScript, and sadly there's no way to do it there. This is the one feature that keeps me from using CoffeeScript, the lack of REPL integration--I have no idea how other people do without MozRepl or SwankJS or something homegrown. If I don't have something akin to Slime for emacs, it really frustrates me. I assume I'm not that smart or extra lazy.
I question your use of "only" able to use your own editor. There are myriad problems with using Firebug to write your code in: It doesn't save your code so if the browser crashes or hangs (which happens all too much with my installation of Firefox) you lose it; if Firebug starts behaving wonky (again, happens all the time) you lose it; you have to copy and paste the code into your editor once it's done; and, the editing mode itself is awful, of course. This is, as opposed to, say, MozRepl, which is instead convenient and safe. I assume the ClojureScript environment is as nice or nicer.
FWIWI, it's pretty trivial to set up hooks in Emacs to automatically refresh a page after you save each JS file. Or better yet, send it straight over the wire via MozRepl. I find "massive time sink" a bit hard to take seriously.
What kind of performance hit does ClojureScript come with? I imagine there's a lot more of an impedance mismatch between Clojure and JavaScript, especially since you presumably only use immutable objects and arrays.
ClojureScript adopts some of JS semantics like the numbers. Like with Java you can use nativ arrays if you really need to. ClojureScript has an implementation of Clojures immutable Data Structurs this are slower then nativ objects but should not be the bottleneck in most applications.
The great thing about ClojureScript and performace is that ClojureScript get piped threw the google closure compiler with does dead-code elimination and some other optimizations.
I have not written any big enought app in ClojureScript that I could really tell but if you look at the compiler output you'll be surpised how little there is.
Sure before Google Closure takes an optimization pass at it. Anyways, I don't really think it's a point worth debating to death - I defer to Erik Meijer.
This is a stupid debate over language. What people mean when they say Javascript is web assembly is that Javascript is a compilation target, which is completely true.
Absolutely. I never heard anyone actually say “blah is to JS as C is to Assembly” nor did i take them to mean that when they said "Javascript is web assembly"
I have to admit that I just don't understand the value of this discussion. Regardless of whether JavaScript is like assembly or C or C++ or MSIL or punch cards, I'm pretty sure all of us have heard of cross-compilation and that many of us realize the value of targeting the installed base (which is why we supported IE6 during the dark years).
Cross-compiling a language designed to address JavaScript's numerous flaws into a safe subset of JavaScript for wide deployment seems like one of those ideas that we already have a noncontroversial word for -- polyfill.
Prediction: Someone writes a CoffeeScript to Dart cross-compiler.
I don't think he'd be surprised. Didn't C++ initially compile to C? He mentioned how these "to-JS" languages are more like C++ to C than C to assembly.
C++ only briefly compiled to C, but compilation-to-C is a time-honored compiler building trick.
It's not always reasonable to make inferences about the quality of a programming language by reasoning about its compilation target. It's probably never reasonable when you're talking about compiling-to-C, which is basically a macro assembler.
I can't seem to find the discussion now, but the C-- people (http://www.cminusminus.org/) found that compilation-to-C was a requirement from some large companies, at least as a backup path, for anything not solidly established. Companies wanted to know that if this fancy new thing's maintenance dropped off a cliff in 10 years, they could at least compile to C, and thereby leverage C compiler ports to new architectures, rather than depending on a straight-to-asm path that may or may not be maintained decades from now.
Not even briefly, I'd say. Cfront-based compilers were the rule rather than the exception well into the 1990's. It wasn't until the death of proprietary Unix and the emergence of msvc and gcc that the world got used to the idea of C++ being a first class language.
So C++ had existed for 10+ years by the time you started with it, right?
I was still having to deal with Cfront-based compilers (the one on HP-UX, for example) in 2002 or so. Amusingly enough, it actually had really good error messages.
I know he knows C++ targets it, but I get the impression he thinks that the result of targeting C is a language like C++. That's not the case. Good languages have also been compiled to C.
I know it's just an off-hand little dig at C++, & I'm sure you know more than enough about C++ to be confident making such a dig, but damn the relentless C++ bashing gets really old to those of us who are happily productive with it.
Technically speaking the article is correct: "JS is the assembly of the web" can seem misleading if one means assembly as "machine-specific code".
But "JS is the assembly of the web" is correct in the sense it is normally meant, which is "a language that you can compile into as opposed to writing directly for."
We are seeing that today, as the list of languages compiling into JS grows, and begins to resemble the list of languages compiled into assembly. Whereas the list of languages that compile into say C is much smaller.
So it is still a fair statement to call JS "the assembly of the web", at least as long as we understand what we mean by that.
Whether or not javascript is analagous to assembly language, I find 'compile to javascript' frameworks such as GWT, GWT-Ext, Vaadin and Thinwire very compelling to use and allow for a consistent and cohesive presentation layer in rich web apps. Unfortunately all of these great platforms are Java based and I would really like to see the same approach adopted for other languages.
Some people just don't like writing plain javascript, myself included. But then I do generally develop UIs which more or less behave like desktop applications, so the value of being able to plug in a few preset components is much more attractive, if I wanted a very customised feel to the components I used I guess it would have to be native javascript.
The idea that debugging tools should determine how Javascript is generated or written baffles me. It's only been over the past few years that we've had any credible Javascript debuggers. The debugger builders will adapt to whatever the developers use. The horse pulls the cart.
I think a major step in the development of complex javascript apps was the development of real debugging tools for Javascript. Prior to that, the barrier to a complex JS app was too high for the hobby developer.
It seems logical that developers will prefer a language that has a good toolset. There are certainly languages I don't develop in as much due to the lack of a compelling debugger (e.g., Lua).
In the case of Javascript though, I don't think many developers were asked if they liked it ahead of time. Really it seemed like it was targeted for the much wider audience of "latent developers" who'd never used a debugger at all and wouldn't know to expect one.
This probably contributed to why it took so long for such debuggers to arrive.
The solution to this issue is already arriving — source maps. They're already supported by Closure (which, incidentally, is part of the ClojureScript compiler toolchain), and Mozilla and WebKit have it on the roadmap for their respective projects.
The browsers are working on a generic solution by providing a way to set source-to-compiled line mappings for the debugger.
Even without special support, depending on the compiler, sometimes it's not particularly hard to debug unless you're really not familiar with JavaScript. I don't think it's as big of a deal as people make it out to be.
.. so he likes CoffeeScript? I'm not sure I grok the complaint or general message of the blog post. I've never actually heard "Assembly of the web" in relation to JavaScript. A link to earlier discussions that sparked this post would be useful, because I think there might actually be a takehome point in there somewhere : )
And assembly is just abstracted bytecode in a certain syntax.
It's rad that you're totally into CoffeeScript, but splitting hairs like this is silly. A lot of the metaphor comes from the fact that JavaScript is actually compiled down to assembly in software like v8. X to JS compilers can even take advantage of that knowledge as well and produce optimized JS for those compilers (I'm sure GWT leverages this) So yes, JavaScript is more like C in that sense, but C compiles so ridiculously close to assembly that it's practically just there to make system calls and memory management easy for you.
So, if anything Javascript is the common language of distribution, or the English of the web.
Over-simplifications and over-generalizations are ones enemies rather than friends. We didn't say that Visual Basic is an assembly language of an office or AutoLisp is an assembly of construction business.
Repeat after me: Javascript is just an in-browser scripting language. Period.
Yes. I know, it is possible to use JS on a server side, but you also can hack a VB run-time to send you some files via http. Wait, isn't that crap already exist and called Azure?
Assembly = "as low as you can go". You can always build things on top of it, but you can never go any deeper. Javascript shares that much. Not too much else.
JavaScript is more or less a (potentially standard) language runtime, just like JVM or CLR--just more compatible and more widely and natively supported. I don't see the need for a strictly binary or bytecode runtime either since parsing and interpreting/compiling JavaScript further inside a browser or other native environment is "fast enough" for many definitions of fast. Certainly faster than booting JVM :)
What would be very interesting to talk about (instead of entering into the details of an innocent analogy) is a toolkit that would make very easy to create new higher level languages on top of JavaScript.
Unfortunately, JavaScript and its VMs have limitations that would not allow us to create very performant languages for some domains but I think we could have a lot of other useful higher level language to program (the web).
I have an issue with the general premise of this article.
Who is saying that javascript is web assembly?
I've only seen one comment in the comments so far, and its weak at that. Yes no human can read Google's javascript, but that says nothing about its efficiency, optimization, or correspondence with machine language. http://news.ycombinator.com/item?id=2783060
I agree. The point of the original statement was just to show that you should be compiling to javascript, not writing javascript. This article is technically right, the original comparison isn't perfect, but it is really splitting it fine.
I'd like to respond to a few of the comments here.
Jeremy imagines correctly. This blog post was essentially a continuation of the subject on the node mailing list, and particularly the assumption that if you feel you shouldn't compile to JS, then you should just write in Assembly, or that JavaScript is only worth using if you want to be "closer to the metal". I believe that these points of view are wrong.
Yes, of course I'm aware that C++ was originally cross-compiled to C. That's why I chose it for the analogy, like Lassie on display in the Louvre. People tend to take comparison that as either a compliment to CoffeeScript, or an insult, depending on their feelings about C++ vs C. I consider both interpretations to be correct.
I have no problem with people compiling to JavaScript, though I personally prefer dealing with JavaScript directly. I like stack traces with line numbers that correspond to the line numbers in my editor, and it's not such a bad language. One of the biggest things I've found lacking with both Node and Browser JS is post-hoc debugging. Syntax sugar doesn't help with that. I'd be much more excited about efforts to produce state-capturing crash dumps that would let a developer revisit an error condition and investigate it after the fact. Other language have this, and it makes me very envious.
"Expressiveness" is a measure of how many tokens are required to write programs. Read some of pg's essays about arc and blub. A less than 10x increase would still be relevant, but.. well... meh. It's not a major leap in power that Assembly to C is, or C to JavaScript is.
Increases in expressiveness often come at the cost of also increasing the difficulty of reasoning about programs' precise behavior, but increase the ability to reason about their intent. Reading assembly isn't exactly fun (in my opinion), but it's also quite clear exactly what the computer is doing -- so much so that it can be tricky to figure out exactly what the human was trying to accomplish.
C is much more humane, and still pretty clear what's going on. It's an obvious sweet spot for many tasks. JavaScript, on the other hand, runs on this huge black box, but it's much more expressive than C (and thus, much easier to write), and it runs in web browsers (which makes it inescapable), doesn't require a compilation step, and is quite fast for a lot of tasks. I've yet to see any similar leap from a to-JS language. They're just other high level languages that all have pretty much the same basic set of features. A lot of them are a bit nicer than JS, but they lack JavaScript's relevance factor.
I must not be a very good writer, because people often read things I write, and seem to come away with the impression that I have these strong prescriptive views about syntax and coding style. I don't. The reason I'm so unenthused is because most high level languages don't really seem to differ all that much. Coding style doesn't solve very many problems, and the problems it does solve aren't particularly hard.
This whole thing is weird (and stupid). I listened to the Hanselman interview with the guy who started pushing the concept of JS as Assembly. He came across to me as being really confused. He seems to conflate the concept of a .Net assembly, with "assembly language". I got the impression he had never written anything in assembly language, and didn't understand that it's a minimal mnemonics + macro layer over actual byte code, not something highly portable, and not something that "assembles" components together.
JavaScript is the new universal web glue language. This is great, as is the fact that people are developing better-abstracted languages which compile to JS. But it's not any sort of "assembly language" unless you employ really confused semantics. I take issue with this for precisely the same reason that I take issue with using "Cloud" interchangeably with "Internet" or "Website".
The problem with JavaScript targets is not the terminology, but how bad the design of the whole web stack is. It's like watching people badly redesign operating systems in the browser, every so often catching up to something that was solved 20+ years ago on the desktop. Painful.
Mr. Schlueter is right on -- C++ is a much more accurate comparison, and especially so because it was originally implemented as a cross-compiler into C source code (circa 1983-1990).
That said, saying that the desire to compile into JavaScript is (to paraphrase the post) pathological language-wank craziness, is a bit extreme.
I'd like to think that the reason why CoffeeScript has caught on like wildfire, when there are so many other AltJS languages out there (https://github.com/jashkenas/coffee-script/wiki/List-of-lang...) is that we're trying to take the deeply pragmatic approach.
Mr. Schlueter writes "you don’t compile it to target a given platform," as if this would be an advantage or a justification for existing ... when it's really quite the opposite. JavaScript is plagued with libraries that will only ever run on certain platforms because they opt-in to platform specific features. I can't use your simple pluralization library to turn "bit" into "bits", because it was only written to run on Node.js, and is riddled with `forEach` and `require`, or because it was only written for the browser, and hides data in the DOM.
CoffeeScript tries very hard to compile into efficient, lowest-common-denominator JavaScript (read avoid Internet Explorer bugs) because that's how your library can be used widely across devices and runtimes, while being reasonably future proof.
I don't know when "order of magnitude difference" became a synonym for "worthwhile difference", but ... how much easier does a program have to be to read and write before it becomes a worthwhile choice to make the change? 2x? 1.3x?
In any case, CoffeeScript is a little thought experiment -- not a corporate project, or a Dart-like browser takeover. If it suits your fancy, use it, and if it itches you the wrong way, by all means leave it out.