Double dispatching and Point

Travis Griggs tgriggs at keyww.com
Mon Feb 2 20:42:07 UTC 1998



David N. Smith wrote:

> At 13:37 -0500 2/2/98, Travis Griggs wrote:
> >Good points. I have never found any use for the Point < method as defined. I
> >have had reason to sort Points quite often, and have always done so using the
> >following sort block:
> >
> >[:a :b | a y = b y ifTrue: [a x < b x] ifFalse: [a y < b y]]
> >
> >True, it establishes a convention, but I've never wanted ambiguous sorting of
> >Points. Why not change the definition of < for Point. Does anyone use it to
> >their benefit as implemented now, and in such a way that would make the above
> >undesireable?
>
> Some random thoughts (sorted):
>
> (1) Well, an inside rectangle test is something like:
>
>    (p1 >= p origin) & (p1 <= p corner)
>
> (which is the definition of #between:and: in IBM Smalltalk, but not in Squeak).
>
> (2) Making such a change would be incompatible with other Smalltalk systems
> (and the new almost-standard if I recall correctly).
>
> (3) One thing bothers me about your sort block is that it presumes that
> points are lineralized along the Y axis. That is, a < b if its y value is
> less. Only if they are equal are the x values considered.
>
>    | lessThan |
>    lessThan := [:a :b |
>        a y = b y
>          ifTrue:  [a x < b x]
>          ifFalse: [a y < b y]].
>    lessThan value: 6 at 3 value: 4 at 5
>  true
>
> This result just looks odd to me: a value with a higher x coordinate being
> less than one with a lower coordinate.
>
> I guess the first test could use x coordinates, and I'd feel better, but
> why one over the other?
>
> (4) How about testing some other value, like the magnitude of the point
> (thinking in polar coordinates for a moment)? This isn't too slow if one
> compares the squares of the coordinates and fakes the signs.
>
> (5) Points are holders for numbers. One can well have a point with floating
> point or fraction values, or a mixture. This is quite valid:
>
>    (2/3)@7.5
>
> Some contexts may assume that points have integer coordinates, but that's
> their problem. If you add Point to some number hierarchy, what kind of
> coordinates classes are allowed? This is valid now:
>
>    ((2/3)@7.5) * (2/3)
>
>    Produces: (4/9)@5.0
>
> Would it still be? Should it be valid now?

I do things like the above all the time. I don't ever assume that Points are
composed of two SmallInteger values. If I do, I send truncated, or rounded, or
ceiling, or floor to them and get one that I know does abide by that rule. I find
the ability to mix simple numbers with Points very powerful and expressive. I find
it even more so with other numeric types I've done before. But I wanted to get
Point solved before implementing those.

This discussion has spiraled somewhat (which is a good thing I guess). A couple of
points stand out to me, not all conclusive. A large part of this discussion seems
to revolve around "why to inherit." For implementation or interface. Other
languages avoid (not necessarily solve) this problem by separating the two. My
proposition that Point be made a subclass of Number was driven by the
implementation one. The majority of Number's interface was also applicable to
Point, and could be implemented using the exact same code. It was driven by the
fact that as I made Point's interface be more compatible with Number's, I found
myself copy/pasting most of the methods. From a classification view though, 'twould
seem that Point should not be a subclass of Number - not because of what Number is,
but because of what Magnitude is. Some MI pundits would argue this is why we should
have MI - I don't know.

As for testing whether Point is less than another Point - it's all a hack. My
suggestion being one of the most obvious. What an obvious kludge to get around an
inheritence problem! And any method that gets put in place to make Point obey <
will be a hack, designed to somehow plug up the hole that is caused by inheriting
ultimately from Magnitude. So... what to do in a case like this? Inherit an
interface that is maybe not quite correct (but close) and reduce the amount of
duplicate code, or keep the inheritence tree pure and duplicate separate code
trees?

It seems that from the way I understand what Self does (and I'm not too solid on
this either), that delegation would solve this problem?

Travis Griggs
Key Technology
tgriggs at keyww.com





More information about the Squeak-dev mailing list