Yes, I thought it was an intriguing title too, especially prefacing an entry on the blog of the only Computational Theologist I know of.
It's an intriguing idea, and his paper introducing the topic is very readable. I recommend it.
I've lost track of the number of heated arguments I've had about whether or not static typing is "better" than dynamic typing. Bracha's point is that this focuses on the wrong distinction. It's not (in his opinion) whether or not you have a static or dynamic type system, but rather whether or not it's optional or mandatory.
I always like to cast abstract concepts in concrete terms. It tends to illuminate them. I'm also in favour of pragmatism over hand-waving. If it can't be cast in practical terms, then it's value is questionable. So what does an optional type system really mean? There's a tendency to suggest practical examples using Lisp or Smalltalk. Without meaning to suggest that either of these are hand waving, I'd suggest that they're hardly the most accessible way of presenting an abstract idea in languages. So what does it mean in terms of Java (this applies just as much to C#)?
Imagine for a moment that you never had to specify the type of a variable in Java. I submit that you'd be able to write a lot of Java code much faster. Yes, a lot of that code would be broken (static typing has some very definite advantages) but you'd have turned Java into a flavour of Python (in some respects anyway) and there are definitely some jobs where it's faster to use Python than Java.
This comes at a price though. Some things are no longer possible. For example, overloading methods isn't possible because there's no way for the compiler to differentiate between the following two methods:
foo(my_map)
foo(my_set)
Written as Java code today these would look like this:
foo(Map my_map)
foo(Set my_set)
and the compiler could use the type information in the parameters to make a decision about which method you intended to invoke. It's debatable how much of a loss this is. Personally, I don't think losing the ability to overload methods is a huge loss and with a slight change in how you structure solutions it's possible you might never miss it.
Perhaps a bigger loss would be IDE support for things like auto-completion (how does the IDE know what methods exist on an object if it doesn't know the type?), or refactoring (how does the IDE make sure every instance of a method name has been changed if it can't check the type of variables in other code?).
A much bigger loss is that of interfaces. Yes, it's possible to tack something like interfaces onto a dynamic language (PEP 245 is proposing an approach for Python) but it tends to be very clunky and requires a fair bit of additional dynamic introspection in your code. Interfaces are essentially a contract between two objects and they tend to work rather well when cast in the form of a type.
So you lose a lot by removing static typing. But you also gain a lot, mostly in terms of flexibility. Bracha also points out that by tying a language to a type system you increase its complexity significantly, usually to a point where formal verification is no longer feasible. Which means you can't prove things about the language which limits the domains in which it is useful. If a language is dependent on its type system for something like security (as Java is) and you can show the type system to be broken, then it's pretty much tickets for the language (from a security perspective).
Optional typing proposes the following. Let's separate the type system from the language. This makes formal verification simpler because you're only dealing with a grammar and we know quite a bit about parsers by now. So your language doesn't depend on a type system at all. We've seen that this requires some thought from the language designers. Certain things (like overloading) are no longer possible. But, we'd prefer not to throw the baby out with the bathwater, so let's allow the type system to be "enabled" optionally. This means that your IDE could apply type checking while you're developing your code, if you wanted it to. So if you like (or feel more comfortable) with squiggly red lines under variables when you cock it up then switch it on. If you're trying to whip out a quick 15 liner to get something done pronto and feel confident in your abilities then switch it off.
But that's perhaps easier said than done. Where is the IDE going to get the type information it needs to play the blame game? With a language like Java (or C#) you could mark things up using meta-data (annotations). This gives tools (like your IDE) the information they need to work with, without forcing it onto the language. Instead of typing
int foo;
you would type something like
@int foo;
The important thing to realise here is that the type information is optional in the second example. It isn't required by the language specification. It features nowhere in the grammar.
So why would we do this? Well, there are a few benefits worth considering. If it turns out your type system is flawed, then you can fix it. The language isn't broken, just your type system. If Java's type system (today) turns out to be broken, then for many applications it would mean back to the drawing board. Applets, for example, rely heavily on bytecode verification to be able to make guarantees about what they can and can't do to your porn collection. This verification depends crucially on Java's type system. If it's broken, so are Applets.
It also becomes possible to plug in diffferent type systems. Why would you want to do this? Well, it's been shown that a range of static analyses can be represented as type systems. Some make guarantees about aliasing (show me a C++ programmer who hasn't been caught by this), others make guarantees about the flow of information through your application (Java relies on this to a degree to catch potential references to uninitialized variables). Throwing all of these into a language would make the language unmanagable, and would also force you to deal with restrictions imposed by one of those type systems which really only make sense in another context (another project, another team, another industry). Essentially you could choose how strict (and exactly what strict means) based on the project you're working on.
It has certain appeal. In many respects it seems to bring a language one step closer to being universal. This alone gives me pause for thought: I firmly believe in choosing the right tool for the job. Languages have strengths and weaknesses and trying to make a language into something it's not usually degrades the language (in my opinion). Another way of saying this is that I don't believe in the idea of a universal language.
Hmmm.