Static vs. dynamic type systems. It used to be an easy choice. Along with the rest of the human race, I make typos all the time. If I made a typo whilst typing a function call in some rarely-used bit of code, a static type system would tell me. Also, I’m a great believe in making computers do as much work as possible so that I can leave work on time and do something more fun. I like the idea of a compiler whirring away, checking lots of common mistakes for me. Letting go of that seemed dangerous…
But then I played with Squeak for a while and now I’m not so sure. Squeak is not just a nice development environment, it’s really nice. It’s very easy to do stuff. You want to find who calls this method? Easy. You want to find which methods use this instance variable? Easy. You’d like to extract this chunk of code into it’s own method. No problem.
Furthermore, the Squeak world is consistent. With C++, there are two worlds – compile time and run time. The compile time world is a swirl of types, methods and files. The run time world is a heady mix of memory addresses and instruction pointers. It’s nearly impossible to ask questions about types once you’re in the run time world. Never the twain shall meet. Debuggers provide an uneasy bridge between the two worlds, but you never have the full power of either. In Squeak, there’s just one world. Your source code is an object. The types you use are objects. The virtual machine is an object. You compile code by calling methods on a Compiler object. There’s no split, so there’s no distinction between “writing code” mode and “running code” mode, like there is in C++.
I have a feeling that Squeak’s flexibility is due to it’s runtime-typed nature. I don’t know if that’s 100% true. For example, a C++ compiler could very easily emit code so that each object contains a pointer to it’s type. I don’t just mean a typename, I mean a full description of it’s type – member variable names, their types etc.
In a way, this partly defeats the point of having a statically typed language. The reason you go to all that effort of figuring out types at compile-time is because you don’t want to do it at runtime. Having said that, not everything in C++ is an object so it’s not that easy.
I can’t finish an entry about type systems without mentioning that although C++ has a static type system, it really sucks compared to languages like ocaml and haskell. With these languages, you don’t have to specify any types in your program – the compiler will infer them all for you. They deal elegantly with parametric polymorphism (templates in C++) and haskell has a very neat type class system (like templates in C++ where the template parameter has to satisfy some condition, like “has operator< defined"). A perlmunger agrees.