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.
behind the design
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.
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.
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?
- will this call produce an error?
primitive(new String(""))
- how about this one?
wrapper("")
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 scopeExactly,
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 notfunction 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, bothES3
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]); // trueEt 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
VSobj["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 suchthis.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 ...