Type Burdened

I've been trying to collect my thoughts on why I prefer Scala's type system to any other that I've come across. To summarise: it has type safety and just the right amount of type burdening.

What is type burdening?

Type burdening is a consequence of type safety. The more you have to specify a type by hand the more type burdened a language is.

Some examples and numbers

Java

Java is very type burdened. I'll arbitrarily give it a type burdening index of 1 (high values are bad).

Employee bob = new Employee();
Not only must you specify the type everywhere, but you must specify it twice in many cases.

This slows us down, makes code longer and adds no value.

ML

At the other end of the scale we have languages like ML. ML has full type inference. It will even infer the types of arguments on function calls. I'll give it a type burdening index of 0 (low values can be bad).

fun fac 0 = 1
  | fac n = n * fac (n-1)
The above defines a function, fac, as a function that takes an integer argument and gives an integer result. This is statically typed - but there are no mentions of types anywhere. The types are inferred by the compiler unless you optionally specify a type.

The reason I say that low values can be bad (not must be bad) is that it forces you to think about what the types are whenever you look at this function. Arguably, if functions are well written and clear then this shouldn't be hard - and you shouldn't really care. However, we all know that bad code creeps in to any code base.

The other reason this is bad is that somebody could accidentally change the type of the function without realising (suppose they changed that multiply to a divide). This could be part of a public API and the consequences of accidentally changing a signature could be bad.

Scala

Somewhere in between we have Scala. You must specify the types of function arguments, but you don't have to specify the types of variables (nor the return type in many cases).

def timesTwo(n : Int) = {
  val result = n * 2
  println("Result is ["+result+"]")
  result
}

Similar to ML, Scala will infer that the type of the variable result is Int. It will also infer that the return type of timesTwo is Int. However, you must specify that the argument n is of type Int. You can specify a return type if you wish, and you can specify a type for the variable result.

I like this because it forces you to specify your functions signature. If you want to change it - you have to be explicit and change it by hand.

I like this because you don't have to specify the types of internal variables that the compiler could figure out for you.

I'm not going to give Scala a type burdening index because I can't formally define how to come up with the number. Instead, I'll say it is somewhere between 0 and 1 ;-)

Conclusion

I have purposefully steered clear of the argument of dynamic vs static typing. It's a culture thing - some people like one, some people like the other, some people like both!

Type burdening gives statically typed languages a bad reputation. I think that some people have embraced dynamic typing because they have spent too long being type-burdened. Over time, I hope that more languages will reduce their type burdening and people will focus on the real strengths and weaknesses of dynamic/static typing and make a better choice for themselves.

Discussion

blog comments powered by Disqus

Colin Howe

I'm Colin. I like coding, ultimate frisbee and startups. I am VP of engineering at Conversocial