Classification according to type vs function - An anecdote

Hi guys,

I would like to share with you a silly experience that happened over the weekend that got me thinking about object orientation/classification and how it affects, (and was affected by) the different ways in how individuals classify and manage bits of information or real objects in the world around themselves.

I recently bought a painting for my girl-friend's lounge, but I didn't get a chance to put it up for her over the weekend, so she got her father to come around to do it for her. He brough along his toolbox (he sells professional tools (Snap-on, KingTony, etc) for a living, so he's a DIY type through and through). Something came up however just as he was about to put the painting up, so he just neatened everything up and left the tools there for me to use.

The art gallery I bought the painting from, kindly and conveniently included a number of frobbitzim, such as hooks, masonry nails, wood screws for the frame, string, etc, all in a little plastic bag.

So last night I get a chance to put the painting up, and lo and behold, the plastic bag with all the goodies is nowhere to be found.

Aggravated, and cursing and muttering, I strip-search the apartment, including her father's toolbox, and the baggie is still nowhere to be found. So Iresort to looking in the trash. There it is, the plastic bag. But empty. And the goodies are not in the trash along with it.

So I go take a close look at the toolbox. My g/f's father decided that, as part of the neatening up, the frobnitses needed sorting as well. His toolbox includes one of those organiser things on the side, so he put the the screws along with their little friends in the screw compartment, the masonry nails along with the existing nails in the nails compartment, and the hooks in the 'misc' compartment, and so on. The string defied classification so it ended up in the bottom of the toolbox. The baggie itself ended up in the trash because it didn't have a purpose anymore.

So here I am aaarghing away, scratching through all the compartments to find MY frobbnitzes, all the while muttering under my breath: why?....why?....why oh why oh why?

All of this was perfectly acceptable to my girlfriend as well, who obviously thinks exactly like her father. To them, it's perfectly logical to classify and group things according to type, instead of according to function. To my way of thinking, the plastic bag was a perfect object that encapsulated all of its members, and the whole's purpose was OBJECT_TYPE_FOR_ERECTING_PAINTING, so leave it be, darnit!

To me it doesn't matter that a screw is of type TScrew, what was important to me was that I had a number of different types that belonged together as a functional whole, grouped according to one singular purpose. The object-oriented programmer in me was screaming inwardly at what I thought to be a very illogical thing to do, but obviously the difference is in human perspective and way of information classification.

I wonder now if OOP is not hard for some programmers to grasp simply because intuitivly they classify information according to type instead of function, and because they think in terms of data pools that are manipulated using functions or operators.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Interesting

wonder now if OOP is not hard for some programmers to grasp simply because intuitivly they classify information according to type instead of function, and because they think in terms of data pools that are manipulated using functions or operators.

Maybe so. I think I have had that problem, even though I think I have gotten rid of to a certain extent. For whatever reason, I tend(ed) to think more naturally about functions acting on objects instead of objects that happen to have methods. Maybe it's because certain class-based OO languages have felt too static for me. But I think a language like Ruby has mitigated that feeling to a certain extent with open classes, mixins, and duck typing.

I've also been interested in Prototype based OO, and posted a forum topic on LtU. OOPLs seem to have a more flexible feel to them.

Both sides were correct; the problem was the lack of typing.

The screws you wanted to use for the painting are of a subtype of type Screw. Your father-in-law obviously used the wrong type, because you failed to provide the correct type for the screws.

On the other hand, you implicitely used strong typing, without declaring it: your set of screws was a different type of normal screws. Your screws were about 'hanging the painting on the wall', while the rest of your father-in-law's screws are for any issue that might arise.

The problem with OO languages is that they do not define the type system over values, but over definitions. For example, a class X is a type. That is wrong though, because the exact definition of X might be of type Y or Z, depending on function.

A toolbox is a limited taxonomy

One issue, of course, is that your GF's father's toolbox is a very limited taxonomy. Assuming it looks like most toolboxes, it has a rectangular arrangement of bins; and no object can be in more than one bin at once.

Software systems are not necessarily so constrained (though some are); it's perfectly natural in the world of SW to be able to "sort" things by form, then by function, or by any other property you want. (One bin for fasteners which are an inch long; another for those which are an inch and a quarter, etc...) The physical limitations of the physical toolbox forced a choice of classification criteria; and he and you made different choices.

Regarding OO languages, there is a lot of confusion, naturally, between a "class" and a "type"--confusion that doesn't come up in most FP languages due to a lack of subtype polymorphism. If I define a Base class, and then a Derived class that inherits from Base--the set of objects which are of type Base is a superset of the set of objects which are of classBase. The set of objects of type base is equal to the set of objects of class Base, and every subclass. The set of objects of class Base are those which are constructed by uttering the syntax "new Base" (in Java), and no more. If Base is an abstract base class; the set of objects of class Base is empty.

One can emulate FP-style type definitions (named algebraic sums) using inheritance, but it's a lot more typing:


List : NIL | { car: Object, cdr: List }

can be directly translated into inheritance like this:


abstract class List {};
class EmptyList extends List {};
class ListElem extends List { car: Object; cdr: List };

Doing so goes against the grain of OO style; so in most OO languages a List type is implemented with a single class; with logic within the methods to handy the empty case. The other issue in OO is that most OO languages assume that a list (and a list element) will be mutated--but most OO languages disallow type migration (or else make it expensive), so the differences in behavior between an empty list and a non-empty list have to be handled outside the type system.

A couple more differences.

In an OO-language the set of subtypes isn't a closed set. It would be nice if I had a static guarantee that there are only two subtypes of List, allowing me to guarantee that I've exhaustively handled all the cases.

Also, the OO-style definition has the advantage in that EmptyList and ListElem are types; I can write a "tail" function that only accepts "ListElem" parameters, which gives me a static guarantee that I will never try to "tail" an empty list. I'm sure some functional languages support something similar, but Haskell and ML don't (right?). I guess Haskell type classes could mimic the OO style, but then you lose the benefits of the algebraic datatype style.

Title de jour

Haskell & OCaml both throw exceptions on "tail []" and "tl [];;". But, I don't see how the OO-style prevents exceptions.

I'm assuming that, for a reference myListObject of class ListElem, myListObject.tail() has return type List, so it may return an object of type EmptyList or ListElem. If it has only one element, then myListObject.tail().tail() should compile and fail at runtime as well.

Ahem

Although interesting, I don't think the story is a good analogy to types or programming. First of all, you were not expecting her father to organize anything at all, be it by type or function. If an analogy has to be made, I'd say it's a project management/documentation problem.

People who try to classify things at inappropriate times find themselves unable to dress since clothes belong in the closet. No, it's not of OBJECT_TYPE_TO_WEAR_BEFORE_GOING_OUT, it's a shirt, and it must be hung in the closet.

What aggravated me was the se

What aggravated me was the seperation of the "TGoodyBag" class into its constituent bits, when it wasn't neccessary at all, which ultimately forced me to search through the pools of objects for what I needed, when it would have sufficed to keep the instance intact .

It was sort of akin to having global lists of TScrew, TNail, etc, then taking the members of the TGoodyBag class instance and adding the member values to the appropriate list, freeing the TGoodyBag instance, then thereafter having to do a search through each list to find the member you need. Hardly efficient, in my eyes.

The screws you wanted to use for the painting are of a subtype of type Screw. Your father-in-law obviously used the wrong type, because you failed to provide the correct type for the screws.

The types of the members were irrelevant to the purpose of the TGoodybag class, but my gf's father obviously thought that it was. It was the deconstruction of the funtional whole that I found illogical, especially considering that everything inside the bag was specialised to the purpose at hand. That they inherited from a more generic class type was immaterial. That property of each item does not automatically mean that it is appropriate to place them along with other descendants of the ancestor type.

It would have been a good excercise after the needed objects were consumed and the excess placed in the type pool, but not before.

One issue, of course, is that your GF's father's toolbox is a very limited taxonomy. Assuming it looks like most toolboxes, it has a rectangular arrangement of bins; and no object can be in more than one bin at once.

Ah, but if Compartment inherits from Toolbox, then the object resides in both Toolbox and Compartment at the same time. It would have been good to leave the instance intact inside Toolbox instead of stripping the members into all the instances of Compartment.

People who try to classify things at inappropriate times find themselves unable to dress since clothes belong in the closet. No, it's not of OBJECT_TYPE_TO_WEAR_BEFORE_GOING_OUT, it's a shirt, and it must be hung in the closet.

I don't quite get the thrust of your example because it implies to me that containers can only accept objects, not release them for use. Objects don't exist to be contained, they exist to be used. Thus the purpose of your shirt is not to be hung in a closet, but to be worn.

Just like a computer cannot "use" all its objects at the same time, you cannot "use" all your shirts at the same time. To that end, I consider the closet to be a generic buffer, with the same sort of taxonomy as the toolbox, except that the sub-containers may be more specialised (you don't hang your Manolo Blahniks on hangers or keep your shirts in shoeboxes).

Lol. Talk about extending the analogy :-)

Buffer overflow

Next time my girlfiend complains that she needs more closet space, I am SO going to burst out laughing.

I hope she won't get offended when I mutter something about garbage collection...

I actually use a garbage coll

I actually use a garbage collection scheme for my closet space. (I think its even multi-generational.)

Object Lifetime or is it refe

Object Lifetime or is it reference counting? :-D

GC in everyday use.

Now I feel less geeky for trying to define which algorithm I'm using to clean up my house. Lately I'm using a generational, mark and compact, GC but I'm trying to use regions ;)

Use a library

Another solution would be to abstract the implementation of GC away, and just use some COTS library. This has its own costs and security issues, though.

Bigger issues

Such schemes tend to be too conservative in some cases and too aggressive in others. Usually they can't effectively figure out what's still reachable from root (it may look old and used, but that's *my* pile of Cardelli's papers and I like them right where they are).

hm, reference counting I thin

hm, reference counting I think

Screws are not special..

Doesn't this make the error that only the screws provided with the picture are suitable for hanging it. We may assume all screws of the correct size are equivalent. Selection of screw does not depend on the picture however, but the type of wall it is to be hung on, so I don't see how sorting into the toolbox makes this any less efficent.

I think the difference in approach stems from experiance. If you only have one picture to hang, it makes sense to keep the fixings together. On the other hand a proffesional picture hanger will be used to finding all sorts of different circumstances, and looking in the right section of his toolbox. They will also keep the leftover fixings for future use on other types of wall.

There were no other suitable

There were no other suitable screws, trust me on this. Not only were there no other suitable screws, there was no other nylon string or triangular hook fittings. I had to dig the tiny wood screws for the frame from among a motley assortment of metal screws and self-tappers. There were no masonry nails in the box to start off with, again, a motley assortment.

Plus, there were no leftovers from the specialised baggy.

It was a perfect instance. There was no purpose whatsoever in my gf's father's "sorting" of the items - it was an excercise that was 100% focused on the type of the items instead of on their ultimate purpose, which in my eyes does not bode well for a DIY man's efficiency :-p

You are both right here

The problem is the sorting happened too soon - the component bits were still most likely to be used together, so they need to stay together. After the picture was hung, the left over parts (nails for a different wall type) should be sorted, so that if the next project happens to need some weird screw it can be found (if it exists) by looking in the screw drawers, not through each of the compartments, each containing an open plastic bag with some stuff removed.

As an alternate view, if GF's father was a pro picture framer he might sort the parts out, but there would be compartments for each size of screw (so the 6x12x.5 isn't mixed with the 8x12x.5). The string would be thrown away because there is a bulk spool to cut the exact length you need off of.

Or back to the OO example, until the picture is hung, each part is in the picture hanging materials container (which is associated with that particularly picture). After the picture is hung you sort them into more generic containers if you might find them useful elsewhere too, otherwise you throw them out.