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

Friday, October 12, 2012

All Right, Gentlemen!

... this is after my latest post, just to summarize with a bit of humor my thoughts on developers getting easily excited with new stuff :D

Once again, not everything is wrong with TypeScript, but this is how I have really felt as soon as I have heard about this yet another JS superset and after a quick analysis through examples.

better if deca



learn twice



a better web



without standards

Thursday, October 11, 2012

JavaScript Made Everyone Crazy

Nobody seems to be happy, nobody seems to understand it ... everyone is trying to change it, pretending to make it better ... and again, nobody seems to realize it has been here since ever, it has been working in any field, it does everything, and it keeps getting faster!

One Scripting To Rule Them All

As simple as that: Dart compiles into JavaScript so does Java, CoffeeScript, C, C++ and any LLVM compatible/compilable language via Emscripten ... and now TypeScript too ... how cool is that? As tweeted before, if every programming language can be basically translated into JavaScript which is already an extremely high level scripting language, don't ya think that maybe is not exactly JavaScript the problem ? Don't ya think maybe it's time to learn it rather than keep moaning about it ? Hasn't this language already demonstrated to be one of the most malleable, powerful, adaptable, reusable, recyclable, expressive out there ? So why everyone is trying to pretend this language is not good? Why everybody wants this language to be something nobody needed until now or something that different?

What Is Wrong With TypeScript

I don't know where to start here ... but I'll try to make few points based on examples, OK? Please bear with me, you'll get it too.

Type Inconsistencies

Ironically, this is the very first point. Consider these two functions:
// note that string is written lowercase
function primitive(s:string):void {
  console.log(s);
}

// note that String is written PascalCase
function wrapper(s:String):void {
  console.log(s);
}
Now, with this "revolutionary brand new language" I ask you two simple questions and you should be able to answer me without testing, OK?
  1. will this call produce an error? primitive(new String(""))
  2. how about this one? wrapper("")
The truth is: there is no way to enforce the usage of a wrapper ... a language born to put on a scripting language types, is not strict with types themselves. string accepts primitives only, those that typeof(s) === "string" but String accepts both primitives and wrappers ... so basically, the most basic problem about JS is still there and developers are not encouraged to understand the difference between new String and just "string", they will put String everywhere feeling like they know what they are doing ... they are using classes ... WOOOOOOOW! Even more funny is the usage of bool rather than boolean, so that even what you know about JS does not work anymore ... so I guess Bool would be at least available, right?
The name 'Bool' does not exist in the current scope
Exactly, Boolean is the wrapper for bool: congrats! What do you say? It was to speed up typing? ... that's why you wanted types, to write less? ... wait ... what?

Fake Security

If you believe that typed code means better code quality, you are wrong. Typed code usually means that the developer knows types in advance ... that's pretty much it. In this attempt, where code is not resolved runtime, only types are, the feeling you are safer than before is natural ... well, you are not
function wtf(s:string):number {
  return s.charCodeAt(0);
}
Above function contract is extremely simple for both input and output ... too bad TypeScript cannot do much when it comes to calling the function, understanding that maybe that input has no char in index 0 so that wtf("") will produce a lovely NaN able to screw the rest of the logic because guess what ... NaN is considered a number: congrats again, another problem kept with TypeScript! Anyway, the latter example shows that it does not matter if input and output types are OK, it matters the logic. The fact String#charCodeAt returns a number does not mean that using it is safe. Same thing is with function s(o:Object):string {return o.toString();} which can easily fail with an object created through a null prototype, you know what I mean? This cannot be solved during translation time ... sorry for that!

Getting Worst On Security

In order to maintain decent performances, TypeScript tries to translate potatoes in potatoes ... which means, not too much magic, neither 17.000 lines of JavaScript are needed to simulate something JS is not, both ES3 and ES5. This time, I am talking about private attribute in classes and here an example:
class Point {
  // private they say ...
  private test:bool = false;
  constructor(
    public x:number,
    public y:number
  ) {}
  method():number {
    return this.x * this.y;
  }
}

class ColoredPoint extends Point {
  constructor(
    x:number,
    y:number,
    public color:string
  ) {
    super(x, y);
  }
  method():number {
    return 2 * super.method();
  }
}
What I am going to show you, is the demonstration that private in TypeScript is the last thing ever you can rely on:
// a lovely colored point
var cp = new ColoredPoint(
  10, 10, "test"
);

console.log(cp.color); // test

// accessing the private property
// from an extend, so not from the
// class it has been defined private
console.log(cp[cp.color]); // false

// setting the private property
cp[cp.color] = true;

// funny enough, this would be the same
cp["test"] = true;

console.log(cp[cp.color]); // true
Et voilĂ , mesdames et messieurs, private in TypeScript is and will always be a lie, for the simple reason JavaScript is that highly dynamic language you don't want to learn which is highly dynamic indeed. If you know JavaScript, you know also how to make things truly private when necessary ... in a much more reliable, secure, and meaningful way than what is offered here.
Repeated History? This kind of attack to private properties, obj.pvt VS obj["pvt"], was possible with ActionScript 2 as well ( damn it ... was it 2003 or 4? can't remember ). Adobe in that case did something similar TypeScript, Dart, or CofeeScript are trying to do to JavaScript but with ActionScript 1: it added sugar on top that was giving nothing to the language. This was because AS1 could already represent basically everything AS2 was able to do (AS2 was based on ECMAScript 4 same as C#, Silverlight, Air, and AS3). Moreover, AS2 has never been safer, better, smaller, or faster. It has been actually an epic fail since it has been replaced by AS3 the year after which was incompatible with AS1 and the reason I have abandoned Flash development: nothing better, just more pain in the ass! Cross platform problems were still there but a whole new language and namespaces to learn ... WOHOAW, and goodbye! ActionScript 1 has been a great product and it was 99% like JavaScript. This language that made Flash the most powerful and popular plugin ever changed, and the plugin is slowly dying since that time indeed ... I hope JavaScript won't do the same because for more than 12 years it has been just awesome and is still there, today more than ever, catching up with everyday modern/real-world challenges and without a glitch!

Translated Parent Accessor

One thing TypeScript got right about classes! Thanks gosh it did not attach anything to the prototype or each instance such this.super() and similar bullshit ... well done! But suddenly, "le wild WTF appears": super in the generated JS code, is the function, the constructor, and not the prototype, so that any super.methodName() call is translated into ParentFunction.prototype.nethodName.call(this)! This means that every super call will perform two lookups and will not ensure that the parent prototype cannot and should not be redefined runtime ... is that what TypeScript would like to be compatible with? I hope no ... so that constructor a part, in this way, every method of every class is penalized with performances and only the constructor has direct access: potentially O(methods * eachClass) rather than just O(classes) prototype lookups.

The Increased Performance Myth

The funny thing about TypeScript, is that basically the only real and concrete advantage of typed languages, the cost free and great improvement performance speaking, is completely absent. Not only all these typed checks are performed during translation and never again, but the tiny abstraction of the syntax requires more code than needed, as more closures than needed, as more memory, operations, function calls than needed so, in few words, performance is worst than before. OK, is not as bad as the whole Dart library moved in mobile devices, but still slower than good old JavaScript with or without common, well known, libraries.

No Benefits At All

After this analysis of "the latest coolest hybrid version of JavaScript", I believe things are clear:
  • more to write because of types (that's OK), more to learn, because of a new behavior specified in a 0.8 draft (that's not OK)
  • no concrete advantages over common JavaScript and its well known shenanigans: DOM still a mess, wrapper VS primitives, undefined and null or NaN, operators and other stuff too ... just YAGNI sugar that supposes to make us happy and dunno why
  • new shenanigans as it is for every bloody programming language ... so we have to be careful with both TypeScript and double check the equivalent generated JavaScript to be sure things are OK and as expected for real: double learning, OMG!
  • performance is worst ... maybe JIT compilers could somehow take advantage of TypeScript generated code but I don't think so plus is more code than needed as it is for every translator: not optimized, rarely faster
  • we can have mapped source code with TypeScript, we cannot have double mapped source code to understand errors if we would like to chose a different minifier over the TypeScript generated JS code
  • more I haven't talked about ...

Not All Wrong Neither

I know this post looks like I am throwing stones to MS intent and effort over this TypeScript tool / thing / language / proposal / whateveritis but I am not, I swear. I love the direction Microsoft is taking since IE9 but I have also said, and it wasn't just me, that the Web needs something else which is not sugar. Cool tools for debugging are all welcome ... new tools for something that does not solve a thing are a waste of time. We would like tools to make the Web better for every browser, faster for every CPU, graphically shiny for every screen ... classes for massive apps won't help anyone to make this happen and we all have the proof today that JavaScript never needed classes to scale, what we need are developers that know the language, use it properly, and move the web forward, rather than being stuck with sugar and sugar and sugar and sugar ... IMHO!

Everyone Is Crazy

Scripting Languages suppose to be easy, expressive and powerful, and JavaScript is one of them. The fact it has no classical inheritance is driving people crazy since ever: they need classes, that seems to be the only way they can think programming ... meanwhile, we all created what is the Web today and is far away from perfect but it's a great place and it's getting better on daily basis. Look what has been done ... think if strict types and classical OOP was the missing thing ... look again, and now move forward with your next, awesome, JavaScript based thing that will simply work everywhere and will satisfy your expectations! Thanks for reading, appreciated.