* Javascript has some warts, and here are some examples.
* It's going to take way too long to get these fixed to the point that we can actually start using new versions of Javascript because of slow browser adoption.
* To get around this problem, people are treating Javascript as a compilation target for other languages, the most prominent example being CoffeeScript.
* Discussion follows of features that would make Javascript better serve its increasing role as a compilation target.
* There is discussion of Harmony throughout.
Sometimes offering a TLDR indicates that the article isn't worth reading "so here are the author's points so you can skip it". That's not the case here. For example, I learned about "Tennet's Correspondence Principle", which helps to give a name to the different ways procs/blocks and methods/lambdas behave in Ruby, as explained in this article[1].
[1] http://www.robertsosinski.com/2008/12/21/understanding-ruby-...
That might sound a lot like Java, but it can can use some fresh thinking. I'm quite excited about NaCl on this front, for example.
Which isn't true, because you could compile newer versions of javascript to older versions. I see languages like coffeescript as interesting experiments in how the language can evolve, but eventually it needs to come back home to javascript and get deployed natively in browsers.
Mozilla introduced this back in Firefox 2, and you can replace var with it, so TFAA's
for (var i=0, ilen=elements.length; i<ilen; i++) {
var element = elements[i];
let (num = i) {
LIB_addEventListener(element, function(event) {
alert('I was originally number ' + num);
});
};
}
becomes: for (let i=0, ilen=elements.length; i<ilen; i++) {
let element = elements[i];
LIB_addEventListener(element, function(event) {
alert('I was originally number ' + i);
});
}
Of course, since this does not quite seem to be a tight loop you should be using Array.prototype.forEach instead: elements.forEach(function (element, i) {
LIB_addEventListener(element, function(event) {
alert('I was originally number ' + i);
});
});
> The JavaScript idiom that potentially spans the most lines of your program may be the inheritance idiom.That's not an idiom. And there are numerous implementations of classes on top of prototypes out there, if there's one javascript "problem" which does not need new syntax it's that one.
Maybe we should give more attention to the basic process behind this, creating libraries aka Programming Motherfucker.
Theoretically maybe, but I've yet to see that. A regular `for(;;)` is generally 3-5 times faster than using `Array.prototype.forEach`.
Re. JIT, hand-rolling a foreach in javascript can be up to twice as fast as the native one, depending on the features you leave out.
Since JavaScript will still invoke a function call even if the number of arguments don't match up, parameter defaults will not completely eliminate all the problems he lists.
function(a = 1, b = "Smith", option = {}) { .. }
Will still break upon trying to invoke it without parameter 'b' since param 'option' will just take its place while option will become an empty object.Furthermore he argues against "option = option || {};" only to do the same thing in the function header: "function(a, b, option = {}) { .. }"? What difference does that make?
The whole section in my opinion is negated by passing object literals to functions. Stuff like:
func({ a: 1, b: "Smith", option: { .. });
That makes it easy to read and easier to handle since names are agreed upon by both the caller and the function handling the invocation: var opt = config.option || {};
This is a common practice in JavaScript already, and it beats the solutions he wished were added to the language.As to the "option = option || {}", he was referring to the ultimate "option = {}" assignment if you passed a falsy value (0, "", false), which is different than if you didn't pass a value (undefined). Which is resolved by "option = option === undefined ? option : {}", which is even larger and kinda ugly.
EDIT: Unless of course you get some non object value passed in and you want to be sure to keep it regardless of whether or not it is falsy. Not sure why you'd want to do that -- I am sure I would NOT like to see someone do that if I had to deal with their code.
GWT could be really strong. But it's this single maintainer problem that I think prevents it's penetration into the market.
Sadly when I hear people talk about the "strengths" of GWT, debugging and IDE debuggers is what I hear most. If that is the core reason for using GWT it seems shortsighted.
And for me personally I find that using Java (static typed system) to compile down to JavaScript (dynamic function system) is too big a paradigm switch for developers to maintain. Other languages, specifically functional type languages are far better for maintaining language paradigms in compiler situations.
I think the only way to defend against that is to have an open source project, and to have a sufficiently large user base such that someone is sure to take over if the owners drop the project.
I think the strength of GWT is that for some languages/teams, a statically typed language is more appropriate than a dynamic language. And isn't more choice a good thing? Avoid the whole 'this is a hammer, everything else is a nail' approach?
I do agree that some teams choose GWT for inappropriate reasons though.
I would only respond with that in particular, GWT is more than a compiler - it is as much a JRE as anything. So there is more to it. I personally don't see Google doing much public interaction with the development of the GWT compiler. If it's left to Google and its own time then my point remains.
JavaScript on the other hand really doesn't have a single organization leading it's development. Maybe this is an argument to be made about its perceived slow progress. Language design by committee is pretty slow.
More choice is good. Always. But right tool for the job should always win.
Disclaimer: I've done GWT and I liked it.
I did not find any Java<->Javascript paradigm shift problem at all. You simply forget about the Javascript and just write Java.
The big benefit of using GWT over writing 'native' javascript is that you get the same behaviour on all browsers.
The big benefit of using GWT over using other java based web frameworks is that GWT moves the client's state down to the client, where it belongs.
If you look at most other Java web frameworks like that (e.g. Struts and it's direct competitors), they expend enormous effort porting data to and from the client, and trying to hack around the limitations of the HTML post operation - namely that blank values aren't returned (checkboxes!!) and that everything is passed as text (numbers!!). So what these other frameworks do is they end up making you write all these model objects, and then try to simulate the client state. JSF is the worst of these as it takes it the furthest, they're not just emulating the model, but also the view as well with their overly-complex de-hydration and re-hydration of components.
If you tell the client state to bugger off back to the client where it belongs, you save a good 30-40% of your typical web framework effort right there.
Eliminating Javascript browser/version idiosyncrasies saves you another 20-30% of your effort (more if the UI is very dynamic, less if it isn't).
-----
I think you're posting on the basis of assumptions you've made based on what you've heard about GWT, rather than experience with it.
BTW an easy way to produce traditional class inheritance in Javascript is to have a single instance from the class you're trying to inherit from, as the prototype. (To work properly that object should be "abstract": have no ties to any physical resources, like a browser widget, a database handle or a file handle.)
I'm not sure why you're implying java's anonymous inner classes have much relation with class inheritance.
The vast majority of class-based languages do not have (or need) anonymous inner classes (though some languages allow for creating unnamed classes on the fly by instantiating metaclasses).
http://www.prototypejs.org/learn/class-inheritance
http://dojotoolkit.org/reference-guide/dojo/declare.html
Plus, I tend to prefer prototypal inheritance to classical inheritance. I do agree that the constructor pattern using the new keyword and the prototype object is a bit odd, but that's not the only way to have objects inherit from other objects in javascript.
Prototypical inheritance in the IO Language is a beautiful thing.
Not so much in Javascript.
Class based inheritance in Smalltalk and its dynamic mind-children Python and Ruby are similarly elegant and flexible. Not so much in C++ or Java.
The problem isn't with Prototypical inheritance, its with the implementation of it in Javascript.
1) Crummy syntax. 2) Everybody doing it a different way.
Q.each(arr, function(i) {
this.rocks();
arr.pop(); // watch out doing this in the loop
arr.push('foo'); // watch out doing this in the loop
});
Q.each(obj, function(k) {
this.rocks();
delete obj[k]; // should be safe maybe
});
var p = Q.pipe(crazy stuff involving pipes and callbacks)
doSql("SELECT * FROM users", p.fill('users'));
getUsers = Q.getter(getUsers); // turns it into a really smart getter
getUsers = Q.batch(getUsers); // turns into into a batched getter
and lots of other stuffWhy must the language take care of everything for you when libraries can do it? That has been the case with C, C++ and other languages.
My favorite languages are C, Java and Python though. So go figure...
Then you can use whatever java-like/basic-like/functional-like language you want, and have it compile to bytecode. Also, with sophisticated JITs for that style of bytecode already lying around, you could probably instantly beat javascript's performance even under the best engines, because of static typing etc. rather than relying on ridiculously complicated static analysis.
It'd have to be supported side-by-side with javascript for the forseeable future, but the earlier you get a change like this in, the better...
2. I don't think anyone but Microsoft would support .NET bytecode in the browser, simply because Microsoft controls .NET and has patents on it. It would take a lot more to reassure other browser vendors than Microsoft's existing CPs.
3. Running dynamic languages on Mono is slow. Look at the speed of all the dynamic languages on Mono (or the JVM for that matter), and compare them to native implementations of dynamic languages, in particular JavaScript and Lua. The native implementations beat dynamic languages on Mono by a large margin, simply because .NET is a bytecode made for static languages. Of course you can say that you prefer to have static languages in the browser over dynamic ones, that's a legitimate opinion of course, but not everyone would agree.
4. Standardizing on bytecode can inhibit innovation. JavaScript doesn't have a bytecode standard, which let JS engines implement very different ways of running it (V8 doesn't have a bytecode interpreter at all, for example). Of course standardizing on syntax also inhibits innovation, just in other ways, it isn't clear which is better.
5. Static languages compiled to JavaScript (that is, that use JavaScript as their 'assembly') are getting quite fast. Some benchmarks I ran found them to be around 5X slower (on the development versions of SpiderMonkey and V8) than gcc -O3, compared to Mono which is 2.5X slower, http://syntensity.blogspot.com/2011/06/emscripten-13.html
6. There is already Silverlight/Moonlight which does .NET in browsers, and it hasn't been very successful. (Of course it is a chicken and egg thing, if it were bundled in browsers it might be more popular. But the failure of Silverlight is a disincentive to add Mono to browsers nonetheless.)
For all these reasons, I don't think Mono has much of a chance to be included in browsers. Most of the same arguments apply to other static-language bytecodes like NaCl.
http://shootout.alioth.debian.org/u32/benchmark.php?test=all... <- That still looks sort of far to me.
>> 3. Running dynamic languages on Mono is slow. Look at the speed of all the dynamic languages on Mono (or the JVM for that matter), and compare them to native implementations of dynamic languages, in particular JavaScript and Lua. The native implementations beat dynamic languages on Mono by a large margin, simply because .NET is a bytecode made for static languages.
It's not fair to compare JavaScript, which is already approaching a limit of how fast it can go, with the speed it gets running in Mono. Why? The two implementations have a vast difference of amount of energy and resources thrown at them; had Google, Mozilla, and Microsoft wanted JS to run fast on Mono, it would run fast on Mono.
Also saying that .NET is a bytecode made for static languages is kind of iffy now that the "Dynamic Language Runtime" is a part of .NET
Am I reading this right? Objective-J (2008), C# (2001), HaXe (2005), etc having compilers to javascript in 1997?
Mobile processors are still slower than desktop ones, of course, but JavaScript on mobile today is already faster than JavaScript on desktop just a few years ago. For example, the benchmarks on http://arewefastyet.com/ show V8 running only about 5x slower on an nVidia Tegra 250 ARM board than it does on an Intel Core 2 Duo Mac Mini.
Googling around, I see tons of misuse: Example of bad usage: "White Stripes are dead (long live white stripes)"
Example of proper usage: "Palm is dead; long live Palm!" (this would mean that Palm got acquired or reformed) "Paper is dead; long live paper!" (could be proper if used in an article about how paper for PRINTING is dead but paper lives on in other forms)
REF: http://en.wikipedia.org/wiki/The_King_is_dead._Long_live_the....