## [squeak-dev] intersect: when intsersects: is false

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Sun Jun 20 09:32:46 UTC 2010

```2010/6/20 Joachim Geidel <joachim.geidel at onlinehome.de>:
> Whatever is thought to be the "correct" answer, please have a look at the
> result of this method in other Smalltalk dialects. I recently had the
> unpleasant experience of having to work around minor incompatibilities
> between VisualWorks, Squeak and Pharo. Please don't add another one. OTOH,
> if it is already different, that would a chance for unification.
>
> >From the point of view of correctness: There is no such thing as a Rectangle
> which is the intersection of non-intersecting rectangles. The "correct"
> answer could be to raise an exception, similar to what happens for a
> division by zero, or to answer nil. Both would certainly break a lot of
> existing code. (0 at 0) corner: (0 at 0) is completely wrong IMO. While it is
> empty in a mathematical sense, it would give you answers for #origin and
> #corner and many other messages which are complete nonsense. One could just
> leave it as it is, because the precondition for answering a "correct"
> rectangle is that the receiver and the argument intersect. If the don't, the
> answer is undefined, which means that whatever is answered is correct in a
> mathematical sense. So the third option besides nil and an exception would
> be to document the precondition in the method's comment.
>
> Whatever you do, please keep it compatible with other Smalltalk dialects!
>
> Just my 2c.
> Joachim Geidel
>
> Am 20.06.10 10:36 schrieb Frank Shearar:
>
>> On 2010/06/20 00:58, Jim Rosenberg wrote:
>>> [Using Squeak 3.8; apologies if more current versions "fix" this ... ]
>>>
>>> This expression yields false:
>>>
>>> ((0 at 0) corner: (50 at 50)) intersects: ((100 at 100) corner: (150 at 150))
>>>
>>> So, what should this yield?:
>>>
>>> ((0 at 0) corner: (50 at 50)) intersect: ((100 at 100) corner: (150 at 150))
>>>
>>> I was expecting perhaps nil. Instead I got (100 at 100) corner: (50 at 50).
>>> This is "a surprise". It's certainly not right mathematically ...
>>
>> It's still that way in trunk, at any rate.
>>
>> I do think that the current behaviour's wrong.
>>
>> In the interest of keeping the result of a #intersect: uniform, we could
>> return Rectangle origin: (0 at 0) corner: (0 at 0) instead of nil. (And we can
>> put that long expression inside a new method,
>> Rectangle>>emptyRectangle.) Then we could compose multiple #intersect:s
>> without special-casing anything.
>>
>> I think we just need a guard clause like
>>
>>      | aPoint left right top bottom |
>>      (self intersects: aRectangle) ifFalse: [^ self emptyRectangle].
>>
>>      "Rest of #intersect goes here."
>>
>> but I'm sure Nicolas Cellier will weigh in with a definitive answer :)
>>
>> frank
>>
>
>
>
>

Well, I never have a definitive answer - though I pedantically may seem to :)...
What I usually suggest is to put enough brain storming to help
reaching an answer that is least surprising indeed.
To me, least-surprising includes:
- uniform thru the library
- mathematically well grounded
The other rationale to be taken into account is simplicity.
And of course, cross-dialect compatibility is another pragmatic POV.

Nicolas

```