What is a "type"?

April 26, 2003 2:55 PM

ajeru1 still thinks we're being betrayed by types. I can't help thinking (s)he is mis-using typing to make a point. Particularly, the solution proposed in the first “we have been betrayed” article is just as inappropriate for these new problems as existing OO typing is. Certainly, if the thing deciding an object's state doesn't belong inside the object, then neither can the behaviour that results from that decision.

The Naming of Cats is a difficult matter,
It isn't just one of your holiday games;
You may think at first I'm as mad as a hatter
When I tell you, a cat must have THREE DIFFERENT NAMES.
     —T S Eliot, The Naming of Cats

In Java at least, an object's type represents three different things:

  1. The messages that the object will respond to. This defines the object's interface.
  2. The code that the object will use to respond to these messages. This defines the object's implementation.2
  3. An attribute of the object, of type Class.

Sometimes, people get stuck on the third one, and give it far more importance than is really necessary. There is nothing magical about the identity of an object's class. It's just another attribute of the object. Its primary value is as a way of determining which messages we can send to an object, something that is done often enough that Java gives us the short-hand operator instanceof instead of making us call Class.isAssignableFrom(). However, the existance of this operator shouldn't make us feel that the class attribute as an attribute is any more or less important than any other.

As ajeru notes, when you use the class as a straight attribute, it's incredibly inflexible because an object's class is immutable. There are various patterns you can use to change the behaviour of an object at runtime, or even to provide an extensible interface, but there's no way to change the attribute-value of an object's class. Which is fine, because you are still free to add as many read/write attributes as you like to an object.

Some languages do allow you to change the type of an object at runtime, or in the case of Smalltalk's become:, replace one object with another. This is still a terrible solution to the state-change problem, because the moment you have more than one set of states that need to be applied concurrently, you end up with a complete mess of classes.

Problems that arise from making things part of the type that shouldn't be tend to end up being “Doctor, it hurts when I do this!” problems. If the class is a bad place to store a certain bit of information about an object (i.e. whether a person is considered an adult or not), for whatever reason, then don't store it there! Your class heirarchy shouldn't correspond exactly to a real-world taxonomy; you shouldn't have every natural language is-a represented by a type in your program. That isn't the function of a class at all.

It's not the hammer's fault that you can't hammer in a screw.

1 memo to all bloggers: please put something on your weblog homepage making it clear what your name is, or at least what you would like to be referred to as. Usernames or page titles are just so impersonal.
2 For more on interface vs implementation, you might want to read my previous article, Inheritance Taxonomy

2 Comments

Is there a way to get in contact with areju? I'd like to talk to him/her about objects and the various problems she/he might like to think up. There doesn't seem to be a contact method on areju's site.

James Robertson accuses me of being blinded by Java's limitations at http://www.cincomsmalltalk.com/blog/blogView?entry=3228773964

I tried to post the following response, but got a fatal error on their site when I hit submit, so I shall put it here for anyone who followed the link:

Hey, I dig dynamic typing. I have certain questions as to whether it is really the God-send it's purported to be, but that's a story for a different day. Or maybe later this evening if I keep writing.

I fail to see, though, how the quoted section doesn't apply equally to a dynamic-typed system like Smalltalk.

Every Smalltalk object has a type that defines the messages it responds to, how it will respond to those messages, and is also accessable as an attribute of the object. (While the concept of interface isn't as important in Smalltalk thanks to dynamic typing, the concept still exists - the messages that an object responds to (and the contract it obeys for each message) are conceptually separate from the implementation. That's one of the major points of having an object in the first place.)

If you want to know for sure if an object will respond meaningfully (i.e. avoiding "doesNotUnderstand:") to a particular message, you have to query its type.

Essentially, my point was: "An object's class is just another attribute. Treating it as the be-all and end-all of an object's identity is a Bad Thing, and you certainly shouldn't blame this on Object Orientation itself", which holds true in any OO implementation.

The only Java-ism in the post was the idea that an object's class is immutable. Even taking "become:" into account, changing the object's class is a terrible solution for the stated problem, because once you have more than one set of states for an object (A customer can be a Child or an Adult. A customer can also be a Regular or Preferred customer), you quickly end up with a complete mess. You're _still_ better off with the State pattern.

Yes, Smalltalk is a great language. But don't use someone's bad modelling as a justification for that.

Previously: Cat-Strangling

Next: Classic Testing Mistakes