Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I've read that Go doesn't actually have true type inference in the sense that functional languages such as ML or Haskell have, but I haven't been able to find a simple to understand comparison of the two versions. Could someone explain in basic terms how type inference in Go differs from type inference in Haskell, and the pros/cons of each?

share|improve this question

2 Answers 2

up vote 4 down vote accepted

See this StackOverflow answer regarding Go's type inference. I'm not familiar with Go myself but based on this answer it seems like a one-way "type deduction" (to borrow some C++ teminology). It means that if you have:

x := y + z

then the type of x is deduced by figuring out the type of y + z, which is a relatively trivial thing to do for the compiler. To do this, the types of y and z need to be known a priori: this could be done via type annotations or inferred from the literals assigned to them.


In contrast, most functional languages have type inference that uses all possible information within a module (or function, if the inference algorithm is local) to derive the type of the variables. Complicated inference algorithms (such as Hindley-Milner) often involve some form of type unification (a bit like solving equations) behind the scenes. For example, in Haskell, if you write:

let x = y + z

then Haskell can infer the type not just x but also y and z simply based on the fact that you're performing addition on them. In this case:

x :: Num a => a
y :: Num a => a
z :: Num a => a

(The lowercase a here denotes a polymorphic type, often called "generics" in other languages like C++. The Num a => part is a constraint to indicate that the type a support have some notion of addition.)

Here's a more interesting example: the fixed-point combinator that allows any recursive function to be defined:

let fix f = f (fix f)

Notice that nowhere have we specified the type of f, nor did we specify the type of fix, yet the Haskell compiler can automatically figure out that:

f :: t -> t
fix :: (t -> t) -> t

This says that:

  • The parameter f must be a function from some arbitrary type t to the same type t.
  • fix is a function that receives a parameter of type t -> t and returns a result of type t.
share|improve this answer
4  
more exactly, Haskell can tell that x, y, z are the same Numeric type, but they can still be Integers, Doubles, Ratio Integers... Haskell is willing to make an arbitrary choice between numeric types, but not for other typeclasses. –  Jan Dvorak Aug 17 at 9:52
    
Thanks, this was really clear –  a3onstorm Aug 17 at 19:14

Type inference in Go is extremely limited and extremely simple. It works only in one language construct (variable declaration) and it simply takes the type of the right-hand side and uses it as the type for the variable on the left-hand side.

Type inference in Haskell can be used everywhere, it can be used to infer the types for the whole program. It is based on unification, which means that (conceptually) all types are inferred "at once" and they can all influence each other: in Go, type information can only flow from the right-hand side of a variable declaration to the left-hand side, never in the other direction and never outside of a variable declaration; in Haskell, type information flows freely in all directions through the entire program.

However, Haskell's type system is so powerful that type inference can actually fail to infer a type (or more precisely: restrictions have to be put in place so that a type can always be inferred). Go's type system is so simple (no subtyping, no parametric polymorphism) and its inference so limited that it always succeeds.

share|improve this answer
3  
"in Haskell, type information flows freely in all directions through the entire program": I find this gives a very good intuition. +1 –  Giorgio Aug 17 at 9:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.