[squeak-dev] Complex isNumber

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Complex isNumber

Nicolas Cellier-3

Though my advice was to keep this change out of the image, it came in
3.9 or 3.10, i don't know...
Complex isNumber allows a lightweight fix of Number = Complex bug.

BUT TOO MUCH CODE RELY ON A DIFFERENT BEHAVIOUR!

In less of one minute of browsing, i can construct a fail test like:

self shouldnt: [Dictionary at: 1 i  put: 'a complex number'; at: 2 put:
'a number'; explore] raise: Error

Guess what, the failing method is called keysSortedSafely... But with
this change in, nothing that was safe yesterday will be safe again ;-).



I recommend AGAIN to browse senders of isNumber and find maybe the one
or two that are prepared for an instance of Complex.

MOST are expecting (isKindOf: Number), and not any number out of the set
of real numbers.

This is consistent with traditional Smalltalk implementation, all
subInstances of Number are in the set of real
(well except Float nan and Float infinity which were not in St-80).



I proposed isNumberExtension so that other Number extensions like
Quaternion can be added too without a rewrite
(http://bugs.squeak.org/view.php?id=2688).

This had no success, maybe the selector is not very well chosen...
I don't care, call it what you want, but please, not isNumber,



The bugs are minor, because fortunately, Complex are hardly ever used,
so we can as well let this change rot in the image as is.

Personnally, i vote thumb down.

Nicolas


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Complex isNumber

Stéphane Rollandin
+ 1

... and my own proposal would be to merge Complex and Point.
very simple, since a Complex IS a Point in the Argand plane.

http://en.wikipedia.org/wiki/Complex_plane

this would help a lot doing geometry graphically. I'm doing a lot of
useless and costly conversions from Point to Complex (and the other way
round) in some of my math code.

Stef


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Complex isNumber

Nicolas Cellier-3
Stéphane Rollandin a écrit :

> + 1
>
> ... and my own proposal would be to merge Complex and Point.
> very simple, since a Complex IS a Point in the Argand plane.
>
> http://en.wikipedia.org/wiki/Complex_plane
>
> this would help a lot doing geometry graphically. I'm doing a lot of
> useless and costly conversions from Point to Complex (and the other way
> round) in some of my math code.
>
> Stef
>

It almost works except multiplication and division...

(0 @ 1) * (0 @ 1) is not (-1@0).


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Complex isNumber

Igor Stasenko
Vector
   |
------------------------
|        |              |
Point |              Point3D/Vector3D
         Complex

Why not move common behavior to Vector class, and make rest be subclasses?

Point class>>new
  ^ super new: 2

And few selectors like:
#isVector
#isScalar


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Complex isNumber

Nicolas Cellier-3
Igor Stasenko a écrit :

> Vector
>    |
> ------------------------
> |        |              |
> Point |              Point3D/Vector3D
>          Complex
>
> Why not move common behavior to Vector class, and make rest be subclasses?
>
> Point class>>new
>   ^ super new: 2
>
> And few selectors like:
> #isVector
> #isScalar
>

Possibly.
Again same argument about *.

We all expect 1 i * 1 i = -1.
Though few will name such an operation *:
{a. b} asVector * {c. d} asvector = {a*c-(b*d). a*d+(b*c)} asVector

Nicolas


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Complex isNumber

Andreas.Raab
In reply to this post by Nicolas Cellier-3
If the goal is to fix Number vs. Complex comparison, isn't the correct
behavior to renormalize Complex numbers when they are indeed reals?
I.e., my attitude would be to fix Complex such that (1 + 0i) results in
a real number (the integer 1) instead of the complex (1 + 0i). In which
case the comparison problem solves itself. Lacking this, I would rather
have comparison fail for real vs. complex and require clients to be
explicit where they mix them, e.g., force you to write "x asComplex = y".

In any case, pretending to be a number when indeed Complex is lacking
half of the protocol of numbers is not the right way to address the problem.

Cheers,
   - Andreas

nicolas cellier wrote:

>
> Though my advice was to keep this change out of the image, it came in
> 3.9 or 3.10, i don't know...
> Complex isNumber allows a lightweight fix of Number = Complex bug.
>
> BUT TOO MUCH CODE RELY ON A DIFFERENT BEHAVIOUR!
>
> In less of one minute of browsing, i can construct a fail test like:
>
> self shouldnt: [Dictionary at: 1 i  put: 'a complex number'; at: 2 put:
> 'a number'; explore] raise: Error
>
> Guess what, the failing method is called keysSortedSafely... But with
> this change in, nothing that was safe yesterday will be safe again ;-).
>
>
>
> I recommend AGAIN to browse senders of isNumber and find maybe the one
> or two that are prepared for an instance of Complex.
>
> MOST are expecting (isKindOf: Number), and not any number out of the set
> of real numbers.
>
> This is consistent with traditional Smalltalk implementation, all
> subInstances of Number are in the set of real
> (well except Float nan and Float infinity which were not in St-80).
>
>
>
> I proposed isNumberExtension so that other Number extensions like
> Quaternion can be added too without a rewrite
> (http://bugs.squeak.org/view.php?id=2688).
>
> This had no success, maybe the selector is not very well chosen...
> I don't care, call it what you want, but please, not isNumber,
>
>
>
> The bugs are minor, because fortunately, Complex are hardly ever used,
> so we can as well let this change rot in the image as is.
>
> Personnally, i vote thumb down.
>
> Nicolas
>
>
>


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Complex isNumber

Nicolas Cellier-3
Andreas Raab a écrit :
> If the goal is to fix Number vs. Complex comparison, isn't the correct
> behavior to renormalize Complex numbers when they are indeed reals?
> I.e., my attitude would be to fix Complex such that (1 + 0i) results in
> a real number (the integer 1) instead of the complex (1 + 0i). In which
> case the comparison problem solves itself.


I share this view. That's how VW did, like 4/2 won't answer a Fraction.
The only advantages of making Complex static are i guess to have things like

        (-4 + 0 i) sqrt

behave differently than

        -4 sqrt

(or try ln, because base image Complex does not even understand sqrt).

Two alternatives are having a special complexSqrt (does not sound good),
or modify Number>>sqrt.

VW propose to raise Exceptions and provide handlers, but i don't feel it
satisfying. I want some library of code to be Complex-free and raise an
Error, whether or not invoked from a complex-full part.


  Lacking this, I would rather
> have comparison fail for real vs. complex and require clients to be
> explicit where they mix them, e.g., force you to write "x asComplex = y".
>

Yes very much like Point:
0 = (0 @ 0). "false"
(0 @ 0) = 0. "false"
(0 @ 0) = 0 asPoint. "true"


> In any case, pretending to be a number when indeed Complex is lacking
> half of the protocol of numbers is not the right way to address the
> problem.
>
> Cheers,
>   - Andreas
>

Indeed, you formulated it better.
It's like we are trying to mix above two approaches with dangerous hacks.

Nicolas


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Complex isNumber

Nicolas Cellier-3
In reply to this post by Nicolas Cellier-3
nicolas cellier a écrit :

> Igor Stasenko a écrit :
>> Vector
>>    |
>> ------------------------
>> |        |              |
>> Point |              Point3D/Vector3D
>>          Complex
>>
>> Why not move common behavior to Vector class, and make rest be
>> subclasses?
>>
>> Point class>>new
>>   ^ super new: 2
>>
>> And few selectors like:
>> #isVector
>> #isScalar
>>

Also think that sooner of later, one will need to work in C^n rather
than R^n, so don't even expect instances of Number in inst.var.

I think we could learn much from Axiom. I remember they had to introduce
multiple hierarchies. Not exactly multiple inheritance, but something
better structured.

Nicolas


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Complex isNumber

Andreas.Raab
In reply to this post by Nicolas Cellier-3
nicolas cellier wrote:

>     -4 sqrt
>
> (or try ln, because base image Complex does not even understand sqrt).
>
> Two alternatives are having a special complexSqrt (does not sound good),
> or modify Number>>sqrt.
>
> VW propose to raise Exceptions and provide handlers, but i don't feel it
> satisfying. I want some library of code to be Complex-free and raise an
> Error, whether or not invoked from a complex-full part.

Good points. Though, I would argue that for practical purposes there is
probably very little difference between raising an error or going
complex when you request -1 sqrt.

No code that I have seen has ever taken a "corrective" approach to the
problem (by handing the negative sqrt condition and fixing the problem
in the handler) but always been preemptive. Either by checking the input
or by having separate methods which are implied to check the input (for
example we use #arcCosClamped which implicitly clamps the input to -1
... +1 in situations where we may get results out of range due to
conversion problems).

Code that isn't preemptive in this manner is very likely going to blow
up either way and I don't think it matters very much if that is because
of the negative sqrt or some follow-on problem with Complex. In
particular considering that unless you use the "corrective" approach
your code is broken to begin with if it allows unintentional negative
input. Checking the image (there are only 34 senders of sqrt in 3.9)
certainly indicates that the usage of sqrt is almost always related to
length calculations in which case this whole discussion is moot.

So from my perspective it would be completely fair to take the only
sensible interpretation of -1 sqrt and create a Complex by default.

Cheers,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Complex isNumber

stephane ducasse
In reply to this post by Nicolas Cellier-3
Nicolas
I always thought that the complex class was plain bad. Can I infer  
from your email
that I was wrong and that it is worth keeping it?

Stef

On Mar 11, 2008, at 10:58 PM, nicolas cellier wrote:

>
> Though my advice was to keep this change out of the image, it came  
> in 3.9 or 3.10, i don't know...
> Complex isNumber allows a lightweight fix of Number = Complex bug.
>
> BUT TOO MUCH CODE RELY ON A DIFFERENT BEHAVIOUR!
>
> In less of one minute of browsing, i can construct a fail test like:
>
> self shouldnt: [Dictionary at: 1 i  put: 'a complex number'; at: 2  
> put: 'a number'; explore] raise: Error
>
> Guess what, the failing method is called keysSortedSafely... But  
> with this change in, nothing that was safe yesterday will be safe  
> again ;-).
>
>
>
> I recommend AGAIN to browse senders of isNumber and find maybe the  
> one or two that are prepared for an instance of Complex.
>
> MOST are expecting (isKindOf: Number), and not any number out of the  
> set of real numbers.
>
> This is consistent with traditional Smalltalk implementation, all  
> subInstances of Number are in the set of real
> (well except Float nan and Float infinity which were not in St-80).
>
>
>
> I proposed isNumberExtension so that other Number extensions like  
> Quaternion can be added too without a rewrite (http://bugs.squeak.org/view.php?id=2688 
> ).
>
> This had no success, maybe the selector is not very well chosen...
> I don't care, call it what you want, but please, not isNumber,
>
>
>
> The bugs are minor, because fortunately, Complex are hardly ever  
> used, so we can as well let this change rot in the image as is.
>
> Personnally, i vote thumb down.
>
> Nicolas
>
>
>


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Complex isNumber

Paolo Bonzini-2
In reply to this post by Andreas.Raab

> So from my perspective it would be completely fair to take the only
> sensible interpretation of -1 sqrt and create a Complex by default.

I fully agree.

Regarding sorting, in GNU Smalltalk I did something, ahem, bold and
decided that comparison methods would compare the absolute values.
Well-behaved applications won't call comparison methods on complex
numbers anyway.

Paolo

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Complex isNumber

Andres Valloud-3
Note that there are some contexts in which getting an error when doing
-1 sqrt is perfectly valid.  For example, if the idea is to implement
pythagoras' theorem, then taking the square root of a negative number is
an indication of deep trouble somewhere.

The issue is that there are some other contexts in which getting 0 + 1i
is reasonable, and that because the determination of what should happen
cannot be made at compile time, whatever decision is made is wrong by
definition.

There has to be a way in which a number knows it belongs to the "real"
(or their rational approximations usually used in computers) or to the
complex numbers.  If numbers knew this, then there could be two
different implementations of sqrt, and since the choice of which number
to use would be done at compile time (as instructed by a developer
clearly revealing his/her intention) there would be no confusion
regarding what is the correct course of action for the given situation.

It's funny... I was just thinking of this in a different context a
moment ago... unfortunately I haven't figured out a way to do this I am
happy with yet.

Andres.

Paolo Bonzini wrote:

>
>> So from my perspective it would be completely fair to take the only
>> sensible interpretation of -1 sqrt and create a Complex by default.
>
> I fully agree.
>
> Regarding sorting, in GNU Smalltalk I did something, ahem, bold and
> decided that comparison methods would compare the absolute values.
> Well-behaved applications won't call comparison methods on complex
> numbers anyway.
>
> Paolo
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Complex isNumber

Stéphane Rollandin
In reply to this post by Nicolas Cellier-3
nicolas cellier a écrit :

> Stéphane Rollandin a écrit :
>> + 1
>>
>> ... and my own proposal would be to merge Complex and Point.
>> very simple, since a Complex IS a Point in the Argand plane.
>>
>> http://en.wikipedia.org/wiki/Complex_plane
>>
>> this would help a lot doing geometry graphically. I'm doing a lot of
>> useless and costly conversions from Point to Complex (and the other
>> way round) in some of my math code.
>>
>> Stef
>>
>
> It almost works except multiplication and division...
>
> (0 @ 1) * (0 @ 1) is not (-1@0).

right, this would have to refactored. I wonder how many
"multiplications" of Points we currently have in the image...


Stef


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Complex isNumber

Nicolas Cellier-3
In reply to this post by stephane ducasse
stephane ducasse a écrit :
> Nicolas
> I always thought that the complex class was plain bad. Can I infer from
> your email
> that I was wrong and that it is worth keeping it?
>
> Stef
>

There are a few complaints on mantis.
It is incomplete (no sqrt, conjuguated, etc...).
And some cosmetic requests (I'd like Complex to be renamed ComplexNumber
and isComplex isComplexNumber).

But overall, it was usable for me after a few extensions i put on
SqueakSource Math-Complex-Extensions.

Implementation choice to keep (1+0i) a Complex rather than
auto-converting to a Number is not light but it enables programmer to
select where and when to use Complex extensions.

I think the reason to remove it is that it is not used at all.
Complex implementation is cool with this respect, because there are no
overriden methods.

We should make it an optional package on Squeak source/Squeak map, not
all users need Complex numbers after all.

Nicolas