Dynamically typed languages make you fight more non-interesting bugs than statically typed languages.
We have "bumble-bee-season" at the moment here. Every hour a queen is coming by my window and flies into my apartment. For some reason the queen must have a vain hope that my apartment will be a suitable place for her nest. Luckily it's not an aggressive type of bee, so you just gently guide it to the exit -- and on it flies.
Now this will not be about bumble bees, as however interesting it might be, the fate was that I shouldn't be a biologist. This is a shame -- gene manipulation sounds fun. So we will write on the other kind of bugs, that most readers will probably be more familiar with. The computer bugs who were once real insect bugs, but took on a more imaginative meta-physical form.
Any set can be partitioned in two. Let us partition bugs in the interesting and non-interesting ones. Of course this is for the pure reason of studying bugs. The set of interesting bugs are those, which make for a good story over a cup of coffee. They explain some fallacy in your thinking in help you understand the problem you are working with. To be specific: interesting bugs alters your perception of the problem you are trying to solve.
The other group of bugs, non-interesting, does not have the virtue of making a good story. These are most common and your only goal is to fix them as quickly as possible to get the program up and running. They manifest themselves all the time. It may be a wrong type that gets passed, it may be a wrong tag, off-by-one, a non-exhaustive pattern match with an obviously implemented missing pattern, swapped arguments in a function call or something similar. They may be really pesky to find and fix, but they do not tell anything new to your brain.
I don't like non-interesting bugs. I don't like to play with code to make it work either. I began hacking ML at a very early age, so my brain is wired to the thought of having static types on everything. To me, I rather want to skip the non-interesting bugs and write the code so I can attack the next problem. At some point, the ML type system becomes a tool for avoiding bugs of the non-interesting kind. We can't pass the wrong type as the type system will complain. We can still tag things incorrectly but not with a typo. The last problem I had in a dynamically typed language was that I had written non-fetched rather than the correct not-fetched. A proper sum-type eliminates this problem. Off-by-one tends to be eliminated by using a data structure such that indexes are abstracted away. Non-exhaustive pattern matches are caught by the compiler. And finally, swapped arguments are either caught by the type system, or you can pass a named record so each argument has a name rather than a position in the call parameter list.
Unfortunately, you don't get complete elimination of non-interesting bugs. There are still some left, but they tend to be few and far in between. I save time and altering the program is simpler because the types have to match for any change, eliminating much work with finding all spots having to be changed. For the experienced type hacker, one can use tricks like universal embeddings and phantom types to squeeze out even more expressibility. And that is without adding more tools into the bag: dependent typing, substructural typing and existential types.
And with this, I think I have explained why I don't like programming in dynamically typed languages that much. My claim will be:
Add a comment