TypeScript and Functional Programming

NOTICE: The latest versions of TypeScript support generics. Thus, this post is currently out-of-date. 

Few weeks ago I had a sort discussion on TypeScript in TechDays 2013 event. In my opinion, TypeScript is one of the coolest things Microsoft announced last year. In short it allows you to write typesafe JavaScript by using the most of the goodies included in forthcoming ECMAScript 6 (ES6) -standard. TypeScript code is compiled into JavaScript, but thanks to the type system compiler and IDE helps you a lot. It is noteworthy that Visual Studio is not the only supported IDE, this video demonstrates IDE support in Sublime Text 2.

Seemingly there is a myth that TypeScript delimits expressiveness of JavaScript and that TypeScript type system restrict you from using functional programming techniques. It’s not quite true. However, if you prefer functional programming (FP) paradigm over object oriented paradigm (OOP), you cannot always use efficiently TypeScript type system. At least not yet. According to Anders Hejlsberg support for generics is in roadmap.

TypeScript and functional programming

Douglas Crockford summarized that JavaScript is LISP in C’s clothing. JavaScript is a functional programming language in that sense that functions are truly first class citizens. The same is true for TypeScript. E.g.

var sum = (a, b) => a + b

creates object of type (any, any) -> any. If you want to make it typesafe you can write:

var sum = (a:number, b:number) => a + b

Now sum is type of “(number, number) -> number”.

TypeScript provides some convenience for functional programming in addition to plain JavaScript. However, currently it’s support for functional programming paradigm is rather limited; or better, it doesn’t provide type safety in many FP scenarios.

Limitations

Consider following simple example: I would like to have F#-like fold higher-order function in TypeScript. In F#, fold’s signature for lists is ((‘a -> ‘b -> a’) -> ‘a -> ‘b list -> ‘a.  You can calculate sum of a list of numbers as follows:

[1;2;3] |> List.fold (+) 0; 
// returns 6

Currently the best match for fold-function is ECMAScript 5’s (ES5) reduce. You can use ES5’s Array’s reduce as follows.

[1,2,3].reduce(function(accumulator, current) {
   return accumulator + current;
}, 0); 
// returns 6

As TypeScript implements ECMAScrip 5 standard you can use it also in TypeScript. It’s signature is (callback: (previousvalue: any, currentValue: any, currentIndex : number, array : T[]) => any), initialValue:  any) -> any. Even if the array is typed, it is not typesafe.

Can you create a nice typesafe version of Array’s reduce by TypeScript? No. Either you have to compromise type safety or generality:

function fold(
   accumulator : (state: any, current: any) => any, 
   seed : any, 
   data : any[]){
   // Implementation that compromises type safety
}
function fold(
 accumulator : (state: number, current: number) => number, 
 seed : any, 
 data : number[]){
 // Implementation that compromises generality
}

Basically, there is no elegant way to implement typesafe higher-order functions in TypeScript. Yet, TypeScript makes calling reduce function a bit more convenient:

[1,2,3].reduce((acc,current)=>acc+current,0); 
// returns 6. 
// Note: Just like in ECMAScript you don't need to use all parameters 
// of the callback.

This is still somewhat clumsy if you compare this to, for instance, LiveScript. In LiveScript, you can say:

[1 2 3] |> _.reduce _, (+), 0

To sum up

TypeScript does allow functional programming and it is a bit better for that than plain  JavaScript. You have first class functions, closures and lambas just like in plain JavaScript. In addition, you can write typesafe functions. However, there are limitations in the current implementation of type system. Oftentimes, you cannot fully utilize type system when using functional programming patterns. Higher-order functions was just one example of that. I could have chosen any other basic pattern in functional programming, but for sake of simplicity I chose fold as an example of higher order functions.

Current version of TypeScript is designed for object oriented programming (OOP). It provides only marginal benefits if you want to use functional approach. What I love in TypeScript, however, is that you don’t need to do binary decision between the assurance created by type safety and the expressiveness of functional programming paradigm. There are many cases, in which you can have them both, even if oftentimes you have to compromise type safety in order to use FP-patterns and vice verse.

Then again, if you want to write functional code rather than object oriented, there are better alternatives. Especially, LiveScript is very promising. Once Microsoft implements support for generics, the situation may change. After all, type safety is a great benefit when writing big applications – no matter what is the used programming paradigm. In the perfect world, someone would combine TypeScript’s  optional type safety with LiveScript’s syntactic sugar for functional programming.

Advertisements