24 Feb 2013

The comeback of static typing

I used to loathe static typing. From PHP to JavaScript to Python to Ruby, I was pretty much a dynamic typing fan boy. I was working primarily on web applications with very straightforward business logic using frameworks like CodeIgniter and Django.

These were some of the reasons why I hated statically typed languages then:

Verbosity – the presence of a type system meant that I needed to type more

Difficult to prototype

Compilation – time spent on waiting

Over time, not only have I learned to appreciate languages with good type systems, I actually now prefer them for solving certain classes of problems.

Java and C++ (the languages through which I experienced static typing) are not the best representatives of statically typed languages. It’s only after I started diving into Scala, did I start discerning between good and bad type systems. A good type system should not get in your way and should definitely not make you type more than it’s necessary. I have also been dabbling a bit with Go and Rust, and I’m excited about how productive I feel in both of them.

Type inference goes a long way in saving keystrokes, but a powerful type system can offer much more than that. For example, let’s take Scala’s structural types:

Structural types [1] eliminate the need for an abstract class or an interface/trait. I can simply define a function speakWith which takes an argument (animal) which is of type {def speak: String}, i.e. any object that has a speak method defined in it.

I have heard arguments that such a type system is complex for the average developer to grok. I used to be one of them, but I’m now convinced that most of this talk about complexity comes from forgetting that there is a learning curve for any tool. One is bound to be unproductive during that time.

Contrary to conventional thinking, I actually find statically typed languages to be good for projects that undergo a lot of churn, either because the problem requires an experimental approach or the requirements are hazy (as with the case with a lot of start-ups). Although it’s much easier to start hashing things out in a dynamically typed language, I noticed that as the codebase became larger, it becomes much harder for me to feel confident about the various changes I was making without the presence of proper tests. And, tests are painful to maintain when there is a lot of churn happening. Static typing does not replace tests, but it definitely catches a lot of stupid errors and makes refactoring code really easy. Apart from better IDE support, you also get the confidence that when the code compiles, you can be reasonably sure that atleast syntactically things are alright.

With respect to compilation time, Go is pretty fast even when compiling large projects, but the same can’t be said about Scala (C++ is also notoriously slow). However, using a SSD has helped a lot, atleast in absolute time. Still, even if the compilation phase robs me some time, it’s a trade-off I’m now willing to make if a statically typed language gives me better confidence about the correctness of my programs, eventually leading to less time spent on bug fixing.

A few years back, one big lure of Python or Ruby used to be the functional constructs that they offered like higher order functions. However even Java has now caught up, with Java 8 introducing lambda expressions and an enhanced collections API. Hence, moving forward, I believe I will find very little reasons to hate static typing as much as I used to. It’s really exciting to see how languages like Rust and Scala approach type safety without compromising on productivity. I’m going to continue to use Python, Javascript and Ruby where it makes sense (either because of the community or the libraries), but dynamic typing is no longer my number one reason to use them.

Here, `speak` is a polymorphic function bounded by those types which are instances of `Speak`. Of course, Haskell goes a lot further than Scala in using types for safety, e.g. by distinguishing side effects in the type level, amongst other things.

Here the big difference is that in Haskell if you have the Man class and Speak class outside of your control (say, both are 3rd party modules), then you can code the missing part of interface (in this example, the ‘speak’ function) and they will be able to interoperate without any changes to the original code.

Not sure I recommend RWH as a starter book – too often it references ideas it hasn’t introduced yet. During the community process while it was being written, loads of issues were pointed out that never got fixed in the final version (check the comments in the online version).

Learn You A Haskell for Great Good maybe a better intro, then come back to RWH once you’ve grokked it to see it used for real world problems.

For there to be a comeback, there would have to have been a pullback. Maybe for you that’s the case, but for a huge number of developers using C#, Java, SQL, etc., static typing never went away in the first place.

what you described in Scala is basically duck typing, not static typing. alot of dynamic languages (Python in particular is famous for it) rely heavily on duck typing to achieve a strict type system without the need to statically declare types in advance.

The scala example could be seen to mimic duck typing but with an important difference – the compiler complains if you call any other method apart form ‘speak’ on ‘animal’. In contrast, Python does not really stop you from calling a non-existent method on an object during compile time.

OK, I agree his argument for not liking static typing is a bit naive, but the whole raison d’etre for being a programmer is to do things faster with less work. I’ve always said programmers are fundamentally lazy; our entire purpose in life is to get a computer to do something that we would have otherwise had to accomplish through work.

At issue here is whether you actually end up doing less work without static typing; I think most people who have spent any amount of type working in both environments realize the benefits of type safety in preventing bugs that cause you much more work down the road.

If you can’t touch-type rapidly, then spend some time learning and practicing. It’s like being a carpenter who can’t accurately hit a nail with a hammer.

It is far, far easier to read and maintain code where things are explicitly written out. The question isn’t whether or not the compiler can infer the type (or even how long it takes to compile). The question is how easily can a human understand it when forced to debug it?

It’s a lot faster and more productive to do extra typing when you write the code the first time.

The whole ‘typing is a chore’ makes no sense to me. It smacks of laziness:

1) A decent IDE in concert with a strongly typed language will do half your typing for you. Learn your IDE.
2) Why on Earth are you banging on about typing? This is ‘The Big One’. If you think coding is a typing exercise you aren’t coding right. THINKING is your primary task, implementing takes a fraction of the time and is such a minor factor that I seriously wonder about the focus of people who think that typing is an issue.

Next you’ll be saying commenting your code is not necessary because it far to inconvenient to do all that typing. Do you have idea how much typing you have to do for a requirements doc, spec, design, test plan, user manual, support notes or installation guide? When you close a fault in your fault tracking system do you settle for cryptic one liners? I suppose you skip writing out comments when you commit your work to source control.

If you are serious about being a software developer, you will be doing a lot of typing, so you better get good at it.

Choosing your first Bonsai tree is going to depend on a
few things, the biggest thing being here you plan to place your tree once you get
it home. Looking after a Bonsai is pretty straightforward if
you follow a few golden rules. Bonsai can be created from almost any perennial woody tree
or shrubs which produce true branches.