Tuple Madness 4

Posted by Tim Ottinger Tue, 13 Feb 2007 12:07:16 GMT

If there is a downside to modern OO languages like Python and Ruby it is the great built-in list types. They’re wonderful, but they’re tempting.

Today I had my fourth or fifth encounter with tuple madness. It seems that the siren song of “free” data structures with unnamed members is just too much to resist. I’ve decided to call it Tuple Madness. An example is: x = (2,3,-1) Could one be less descriptive? Probably not.

I came across some code which uses two-tuples where both values are encoded integer values. It’s a pain to figure out.

In a previous job, a coworker would write his python entirely as filters on n-tuples so that figuring out what his code was doing was really painful. A function would take a sequence of n-tuples, and return a sequence of n-tuples where some of the values were preserved (though reordered) from the input, and the rest were transformations on the input + some local data. It was really tough to read a program where the data structures had unnamed elements and only existed between the return of one function and the invocation of the next.

At least one of my colleagues has blogged about suffering from Tuple Madness as well.

I don’t think that “magic tuples” are always evil, only that they’re no substitute for proper objects and meaningful data structures.

Trackbacks

Use the following link to trackback from your own site:
http://blog.objectmentor.com/articles/trackback/169

Comments

Leave a response

  1. Avatar
    Michel about 1 hour later:

    As an old scheme/lisper where tuple/list like structures is the core abstraction and being taught programming by reading “Structure and Incterpretation of Computer Programs” by Abelson and Sussman. You learn its a good idea to write accessors to your tuple structures to raise the level of abstraction and enhance readability.

  2. Avatar
    YAChris about 2 hours later:

    As another old Lisper, when I saw XML my first thought was “Named Parentheses!” My second thought was “GREAT!”

  3. Avatar
    Samuel A. Falvo II 5 months later:

    I prefer Io’s structures—they’re much more readable than XML. But I digress.

    It sounds like the Python coder has a strong functional programming background. You’ll need to become more familiar with functional programming to understand more clearly the reasons why he did things the way he did (and that will, in turn, help elucidate the code and make it substantially more maintainable).

    Still, taken to the extremes, writing ML code in Python is generally considered bad form by all parties around, including other ML coders. :)

  4. Avatar
    Tim 12 months later:

    No, I don’t think so. I understand the appeal of functional programming, and my problem is with the parade of obscure intermediate forms, all produced by obscure functions. Realize that I love “clear” and despise “clever”. I found this program to be very clever in its use of primitive structures, and not very clear at all.

    I don’t have the actual code, and it was very, very, very long, but it looked mostly like this (strawman):

    def t23(x):
            if x[7] == 'a':
               g = 8
            else:
               g = 4
            return  (x[0], x[9], x[4], x[5], x[3], g, x[1])
    

    Clearly, it rearranges some of the input elements, drops some, and adds a new derived value. It does so without any real reference to the meanings of the input, transformation, or output.

    Was there a meaning to that transformation? I would revisit it a few times, and still not know. It seemed to be arbitrarily decomposed and recomposed, as if the goal were to multiply intermediate forms. I suspect that Occam would have vomited.

    The issue is not with the use of filters, but that the function and the data it operates on are completely non-self-describing, and can only be understood by grasping the entirety of this absurd parade of intermediate forms, from program start to program end.

    A parade of meaningful forms, produced by meaningfully-named functions, operating on named variables, would have been quite welcome.

    Indeed, it seemed to me that some transformations only existed to rearrange the elements of the array to an order expected by the next filter, which rearranged the elements for uncertain reasons. Considering that all the transformations were local, non-reused, purpose-built, that seemed mad to me. Why not keep the smallest number of functions on the most consistent forms?

    Also realize the application was not number-crunching, was not parallel, and was not being run as a unix text filter. It was purpose built to manage mostly-textual structured data.

    The python programmer had just learned lisp a bit earlier. It may be that he was trying to write lisp in python. I may be wrong, but I don’t think that’s how it’s supposed to look. He once bragged about how deeply he’d nested his lambdas, so maybe it was a brand of cool built out of complexity for complexity’s sake.

    Python gives us unpacking syntax, so this could have been more clear, even if nothing was done to make it more simple:
    def reorderForSorting(x):
         first_name, last_name, birth_date, address = x
         return ( birth_date, last_name, first_name, address )
    

    Maybe I’m a piker here, but it seems that there should be a way to make any code more clear, so that it can be adapted and maintained. Is that not a goal?

Comments