Re: Is Static Typing a Form of Bad Coupling?
Posted: Apr 12, 2006 3:00 PM
> Im just a beginner at Haskell, but type inference is
> really quite cool. At the lowest level, programs work with
> literals, which have known types. When I say
x =, I can pretty much assume that x is of type int.
> Well, lets more broadly assume its an integer, without
> making any assumptions about the number of bits involved.
Looks like I'm going to be learning Haskell soon time permitting, because the local Silicon Valley Patterns group is going to have a track on it. So after that I may be better able to understand the issues.
But I think there is a bit of confusion in this discussion about what I mean by optional versus implicit typing. Let me clarify what I mean, and you can correct me if I'm not using the terms correctly. To me, implicit typing means that, as in Java, every variable and expression has a type known at compile time (or say, at the source code level), but, unlike Java, I as the programmer don't always have to explicitly say what it is. A type can be inferred from context, as in the example you provide. The language defines the rules for type inference, and then that allows me to express a fully statically typed program with less verbosity.
Optional typing to me means that you may or may not define a type, not just write it out, but actually define it. In an optional typing language, therefore, if you leave the type declaration out, the variable actually doesn't have a type. That variable can hold onto anything, as in Python.
For example, given:
j = 1
In a type inferencing language, j would get the type int. An alternative way to say it would be explicit:
int j = 1
But in both cases, j is defined to be type int. If you next tried to assign a string to it, it wouldn't compile:
j = "won't compile"
In an optional typing language (I don't know of one of these, but Guido's discussion of doing this in Python is I would think an example of the concept), however, if I say:
j = 1
The j variable doesn't actually have a type, other than object. It can hold a reference to anything, which means later on I could quite happily assign a string to it:
j = "this does work"
But if I were to add the optional type declaration, as in:
int j = 1
After that, j does have a type, and I couldn't assign a string to it.
j = "this won't fly, because j is an int"
It occurs to me that Java is actually kind of an optionally typed language in the sense that I can use reflection to invoke a method that matches a signature. So Java kind of has optional typing, but the ugly verbose syntax I have to go through to do things the reflection way really points me in the static typing way. Perhaps what Michael and Guido and you are talking about is starting with a dynamically typed approach to quicken the development, then later as things grow you can add type information in to give the program some maintainability benefits of static typing if the program actually does get big.
One problem I see is that I'm not sure how much of those static typing analysis benefits you get if static typing is optional. If the whole program isn't statically typed, I'm not sure the benefit is worth the cost of programming in a static style. Take refactoring for example. If I change a method signature in Java, then my IDE can go out and find all places that call the method that need to be updated, and it can help me update it. Or if I do it by hand, I can change the signature, compile, and the compiler will give me a do list of places I need to go fix. If a method is being invoked in the dynamic way, via method signature matching from an untyped variable, the tool can't be sure it is a place to change. Because at runtime you could be invoking a method with the same signature but in a different class. And in Java, in fact, niether the refactoring IDE nor the compiler can usually help me find places where the method was being invoked via reflection, places which I broke by changing the method signature.
Lastly, I made this point earlier, the freedom you get with the dynamic approach is you can change types at runtime. In Rails, for example, they instantiate a controller object for each incoming HTTP request, and populate it at that time with one field for each POST or GET parameter. Each request kind of gets its own class. It is very powerful, but there is no mention of these dynamically created classes at the source code level. So you can't add types to them later. They don't exist in the source. So if you're planning on doing that later, you might avoid doing the metaprogramming stuff in the dynamic language, which means you'll be missing out on half the benefit of that language.