The old argument goes that static means fast, because the compiler knows what memory requirements are going to be needed, and dynamic means easy to code because you can change your mind about what a variable will hold. In PHP, $data can be a value one minute and an array of mixed objects the next. In Fortran, once declared an integer, always an integer.
But I suspect there is a hybrid possible. For the most part, my choice of type for a variable conveys information to the compiler for its compile-time work. It's a promise not to try to change the variable's type. But there are other ways to do that.
Suppose I take an otherwise dynamically typed language and add a language extension that allows loose declaration of type; I declare it to be a single variable, an object, a collection of objects, etc. Nobody really puts completely different things in $data, unless they're writing appallingly bad code.
So let me do this:
singlevar val = new String();
mixedarray outputCollection = array(i, 4.235, myObj);
singleobj house = new House();
Thus we give the compiler information it can use. I promise not to do too much funny stuff. But it means
- Flexibility: my IOobject can be a file, a socket or a commandline pipe with the flexibility of a dynamic language (singleobj myIOobj = getIOObjectFromHandle(thisHandle)).
- Compile errors: I can catch myself doing mySingleObj = objectArrayGenerator(); and fix it.
- Speed: My compiler is (presumably) doing much the same optimisation for all my fixed-length types, allocating my object handles on the heap, etc etc. And it can do that here, too. Variable length strings are tricky, I'll grant you, but leave them as objects.
- JIT compilation: hopefully the extra information can aid the JIT compiler
- Not annoying the coder: dynamic languages are great. You do what you mean to do, and you don't worry about what's coming back. Except that you do, for the most part, know what's coming back. Even if it's a function coming back and you're about to do a functional filter lambda thing with it, that's a good start.
- Confine implicit conversions to a single type strata: float to integer, integer to char array, these are easy. MyMixedObjectCollection to boolean? It's not even meaningful.
Templates should get a lot easier with these type strata - a vector of ints, floats, bools, all make some sense.
Perhaps this would lead the way to per-object overloading: destroy all these books but coat that one in paraffin - we understand exceptions to rules in the everyday world. Why not let us overload the destroy() method in this one, then pass the whole collection to be systematicallyDestroy()ed?
There is much for me to learn about functional programming, typing, OO and design patterns, so I'm not well placed to see whether this would all work. But in my mind, it spun a fine drop.