Thursday, July 22, 2010

In reply to Structural versus Nominal typing

Let's start with a claim from a wikipedia page:

"Comparison:
Nominal typing is useful at preventing accidental type equivalence, and is considered to have better type-safety than structural typing."

Wow, where did that come from? Well, not everybody knows it but inheritance, one of the core software resuse concepts in object oriented programming, is not a guarantee for sub-typing. In other terms, inheritance, the fact that as a programmer you declare a class (identified by a name) is a subclass of another one (identified similarly) doesn't guarantee that the Liskov substitution principle can be applied. This is due to the fact that one can actually replace implementation of non-final methods in any subclass, changing behaviour of current implementations.

This is probably one of the reasons the makers of the Spring framework have a guiding principle "open for extension, closed for modification"; basically sealling most implementation methods with final.

On the other hand, we are already seeing the world of structural types creeping into the OO space: the introduction of "generics" is nothing but the realization of the OO community that parametric polymorphism - a concept developed within structural type systems, namely those with Hindley-Milner type inference - is a better way to express programmer's intentions. And what's a generic type? Yes, it's a type defined by structure, not by name.

So, what's the obsesion in OO -and particularly in Java- with names?

I agree that names are important. Two tuple types of (double, double), one used for cartesian coordinates and the other for polar coordinates should be named properly so programmers are protected from mixing them up. Yes, naming is important in this context.

But I believe this is not always the case. Enter the debate of closures for example. In java you need to declare (i.e. give a name), to every closure you intent to use, and the programmer has to implement that interface. Since its inception, every knew that this was very verbose.

From a programmer's perspective, I believe that for simple cases we already have a way to tell what's expected: the parameter's name.

So, instead of declaring an interface:

interface ValidItem {
boolean isItemOk(Object item);
}

just to be able to provide something like

class Something {
...
void checkAll(ValidItem test) { ... }
...
}

It should be enough to do it like:

class Something {
...
void checkAll(isItemOk:Object -> boolean) { ... }
...
}

Which is the way you do it in FP (Haskell, Ocaml, Clean, etc).

So, bottom line, in Java the descriptive power of a parameter's name is underestimated.

I'm already hearing "but this is only for simple cases". Well, one of the core principles of maintenable code is simplicity, the overarchingprinciple in Clean Code book. So, this should be sufficient in most cases... well, given that you were able to provide a type signature, which you are not at the moment.


No comments:

Post a Comment