Monday, March 25, 2013

TypeScript: initial impressions

There are several things under the TypeScript umbrella: a type system, language spec, JavaScript-targeting compiler and tooling that provides interactive code completion. I have tried TypeScript on a few small projects, the latest one being TypedPhoneGap. I also worked extensively with the language spec, wrote a parser and analyzer for the `.d.ts` contract specification fragment, pondered the semantics, and engaged in little flamewars on the language forum. My conclusion, in short, is this: the type system and language design are terrible, the compiler is OK, and tooling is excellent. Overall, it is an improvement over writing bare JavaScript, and the definition fragment is helpful (though not ideal) for communicating JavaScript API formally.

It is easy to see why the tooling is good - you can check out for yourself in the interactive environment on the TypeScript website. I used it through VisualStudio and though I found it glitchy in a few places, with having to restart VS a dozen times, it is overall quite helpful.

My complaints are mostly on what I consider to be poor language design decisions.

First, the type system does not even try to be sound:

Second, there are no generics (though they are promised for the next release). It feels very dumb having to replicate code that could have been expressed as generic specialization. Code duplication can be avoided if you drop to JavaScript and start computing things, but this only applies to values and not types. There does not seem to be an easy way to compute TypeScript types as-you-go.

Third, I find the whole subtyping story simply a waste of time. OCaml has a much better system with row polymorphism, and still I do not get the impression it is used much. Would be interesting to see if it is used in js_of_ocaml to reason about JavaScript libraries. I have not felt a need for this using WebSharper.

Fourth, there is no abstraction. I have not found a way to define an abstract type. Interfaces are always open. Classes are open too, and I have not found how to make all constructors private. This is really annoying.

Fifth, there is a lot of recursion craziness going on in the language, complicated with structural typing. I think the types are best described by regular trees. This is not exactly implementation-friendly - I had a very hard time trying to implement things like a subtyping decision procedure, especially since the language spec is very terse on these issues. The online TS compiler works for quite arcane examples - I wonder if they have a correct equality and subsumption implementation over regular trees, or they are using some hack that just happened to work on my examples. Not that it matters very much since subtyping as defined breaks soundness and is therefore not very interesting or useful.

Now, the biggest promise I see in TypeScript is to give a formalizm for expressing JavaScript contracts, especially since there is some adoption. This essentially involves the .d.ts fragment: constructs for expressing JavaScript interfaces. Unfortunately, as it stands, it is quite limited because of the lack of generics and abstraction.

Also, from our experience with WebSharper, artifacts expressing JavaScript contracts should not be authored by hand. Usually there is a lot of repetition going on in JavaScript library APIs, something that can be easily abstracted over if you are writing in a Turing-complete programming language (`.d.ts` files are not).

I therefore envision an ideal toolset for JavaScript contract specification to consist of:

  • A machine-readable simple (JSON-based?) standard spec for API contracts
  • A JavaScript library for generating the API contracts in some EDSL allowing to take advantage of abstraction
  • Tooling for generating easy to use API documentation from the contracts
  • A utility for sealing a value with a contract to introduce runtime checks and blame assignment (there is some good literature on how to do that)
  • Tooling for generating `.d.ts` from contracts, parsing `.d.ts` into contracts (possibly with some approximation)
  • Additional tooling for consuming contracts from JavaScript-based frameworks such as WebSharper

The problem, as always, is marketing - convincing library authors to use a formalism to express their API. Even if we had a working system satisfying the above wishlist, this would be a tough one.

No comments:

Post a Comment