Summary: The problems facing web development today. Microsoft’s new TypeScript language, what problems it addresses, and what it leaves wanting.
Earlier this year, I predicted Microsoft would be utilizing their still-baking Roslyn compiler service to transform C# into targets besides IL, such as JavaScript. That prediction didn’t come true, but I was close: Microsoft is indeed getting into the compile-to-JavaScript games, but they’re doing so with a brand new language announced today, TypeScript.
JavaScript is a messy, powerful language.
The whole compile-to-JavaScript trend addresses a real problem in web development today: JavaScript just isn’t a great language for big web apps. Some argue it’s not a great language for anything besides quick DOM + event handler glue. And honestly, they kind of have a point.
Half baked, escaped the lab too early, leaving us silly things like implicit conversions for equality comparison. Quick, what’s the result of this?
foo = 0 == (100 + 23 === “123”)
If you guessed the boolean true, you’re right (I think!) but it shows kind of the trouble you get into when languages try to do too much for the developer.
But silly syntax puzzles aren’t the real reason JavaScript is bad for big apps.
No, it’s for a number of more deeply-seated reasons the difficulties arise when coding a large JS app with a team of developers:
- The automatic, often accidental, inclusion in global scope. (The above snippet adds foo to the window object, woops!) This results in code littering the global namespace at best, and overwriting other code’s functionality at worst.
- No modules or namespaces for code organization. In addition to contributing to the above problem, a lack of built-in modules means we have to resort to 3rd party libraries for dependency detection and loading. Often, developers will just take the easy route and load everything, resulting in web apps that load slowly and use excessive memory.
- A 10-ways-to-do-this inheritance pattern that kinda sorta looks like classical inheritance but is really prototypal. Some codebases standardize on a 3rd party library (such as MooTools or Prototype), while other codebases become the Wild West of inheritance problems.
- Without any types, refactoring and symbol analysis becomes painful. For example, want to find all callers of a function? Have fun with CTRL+F, and weed through who’s calling your function and who’s calling a function of the same name. Want to rename a property? CTRL+H and pray that no other code file has a property of the same name. And so on.
Plus other uglies like optional semicolons to end lines, resulting in production-level frameworks being filled with, in the words of JavaScript creator Douglas Crockford, “insanely stupid code.”
But one thing JavaScript is, is capable. It’s a functional, prototypal, object-oriented language. General purpose.
So rather than wait for JavaScript to slowly evolve through standards bodies and bickering, we build our own fast-evolving languages that compile down to JavaScript.
CoffeeScript: A (slightly) better JavaScript
At the time of this writing, the compiles-to-JavaScript language de jour is CoffeeScript: a superset of JavaScript that adds things like classes, and removes things like semicolons, parenthesis, and other staples of the C family of languages.
But CoffeeScript still lacks a proper compiler. Oh, sure, there’s the CoffeeScript compiler, but it’s not really a compiler. It can’t tell you if you’re passing the wrong type into a function. It can’t tell you if foo.Blah will error at runtime, because there’s no symbol analysis.
CoffeeScript also suffers from its straddle-the-fence stance on compatibility with JavaScript. Want to include parens? OK, valid! Want to exclude parens? OK, valid! While it sounds nice in theory, in practice you end up with an inconsistent codebase, and an awkward rule set about when optional syntax isn’t really optional.
And though CoffeeScript tried its hand at list comprehensions, it falls far short of what Python and C#/LINQ devs have been enjoying for years.
To make matters worse, there’s still no real standard library for JavaScript. Just a mash of tiny libraries that do things differently ($.map? or array.map?)
And finally, we still have terrible debugging support. Got Coffee? OK! How do I set a breakpoint on this CoffeeScript line? Silly developer, you can’t! You have to look at your Coffee, figure out which .js files were emitted, find those in your favorite web browser developer debugger tool, and break into that. Grahgghhlhlhlhsl.
End result? As of late 2012, we don’t have any great options for building big web applications. We need a language that supports symbol analysis (refactoring and the like), type error detection, modules, classes. We need a web development platform with a standard library. We need a web development platform that supports debugging in the language you authored.
Enter Microsoft’s TypeScript
TypeScript is a Microsoft attempt at solving these problems, in particular through the adding of types. It’s JavaScript with types.
Does it solve all the problems?
Too early to say.
It was announced only today, and I just downloaded the damn thing. At a glance, they solved the classes and modules problem. And by adding types and tooling support in Visual Studio, you can actually perform refactorings in your big codebase; something Java and C# developers have been enjoying for over a decade, but web developers have been suffering without.
It doesn’t appear to have a standard library – sorry, LINQ fans.
Nor does it appear to support debugging in Visual Studio.
UPDATE: The TypeScript compiler supports an experimental –sourcemap command line argument that generates a source map file. These source map files can then be used to debug TypeScript in the browser. I predict that Microsoft will use these source map files to integrate into Visual Studio’s debugging experience, likely through a special debugging browser similar to the existing Page Inspector.
So that answer for now appears to be, TypeScript is an incremental improvement upon CoffeeScript: types and modules and symbol analysis are a nice addition. We’re still missing some important things, namely, a standard library and a powerful source-language debugger. Until we get these things, web development is still a second class experience.