Home

Simplicity rules - in the right place

In Cafe au Lait Java News and Resources, a guy named Elliotte Harold does a perfect job to show what kind of guys write Java books these days (well… come to think of it–most days).

If you fail to make the distinction between telling an object to hand out its first element or asking it to give you the element at index 0 (or at index 1–there you start already. What about index ‘A’ for some other kind of list?), you haven’t even started to come close to understanding the idea of encapsulation. If you think that simpler means something “whip up a basic API and dig into the object innards where the API stops”, you need to learn a lot about OO.

“How often do you need to get to the first item of a list”? Well, every time I use it as a FIFO. Oh wait - Java probably has a separate class library for that. JFXSCL or something…

Granted - if all you have is one monolithic API then more than a handful of functions in the API quickly becomes a nuisance. So I’m very glad that Smalltalk has method categories, so the 437 methods in Object or the 137 in Collection don’t get in the way. Of course, in Squeak you often don’t even have to browse the API, just go to the Method Finder and type in an example of the operation you’re looking for.

My favorite analogy here: the difference between a human and a donkey is maybe 5% in genes. I like to think that a good object system works the same - the difference in behaviour between my classes, if you count everything they inherit, is typically 1-5%. Just a handful of methods, with usually a couple of lines of code because the base classes are so rich. Now, that is where simplicity rules.


Stumble it!  Post to del.icio.us 

14 Responses to “Simplicity rules - in the right place”

  1. Isaac Gouy Says:

    “Well, every time I use it as a FIFO. Oh wait - Java probably has a separate class library for that.”

    java.util.Vector
    firstElement() lastElement()
    have been around since Java 1.0

  2. JoeJoe Says:

    They were discussing List, not Vector.

    Vector is also frowned upon and ArrayList as touted as it’s successor. Guess what? No first or last method in there, either.

  3. Isaac Gouy Says:

    JoeJoe hold your frowns - what makes you think ArrayList should be used as a queue?

    Wouldn’t we use one of the classes that implements the java.util.Queue interface? They don’t implement first/last either but they do implement peek.

  4. Robert Sanders Says:

    “If you fail to make the distinction between telling an object to hand out its first element or asking it to give you the element at index 0 (or at index 1–there you start already. What about index ‘A’ for some other kind of list?),”

    This is not an issue of explsing the implementation. A List is a collection of objects, held in some defined order, which can be numbered 0 to n-1 for a List of size n. In fact, for LinkedList, that has *nothing* to do with the implementation. It is a contract. If you want the n’th element, you ask for it.

    Whether the numbering contract is 0-based or 1-based is really a separate question. There’s no arguing taste.

    If you wished to number your list according to the words in the OED, great, that’s up to you. But it’s not a very convenient system. I have no idea what index ‘A’ for a List (as opposed to a Map) means, and if you did tell me what it means, I’d just mentally translate that into an ordinal number. So why not use ordinals to begin with?

  5. cdegroot Says:

    Robert, you’re right, of course. I was barking up the wrong tree there. Can I defend myself with being under the influence of influenza when I wrote that?

    In any case:

    This is not an issue of explsing the implementation. A List is a collection of objects, held in some defined order, which can be numbered 0 to n-1 for a List of size n.

    Or, as you say, as 1..n. Which is where you start getting the benefit of intention-revealing selectors–if you code a stack or a FIFO, just operating on the list by sending it #first, #removeLast, etcetera, you abstract away from the underlying implementation and towards the reader of your code, making clear what you intended (instead of what the author of the underlying library code you’re using implemented).

  6. Victor Volle Says:

    hm, perhaps there is rule of thumb that could be used to decide when to prefer “humane” over “minimalist” (and vice versa): a class that is very basic (like a List) and therefore used in many different ways should rather have a human interface. A class that is rather specialized, seldom used, should tend to have a minimalist interface. The reasoning is about weighing the learning curve (+minimalist) against code duplication (+humane).

  7. cdegroot Says:

    I think that things like encapsulation, intention-revealing names and code duplication prevention should be the only deciding factors here - they decide what goes where, and then you end up with an interface.

    Now, that interface might be larger than you’d wished for, especially if you are writing some code that you hope will be reused by others. In Smalltalk, then comes the final “refactoring”, categorizing the various parts of your interface. In theory, you could categorize your interface into “basic” and “advanced” (and “private”, of course) categories, but more often the categorization is more functional (”accessing”, “updating”, …). In either case, this goes a long way towards making class interfaces more approachable to developers that aren’t completely familiar with the class.

  8. truth machine Says:

    This is one of the stupidest “technical” discussions, which took place over numerous blogs, written by some of the stupidest people (with a few exceptions), that I have ever read on the web. Language theocracy, unsupported opinion being passed off as wisdom, insight, or logical argument, numerous factual errors about the classes being discussed, and a steady stream of shed-painting. Which class library is designed correctly, Ruby’s or Java’s? Neither — they could both be improved. Neither is completely Humane or Minimalist — but no competent programmer or designer could want the latter; it’s completely counter to good design principles, and seems to be based on the false dichotomy that what isn’t minimal is bloated. Of course what isn’t minimal is unnecessarily redundant, but only in a very formal sense — it isn’t unnecessary to achieving goals of lower cost, higher production, greater robustness. Even Sun figured this out, as it has added to Java quite a bit that was obviously missing (while numerous Java theocrats crafted sophistic rationalizations for why it was a /good/ thing that the language was crippled).

    Ironically, in Ruby you can say array[-1], which, /for arrays/, has the same semantics as (is /defined/ as) array.last (but not so for other objects, which makes it non-redundant), whereas in Java you have to say array.get(array.size() - 1) (or getLength instead of size for ArrayList, sigh), which /is not/ defined as accessing the last element and isn’t recognizable as such, since the /calculated/ index is an integer just like any other. Aside from the fact that it takes slightly more space and time (the

  9. truth machine Says:

    Ack! You have a length limit? And throw the rest away? What horrible horrible horrible engineering … any concern about Minimalist vs. Humane pales in comparison.

  10. truth machine Says:

    “Whether the numbering contract is 0-based or 1-based is really a separate question. There’s no arguing taste.”

    It’s not a matter of taste. If C had used 1-indexing, then a pointer to an array would have had to point to the element preceding the array … which would have been a different address depending on the type of the pointer (so, e.g., casting int* to char* would have required runtime arithmetic). This obviously would have been insane. Java is derived from and is supposed to resemble C, so it would obviously have been a very bad idea to switch from 0-indexing to 1-indexing, and of course interfacing with the OS or C extensions would have been error-prone. These are just the most obvious reasons why 0-indexing is /objectively/ superior, for those languages at least. (There are numerous other cases where it’s useful for “index of” and “offset to” to be the same thing.)

  11. cdegroot Says:

    @truth machine: sorry for the truncation. It seems to be a standard Wordpress feature, you’re the first one to hit it.

    About 0-vs-1 indexing: you made a point about the C family. That doesn’t mean it’s a valid point across all languages.

    Oh - and please keep your ad-hominem attack mode in check. Calling people stupid is at best counterproductive in *any* discussion :)

  12. Tucows Services » Tucows Developer Blog > Blog Archive » Monkey Knife Fight! (or: Not Much Has Changed) Says:

    […] Cees deGroot: “My favorite analogy here: the difference between a human and a donkey is maybe 5% in genes. I like to think that a good object system works the same - the difference in behaviour between my classes, if you count everything they inherit, is typically 1-5%. Just a handful of methods, with usually a couple of lines of code because the base classes are so rich. Now, that is where simplicity rules.” […]

  13. Global Nerdy » Blog Archive » Monkey Knife Fight! (or: Not Much Has Changed) Says:

    […] Cees deGroot: “My favorite analogy here: the difference between a human and a donkey is maybe 5% in genes. I like to think that a good object system works the same - the difference in behaviour between my classes, if you count everything they inherit, is typically 1-5%. Just a handful of methods, with usually a couple of lines of code because the base classes are so rich. Now, that is where simplicity rules.” […]

  14. cdegroot Says:

    Funny - somehow another analogy than the human/donkey one struck me, closer to home: you write and deploy a website on a stand-alone Linux box with basic LAMP stack. Then you write and deploy a second website on another stand-alone Linux box with basic LAMP stack.

    Of the total code base of these boxes, what percentage is different? 0.1%, maybe? Yet that one percent makes all the difference between the two sites.

    It could be argued that these LAMP boxes have “too rich API’s” and that it should be trimmed down to just the bare necessities. Somehow, though, I’d think it’d be harder to do this trimming down and rebuild your Linux box “just for that single site” with simple building blocks all the way up from the kernel (I’m a systems thinker, so I look at systems :-) )…

Leave a Reply

(note: comments may be moderated so don't always appear right away)


Copyright (C)2000-2005 Cees de Groot -- All rights reserved.