One of the things he mentions that I found interesting is in relation to Erlang's type system; more specifically, he claims static type checking would have made dynamic code upgrade virtually impossible. Can anyone shed some light on why this is the case, or perhaps give me a reference to a good paper on the topic? From looking at the example he gives it seems to me all you need is first class functions.
For example, over time you dynamically upgrade a module going from version 1 to 2 and, later, to version 3.
During the first module upgrade, data types from the newer module (2) can be incompatible with the data types from the older module (1).
Such incompatibilities are resolved dynamically during the upgrade procedure (implemented as a part of v2) which knows about type incompatibilities between versions 1 and 2.
After the upgrade from version 1 to 2, any subsequent module versions (e.g. 3) doesn't have to know anything about types from the initial module (1).
Isn't this still a problem in a dynamic language? For example in Erlang let's say my state is the 2-tuple. In version 2 I make it a 3-tuple but it stays the same in version 3 so it has no upgrade code. Consider the same situation with any code where the middle version update adds data to your state.
I'm not sure why being statically typed would make hot code loading impossible. Can't you always interject some transformation function between updates? At the very worse you could have code to serialize your data structure right before update, then another function after the update to deserialize and turn it into the new structure. Am I missing something?
There are two things. First, although the above transformation is theoretically possible to achieve with statically typed language, it is for sure harder in practice. In contrast, in Erlang it is super easy and natural although it may often seem as ad-hoc. But being able to do something like like on the fly is tremendously useful in practice.
Second, which is more important -- in my first example, I forgot to mention about the ability to use two versions of the same module at the same time. Check the thread below for more details.
So would I be right in saying that to update a function from v1 to v2, in a statically typed language I can't change the function prototype, whereas with a dynamically typed language I can? Would I not still be somewhat limited in the latter case (e.g. I'd have to have the same number of arguments)?
I think you can do both in static and dynamic languages, but in dynamic language everything is just practically easier.
Another thing I forgot to mention, and it is more important than my first example, -- in Erlang, during the upgrade procedure, you can have two versions of the same module loaded simultaneously and their code can execute at the same time until all the code starts using functions from the second module. Basically, when you call a function, you can specify explicitly to call it the current module or from the new module. I can hardly imagine how you can get away with it in statically-typed language.
If you are interested in the topic I recommend reading Joe Armstrong's PhD thesis. It describes this and many other advanced topics in detail. Actually, it changed the way I think about concurrent and fault-tolerant systems and languages.
That's a really nice introduction to Erlang and much better than the management cruft that usually fills CACM. Although, I haven't read it for about a year (due to the aforementioned cruft,) is this article indicative of an improvement of the computer science content?
Yes, CACM is less crappy in that respect than it used to be. There's still a fair amount of cruft, though. (Queue has more non-cruft, but it's now online-only.)