Wednesday, May 14, 2008

Type inference thoughts

I have been wondering about one thing and throw out this question just in case someone possibly reads my blog - does type inference bring any benefits apart from less typing?

I know proponents of dynamic typing consider declaring variable types "noise" because it is the antithesis of their style of coding, and they say the compiler can usually infer the type for you anyway. Scala for instance is designed this way:

var x = "Hello"

The compiler will infer that x is of type String. You can reassign it (just like you can in Java) to a new String, but if you try to reassign an object which is not a String compile will fail.

Map<Integer, Office> offMap = ....
for instance, is more to type, that is true. In my opinion that can be an acceptable tradeoff. If I have the code in an IDE mouseover could tell me the return type of the right hand side method, true, but I often look at code through other interfaces than an IDE (online, books, a shell). Note that I'm not saying I think type inference is bad... sometimes it is a relief. But I don't think it is terrible that Java lacks it, either. For me it is just a matter of style.

But just in case I have missed anything, my question is again: does type inference bring any other possible benefits? Compiler optimization...?


Lars Westergren said...

A very comprehensive answer by Ola here!

helium said...

for (std::map<std::string, std::vector<boost::shared_ptr<Something> > >::const_iterator it = foo.begin(); it != foo.end(); ++it) {

(This is nothing I make up. You will see things like this in real C++ code)

now let's look at the same example using the type inference abilitys that will be avilable in C++09:

for (auto it = foo.begin(); it != foo.end(); ++it) {

What did we get? A bit less typing? Yes, but as well the code got easyer to read.

Lars Westergren said...

@Helium - hmm.... that IS pretty darn ugly.

Still, there is a lot of information that disappears in the inference that I still think might be useful to know, i.e. if you see
var x = factory.init
you'd have to look up "init" first to see what it returns, and then look up the class of the return.

Some people seem to have photographic memory for APIs. I'm not one of them alas.


> Does type inference bring any benefits apart from less typing?

Well, have you looked at LINQ? How it enables anonymous types to flow out of complex expressions, while remaining 100% type-safe about the whole thing?

Greg said...

@Lars: there are tools for that.

Hugs> :type factory.init
factory.init :: <whatever-type-it-is>

Lars Westergren said...

@Casper I have been meaning to look at C#, LINQ etc for a long time, it seems very nicely engineered. But there are lots of other stuff on my "todo" list I have to get out of the way first.

@greg Yeah, but as I said I'm often reading source online, in books and so on, so I would have to find and download it every time.
Still, it feels like I'm making a mountain out of a molehill here. I think I'm convinced, I want type inference.

Ola Bini said...

See, Lars, the difference is that when I see examples like heliums second version, I don't care about the information that's disappeared. I don't _need_ to know that. In most cases when reading code you actually don't need to know the real type, you just need to know how it is used. And obviously it is used as an iterator here, and that's really all I need to know. I would be more interested in knowing what foo is, since that's probably a collection like object, but that should be really easy to find from surrounding context too.

So the main question is, do you really lose so much readability if you see this in real code? In a real method, which will almost never be larger than 20 lines, you can always see the method header which gives you the types of all the arguments. From that point on you should be able to see what everything does without the explicit type tags. That's why duck typing works so well for me - I just don't care what type things have, I just do what I want to do with them.

Ola Bini said...

Also, LINQ has nothing to do with type inference at all. The compiler creates synthetic types for you based on the LINQ definition so it saves you a bit of typing on the left hand side of a LINQ expression, but extension methods and expression trees are the real enablers for LINQ.