Monday, April 03, 2006

Const correctness and duck typing

I am a big fan of "const correctness" when programming in C++. It permits me to be a lazier programmer, but this is a good thing. It permits me to be a lazier programmer in the same way that these other language features do:
  • Using local variables instead of global variables
  • Using formal loop constructs like "for", "while", and "do", instead of "GOTO"
  • Using iterators instead of looping with "for", "while", and "do"
  • Program to interfaces instead of implementations
It is possible to write robust computer programs using only global variables, while branching using only GOTO statements. It simply requires more discipline on the part of the programmer. I am grateful that modern languages have features that permit me to be less disciplined while still writing maintainable code. The application of "const correctness" is one such language feature that make programs easier to write and maintain. I am amazed that it does not appear in other languages that I use, such as Java and Ruby.

Sometimes Java and Ruby fanboys who do not understand what const-correctness is will assert that one can get the effect of the const keyword with "final" in Java or "freeze" in Ruby. That is utter nonsense.

On the other hand, it is possible to get some of the const effect in Java by creating separate "ConstInterfaces" for each class. Unfortunately, such interfaces do not already exist for the standard library, and I believe that it is not possible to retroactively declare existing classes to conform to a particular Interface, even if they (syntactically) already do conform. The only alternative is to create derived wrapper classes for each standard class, explicitly declaring ConstInterfaces. Even this Herculean approach will fail with the many "final" classes in the standard library. In keeping with the general ultra-wordiness of Java, the reams of additional source files and lines of code required to emulate const-correctness in Java make this approach essentially extinct in the wild.

Ruby fanboys make a big deal about "duck typing", which is a fancy way of describing a lack of static typing. Static typing means that something about the type of each variable can be determined in the local source code context. "Duck typing" is more flexible than static typing in the same way that GOTO statements are more flexible than formal loops. The one big advantage of lack-of-static-typing is that it permits languages like PERL and Ruby to have essentially zero compile time. I love the possibilities that zero-compile-time languages create. But please do not overextend this tradeoff and pretend that "we meant to do that" and that "duck typing" is somehow a desirable language feature. Put the kool aid down.