gah! I hate the new string syntax

Quinn Dunkan quinn at retch.ugcs.caltech.edu
Wed Mar 14 17:03:34 EST 2001


On Mon, 12 Mar 2001 17:56:33 +0100, Alex Martelli <aleaxit at yahoo.com> wrote:
>Focusing on the polymorphism needs, I see the issue in the mirror
>way from you: it's a _weakness_ (of Python and most other languages)
>that I can't add methods 'post-facto, from the outside' to existing
>objects -- it impedes the most natural, elegant, typeswitch-free way
>to add functionality.  If you pursued your "capitalize as a function"
>idea, you'd be unable to properly capitalize Unicode (e.g.) without
>a typeswitch -- a very unadvisable construct.  Something like Haskell's
>typeclasses, on the other hand, would provide the best of both worlds
>(multimethods would be an even more powerful alternative) -- let the
>compiler/interpreter/runtime do the dispatching, and just code in
>the most natural, polymorphic way.

Note that in ruby, any time you write

class Foo
    ...
end

you are adding to, not overriding, 'Foo'.  Thus,

class String
    def cap
        s = (if self[0].betwwen?(97, 122) then
                self[0] - 32
            else
                self[0]
            end).chr
        s + self[1 .. self.length]
    end
end

is perfectly valid ruby that does what he wanted.  I thought this sort of
thing was cute when I first saw it, but it makes me a bit nervous: I've
introduced a global change in a system-level class.  The problem is that, in
an imperative language, that change occurs at a pont in time.  It makes the
order I load modules of possible importance.  It could break client modules
who are expecting a "clean slate".

Naturally, in a statically-typed functional language like haskell, these
issues don't come up.  But in an imperative language, it's like frobbing
__builtins__ ---probably not a very good idea.

For classes that are not completely under your control, or if the
functionality is only of local interest, I think either a subclass or a
"external" function is better style (ruby provides "singleton methods", but
I'm happier with a plain non-OO function).

For example, I had a set of Cell objects that were to be displayed
graphically.  The display mechanism required that they each have a special tag
to keep track of their position on the screen.  The tag was useless to all
other clients of Cells, and not even computable by the Cell itself.  Unsure of
what the "official" solution would be, I wrote the tag computation as a
function of the display module, and had the display object cache the tags
internally.  It seemed more logical that way: the display mechanism should
keep track of its own administrivia.  But then I wound up with 'tagof(c)',
where 'tagof()' was a typeswitch on 'c', which is the sort of thing you're not
supposed to have in OO.

In haskell, I could have simply defined a 'Taggable' class and instances
implementing 'tagof' in the Display module... no problem.  But "traditional"
OO seems to make the solution much less clear...



More information about the Python-list mailing list