My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Thursday, June 14, 2012

Ranting About Racing Engines

Update ... regardless this rant is still valid ... I have updated for both Web and node my es6-collections following stricter currently available specs.

This is happening right now, or better, since this race started a while ago between alternative browsers and the idea of bringing JavaScript every-bloody-where ...

On Engines Fragmentations

This happens since ever in vehicles engines and we can all see the difference in themes of both prices and CO2 emissions. Every major car/motorbike engine manufacturer is competing against others.
N times the amount of money spent, N times the number of patents slightly different and potentially able to make better engines production slower/farer due patents lifecycle.
Almost zero joined effort ... same studies over and over with of course different solutions, and these are always welcome, but rarely a shared effort between teams able to bring the 0 emissions, ecologic and usable engine we are all dreaming about ( look at all these prototypes with batteries rather than gasoline ... look at the very first and only hybrid diesel engine, etc etc ... now ask yourself how long will it take before we can all afford these engines for real ... )

The Web Is Different ... But

Well, at least there are tons of groups trying to bring some Harmony between JavaScript engines.
I believe is still good that there are different implementations such V8, Nitro, SpiderMonkey, Chakra, Whatever ... but when it comes to the race, all these engines are adopting early versions of specs that are still under definition and this is bad 'cause ...

The Side Effect

Works only in Google Chrome is the very first side effect of this fragmentation and while earlier/faster adoption of most recent standards and drafted specs can be considered one step forward, the idea that a Web page works only in a single browser, and no matter which one is it, bring us back to year 2000 ... have we learned anything since?
Chrome Engineers are great and extremely fast, same is for all Webkit contributors, as well as SpiderMonkey and all other engines but if we find 2345678 different APIs that works inconsistently across all JavaScript engines I believe we are doing it wrong.
Here just a few examples:
  • W3C effort to bring more HW access through the Web
  • PhoneGap APIs to expose native access to JavaScript and Web Pages
  • webOS APIs to expose native access to JavaScript Apps
  • Boot 2 Gecko APIs to have HW access through JavaScript
  • ChromeOS APIs to have lower level access
  • Safari Mobile APIs not present in other mobile browsers
  • Opera and Mobile proprietary namespace ( really guys, please drop that window.opera thingy to start with ... )
  • Adobe APIs to interface Flash objects and JavaScript for Air or generic plugin content
  • newest ES6 APIs ... so cool, and so unstable at the same time ...
About latter point, I am unable to push my updated version of my es6-collections and I tell you why ...

The Curious Case Of Harmony Collections

Map, Set, and WeakMap respective prototypes are changing all the time ... oh well, this is a common side effect about adopting features that are under discussion on daily basis and not defined anywhere yet.
In any case, I would like to use the native constructor where available, and this is true for both Firefox (Aurora) and Chrome (Canary with enabled experimental features).
While updating my es6-collections code I have realized, after changing tests and implementing the desired behavior, that Aurora has a size() method that does not exist in Canary and that Map#set(key, value) does not return the value as it does in Canary.
Who is correct? Who is wrong? It doesn't actually matter because if these methods are frozen in the prototype, I cannot fix anything there and I need to create another subset with a different name in order to obtain a fixed and consistent version of these constructors across all platforms and most likely penalizing Aurora or Canary being unable to use respective native implementation ...

Why Native

Native is fast, native is good, native is the way to go and the reason we create polyfills: to be able to remove them once our current A grade target browsers support already this or that API and it works as expected and as fast as possible.
About working as expected once we deal with a native API ... I don't even want to start this conversation 'cause there are too many things to consider here ... my take on this is: don't fix browsers bugs unless it's IE that won't update automatically and only if IE is an interesting target browser for your app.
As easy as that ... if a browser vendor realize the gravity of a bug the team will fix it asap ... if we show easy work-arounds to a specific bug all over the place they won't consider that problem as a show stopper.
Even better, always file a bloody bug with proper description, a link to specs, and a use case that makes sense so that these guys can properly understand the gravity and what is this about ... OK? A bit more effort from the Web community itself about filing bugs can only bring a better Web for all of us.
In any case, if we cannot trust native behavior across platform, we need to create yet another boring library able to fix all these things for us ... and this is getting ridiculous, imho ... I don't want to re-fix the browser for every single native call I do from the JavaScript core ... I just would like to use the programming language and its native "things" and focus on something else, something more, something productive!
Today for a basic web page with a stupid form to submit, we add minimum 200Kb of fixes through any sort of "lightweight" library ... isn't it? Is this what the meaning of "JavaScript everywhere" is becoming day after day? If you don't use the library to fix native stuff you cannot do much?

Not Only JavaScript

You don't need me to tell you that the CSS world is even more messed up than JavaScript one ... and the reason is basically the same: fragmentation of rules and new features using prefixes all over the place which results in 5 times bigger CS with repeated things all over the place ... the most distunging piece of "code" ever in the Web history that ... needs to be fixed with libraries, again? meh is the maximum expression I have for this without being vulgar ...

What Can We Do

I have no idea ... and in my specific case, talking about es6-collections, I have to wait and nothing else. I have to wait in order to be sure one behavior is correct, while another one is not, and finally penalize browser A or browser B feature testing the inconsistency and throwing away native constructors in favor of shimmed one ... so that my tests, at least tests, will be consistently green across all supported engines/platforms.
Was my fault in first place to propose polyfills for something still that unstable and not properly implemented in these browsers developers channels? Probably yes, but many others are bringing few ES.Next things through libraries and polyfills so be aware that things might screw up without notice from a day to another one due automatic updates and if you don't follow all these libraries on daily basis you might find yourself in a situation where all your code needs to be rewritten ... and I guess none of us would like that much this situation ...

Shim The Spec

To avoid misunderstanding, polyfills for already official and approved specs are always welcome. This is the case of ECMAScript 5 or 5.1, as example, where things are not going to change any soon while everything related to Harmony and ES6, if the shim is even possible, should be categorized as "experimental, might not work, I knew it was going to break somewhere" ... and this is true even for what I am proposing with es6-collections: it's cool! ... and be careful, even if the shim you are using is not mine.

P.S. the current version has keys and values plus does not work with edge cases such NaN or -0 when it comes to Map keys ... the local version I have is green everywhere and implements specs properly so stay tuned if you want a closer ES6 version of these constructors API while start avoiding the usage of keys and values properties if you are using that code already ( about NaN and -0 I don't bother, I think using these values as keys is an error in any case ... however, next version will have a better indexOf to match NaN and -0 too so that specs, those we know today, will be respected, forcing the implementation to do not trust native Array#indexOf and its inconsistent result when it comes to those values that are not reflective).

Last, but not least, more than asking clarification in the ECMAScript group I could not do ... so, even filing a bug in this case is kinda pointless since I don't even know what to write there except that another engine does something different about something that's not fully defined yet: Math.pow(MEH, 31)

No comments: