On Type Inference


This is a comment I recently saw on a headline-grabbing article about Swift: –

I also don’t think that “type inferring” is of great use. If you cannot be bothered to hack in a variable’s data type, maybe you should not develop software in the first place.

I was so infuriated by this comment that I ended up writing this blog post. The thing that infuriated me so much was more the arrogance of the second sentence as much as the ignorance of why having type inference can be such a massive productivity gain.

Here are three versions of the same sentence written in three different ways – slightly contrived as usual to make my point…

  • Hello, I’m Java. I have a bag of apples. In this bag of apples there are five apples.
  • Hello, I’m C# 3. I have a big of apples that has five apples in it.
  • Hello, I’m F#. I have a bag of five apples.

These statements don’t actually translate directly to code but you get the idea. Why would you need to write out the above sentence in either of the latter ways? Are you learning the language from a school textbook? Or using it in a professional & fluent manner?

C# can declare locally-scope implict variables and create implicit arrays. F# can do full H-M type inference. Java can’t do much of anything really. Here’s the above sentences sort of written as code (the final example uses the same C#-style syntax to keep things consistent): –

The latter example is more in the F# vein, without braces, or keywords whose usage can be inferred.

The real power of type inference comes from the ability to chain multiple functions together in a succinct manner, and then at some point in the future changing the type of one of those functions and not having to change any type signatures of dependent functions. It’s quite addictive, and once you get used to it it’s quite difficult to go back to an explicitly-typed language.

Last minute update: It turns out that the individual who I quoted above at the start of this post had confused type inference with dynamic typing. I suspect that this won’t the first or last person who has done this.

TypeScript exposes some irrational Microsoft hatred


Just watched a couple of videos on TypeScript – basically a Microsoft-developed (but open source) superset of JavaScript which compiles into plain old JS that gives you a type-safe environment to write JS. Unlike stuff like Dart or Script#, because it’s a superset of JS, you can easily opt-in to bits you want; it integrates without any issues with existing JS like Node.js or JQuery.

Initial thoughts of TypeScript

Firstly, coming from a .NET developer background, my first thought was that TS reminds me of F#! By that I mean, first it builds on top of JS to give more functionality in a similar way that F# builds on top of the functionality of C#. Ironically some of this is accomplished by “removing” functionality e.g. static typing, just like F# introduces immutability which initially seems like a restriction but actually is a boon.

The type inference also reminds me of F# is that the output of methods is inferred from the return type from the method, or how you can define fields within the constructor directly. In fact, it makes me wish that C# had better type inference – and it just goes to show you can do more powerful type inference without more CLR support.

All in all, it looks very nice – basically gives you more intellisense, refactoring opportunities e.g. rename, lambda expressions, implicit closures etc. which are very C#-like.

Initial thoughts of TypeScript – with feeling

This is all good. Yet I’ve already read an incredible amount of emotional, uninformed spouting about it. I’m not referring to the actual articles in the links here – although the Register one isn’t quite as accurate as I’d have liked, talking about “extending JavaScript” in the headline which isn’t quite right. They’ve written a new language which itself is a superset of JS. They’re not writing an MS-only version of JS.

Yet there are many comments on the following tangent: –

  • It’s from Microsoft. Ergo, it’s crap.
  • It’s from Microsoft. Ergo, it must have some hidden nefarious purpose.
  • It’s from Microsoft. Ergo, it won’t be secure.
  • It’s just another Dart. What’s the point. Oh it must be competing with Google for the sake of it.
  • They’re trying to lock me in to the Microsoft tool-space etc. etc.
  • Static typing is crap.
  • This will just fragment the JS community by creating a different version of JS.
  • I can write JS directly, what do I need this for?

What a load of tosh! Anything that allows me to refactor a method or property name easily, or gives me intellisense for exploring an API is definitely a good thing. It doesn’t affect the runtime – it’s still spitting out plain JS. It doesn’t require me to learn lots of new things if I’m a JS developer. The language builds on top of JS – so you can opt-in for the bits that you want. It’s open source. What’s the problem?

Of course – it’s written by Microsoft.

Type inference in C# and F#


When C#3 first came out, I thought that the type inference was awesome – you could do stuff like this:

image

image

image

Amazing, isn’t it? The C# compiler figures it all out for you!

Except there are other languages out there that are statically typed and yet have much more powerful type inference which cuts down on a lot of boilerplate coding for you, F# being one such language. Here’s some pseudo-C# examples of things that you simply can’t be done in the real C#..

Type inference of method parameters

In this example, I want the compiler to infer the types of the arguments being used in this method:

image

Obviously, C# won’t allow this, but here’s an F# equivalent which is perfectly legal: –

image

Notice how employeeName and employeeAge don’t have any explicit types against them. Once you’ve compiled this in F# interactive, you get the following:

image

i.e. printDetails takes in two parameters, string and int, and returns unit (read: void). This isn’t like generic resolution. In the example above, the compiler knows that employeeAge is typed as an integer because of the equality comparison with 31 (which is an integer). Similarly, the %s argument tells the compiler that employeeName is a string. In some ways this is reminiscent of lambda expressions which do away with the type declaration completely, except more powerful.

Now I’m no F# expert, but I think that you probably wouldn’t write even it like this in F#; you’d probably use a Tuple (think “a more flexible anonymous type” from C#) like this:

image

Same thing as before really, except here we take in a single parameter which is a Tuple of string and int; we treat the first bit as name and the second as age.

Sharing types across methods

Here’s another example of where type inference could be stronger in C#. I have two types, Customer and Employee. Both share a common property called Name, and I want a method to print that name out that can be shared across both types.

image

This PrintName method wouldn’t compile obviously, but if you wanted an all-purpose method like that to print out the name of a Customer or an Employee, you would need either: –

  • The creation of a common interface (say, INamedPerson, which Customer and Employee implement)
  • Use of C#4 dynamic and duck type it away
    In F#, the above sort of code is actually possible and perfectly legitimate – the PrintName method would be declared as taking in a tuple with the first parameter of Name and the second as an anonymous property. This is legal in F# because the type inference knows that the PrintName method only accesses the Name property, so it’s legal to use different types with it.

    image

    So the above example takes in a tuple parameter called person, which has two parts – the first is name, of type string, and the second is “something else”. It doesn’t know, or care, what the other bit is, because it’s not used in this method. The compiler calls it like so: –

    image

    i.e. string and an anonymous type ‘a (you get the same if you create an anonymous type in C# and mouse over the var). So now I can call it as follows: –

    image

    The first part in yellow above is my declaring a customer and an employee. The next bit is the compiler determining the type declarations of them. Then I call printName on both! Also note in the second example that there isn’t even a predefined Customer or Employee type – everything has been effectively done with anonymous types that simply are matched based on their type signature. Very cool!

    Compare the C# and F# code samples above – the F# ones might seem a bit “uargh!” at first – almost as if they are weakly typed – but they aren’t; it’s just that the F# compiler is very, very smart and allows you to write very terse code such that you can do away with a lot of stuff that is, in fact, largely unnecessary.