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@3 value: 4@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@keyww.com