Loren Segal writes a blog discussing the question whether users of dynamically typed languages are just
too lazy to type? The argument goes roughly like this: The dynamic is not in "passing wildly arbitrary ever-changing types to methods" and we're just (okay, not only just, but mainly) doing dynamic code generation and are too lazy to add type information. Regarding a particular, but not too relevant code example, Loren says:
It’s easy to see that this code is executed immediately at load time. Although it’s possible for someone to generate a method at run-time (by run-time I mean much later after the initial .rb file was require‘d), it’s a fairly rare occurrence. What we’re really doing here is just avoiding to extra LoC involved in typing out those def’s each time. What we’re doing here really is just runtime code generation.
Yes, Loren, it's just runtime code generation, but calling it 'just' is somewhat misssing the point. I mean, if runtime code generation is not dynamic, what is? Loren goes on to say that
programs in dynamic languages with these runtime modification behaviours often stop modifying their behaviour after a certain amount of "load time".
I agree, this is also what I would expect. But the entire point is that once again, "dynamic" means that it is not necessary that you have to (statically) pre-determine at some fixed time (compile time or initial process launch time) which stable behaviour it should be.
Of course, after a certain amount of load time, it's likely that the behaviour of your program (or better said of the running process) becomes stable and all functionality needed is loaded. But a different process of the same program may use a different set of possible behaviour. Plus: you might be able to add new functionality to a running programm. Additionally, you don't necessarily have to provide all possible behaviours at start-up time, runtime code generation (or runtime code loading) allows you to add new behaviour later on. In some cases (Ruby and Lisp come to mind) it is even possible to alter existing behaviour. Now, if "typical" dynamic programs really don't do that routinely (as suggested by the studies Loren is citing) this says more about how often we (really don't) need such dynamic behaviour but it sure is dynamic.
However, I must admit that I'm a little surprised by the cited results of the studies. I've seen systems that have the ability to change their behaviour at runtime one time too often. First, there are programs that embed some extension mechanism (be it embedded scripting languages, plugin mechanisms or other) that are specifically crafted for users to tinker with the running system, which clearly is all runtime code generation. Second, a particular interesting aspect of web programming is that many templating engines have some kind of import/include statement that are typically used to build complex templates out of smaller ones. In combination with other features of template languages, specifically conditions, loops and even macros (cf.
stupid template languages,
not so stupid template languages) this feature can be and is used to alter behaviour at runtime. So, obviously there is a need for dynamic behaviour, and people find ways to scratch their itch. Note that neither of my two examples require dynamic languages, so it's not a rebuttal of the studies or Lorens claims. However, thinking about it, I would expect that a lot of programs written in your todays typical dynamic language are 'scripts', which might be the reason why most people treat the idea of 'dynamic language' as synonym to 'scripting language' (it isn't -- Common Lisp, for instance, is surely a dynamic language, but hardly a scripting language). That such scripts don't require much dynamic change in runtime behaviour isn't too surprising, after all.
Now ultimately I wouldn't really disagree with the impression that quite often one "value" of dynamic languages lies in reduced typing and that on the contrary some type related problems would be found more quickly in static typed languages. I would even go so far and say that wrt.
I’d really love to see some research on case studies of how often arbitrary structural typing (that cannot be refactored into polymorphic relationships) is really used in dynamically typed languages. If anyone knows of any research/papers in this field, I’d love to hear about it.
it's highly likely that it's extremely rare to find "arbitrary structural typing", if such a thing exists at all (ironically I would guess that using 'void *' as a type specifier in C functions is where one comes closest to "arbitrary"). To me the very idea looks suspiciously like a strawmen for an argument that if there were "no arbitrary structural typing", we could/should go for static typing anyway, as we could "reduce" the solutions we implement with dynamic typed languages to solutions in statically typed languages (an argument coming close to the 'turing complete' hammer). This looks like a distinction between 'we can't use type information at all' and 'we need to use type information at each and every place' and I don't believe that the world is only black or white.
The point I want to make is this: Let's assume it may be very much the case that in all places where dynamic typing is used you can find a static typed solution, too. Then the benefit is of course not that "you're doing something that's not possible in statically typed languages" (which might still be true under the interpretation that the statically typed solution probably looks rather different). But there might be plenty of room for benefit in that coming up with a solution in the dynamic language might reduce cost (e.g. less development time, greater flexibility for extension later on). The arguments by proponents of static languages that the cost reduction lies in other aspects (e.g. earlier detection of errors) are surely worth a comparison. If studies for this question of associated costs beyond anecdotical tales exist, I would be interesting in seeing them.
Update:
Uncle Bob raises another important point that with introducing static type information we'll get closer coupling:
But in the end, we like dynamic language not because we are too lazy to "Type". We like dynamic languages because we are tired of untangling couplings.