CoffeeScript (http://coffeescript.org) is my attempt to solve this exact problem. Take the parts of JavaScript that work well, fix the broken areas (statements-vs-expressions, variable scoping, difficult prototype chains), add features (like the array comprehensions mentioned in the article) ... and compile it all to lowest-common-denominator JavaScript that runs just as fast as the JS-you-would-have-written-yourself, and runs just fine from V8 to IE6.
If you want JS with nice features, and not to have to worry about JS language support, do yourself a favor and check it out.
I like CoffeeScript, but what does it have to do with Eric's complaints? It does nothing to prevent people from duplicating effort or tying libraries to a specific environment.
Eric complained about implementation-specific language features in JavaScript -- things that only run on some, but not all of: SpiderMonkey, V8, JScript, and Nitro. To quote:
Instead of coding in one language, we're actually coding
in two. One is the subset JavaScript that can be run in
all browsers, and another is the set of JavaScript that
can be run by Node.
He's not talking about features specific to the Node API, but to features present in V8 that are lacking in older versions of JScript, effectively. A lot of Node libraries use features like Array#forEach, Object.create, Array#indexOf, Function#bind, making libraries unusable in the browser, even when they should be able to run perfectly well there.
CoffeeScript doesn't prevent you from using implementation-specific features if you want to, but provides in-language alternatives to all of the things listed above, in a cross-browser fashion.
Objective-J works in the same way, doesn't it? It's possible to write Objective-J code that is tied to a particular runtime, but if you write in the regular style, you won't have any cross-browser trouble.
When he said "language" I guess I automatically translated that to "APIs" since that's usually what people mean when they complain about incompatibility in JavaScript environments.
Differences in the JavaScript language in engines are fairly minimal these days (BTW all the features you mentioned can be added to legacy engines, see http://github.com/280north/narwhal/blob/master/engines/defau...) I think the bigger problem with sharing code between client and server is the libraries that unnecessarily tie themselves to APIs specific to each environment (i.e. the DOM and other browser APIs, and Node.js or other server-side APIs)
First -- your global-es5.js module is awesome. I frequently point folks to it for a way to bring old browsers up to speed. But at the same time, if you don't include a library like it, you have to admit that there are 30 core functions in there that it's easy to depend on, and that the global-es5 implementation isn't perfectly compatible with real browser implementations, it's just very close (Object.getPrototypeOf being a good example of something you can't fix).
The other approach, and the one that Eric is lamenting, is writing lowest-common-denominator JavaScript. The problem he calls out in Node isn't that it's not possible to write cross-implementation libraries -- but that people aren't doing it. There are tons of Node libraries which could very easily run in the browser, but don't. Just browsing through NPM, here are three random ones:
I don't know if it matters per se, but I'm in IE7, and while the 'run this code' demos work on the site, almost nothing else does. Specifically, none of the buttons in the floating toolbar do anything.
Also, I can't read the first paragraph of text, as the toolbar is hovering over it.
While it's quite embarrassing in regards to this conversation, zero effort has gone into making the homepage render properly in IE. The language is quite another matter. After working around IE bugs all day, getting up motivation to tackle them for the homepage of personal project is difficult -- you want to draw a line in the sand, and say, not this time. But you're right, of course.
Oh no, I understand completely. If my personal homepage works in IE7, it's a fortunate, but unintended happening altogether.
That said, I was very interested in CoffeeScript as part of my job is to write new whiz-bang features into applications that run on older browsers (such as the IE7 I visited you on today.)
Bear in mind, CoffeeScript especially appeals to people in my position. It just sucks I can't read it / play with it now.
Still, I've bookmarked it for later reading from home, so hopefully I won't forget.
I've pushed some CSS tweaks for IE to CoffeeScript.org -- it still won't look real pretty, but everything should be usable now. Should have done it a long time ago, thanks for the nudge.
They work like a champ, though I basically got what I wanted out of it last night at home.
Any idea how far away you are from putting out something one might consider 'stable'? I'm in the government, and it's effectively impossible to use 'beta' code here.
The language syntax is pretty much stable at this point -- getting to 1.0 is now mainly a matter of shaking out the edge cases in parsing, and solidifying the compiler as much as possible.
Fortunately, you don't have to take my word for it. Even if the CoffeeScript compiler were to disappear in a puff of smoke this afternoon -- you'd still be left with pretty-printed, quite-readable JavaScript. It's not like depending on a beta of a VM or interpreter.
There are lots of things that it would be wonderful to fix, but can't be done without either patching native objects, running an interpreter on top of JS, or adding lots of special functions in a required library.
Take, for example, negative array indices. It would be lovely if JS allowed you to say:
array[-1]
As an alias for
array[array.length - 1]
Unfortunately, we can't add the feature because you'd have to intercept "[]" at every call site. For example:
a[b]
Is a an array or an object? Is b a string or a number, and if so, is it negative? You just don't know at compile time, so we don't support the feature. This is just one example of something that would be nice to fix about JS, but can't be done cleanly -- there are plenty of others.
Sorry, I accidentally downmodded you, so went through your comments and upvoted some to cancel.
(Using Epiphany browser for the first time today, and it seems to offset the upvote/downvote arrow links so that you have to click above the upvote arrow to upvote. Clicking the upvote arrow itself downvotes. Maybe this is a problem with its text zoom feature...)
If you want JS with nice features, and not to have to worry about JS language support, do yourself a favor and check it out.