SYSTEM WARNING: Creating default object from empty value

SYSTEM WARNING: Creating default object from empty value

SYSTEM WARNING: Creating default object from empty value

Mantis - Squeak
Viewing Issue Advanced Details
2688 Kernel minor always 02-08-06 02:06 10-21-06 04:27
nicolas cellier  
new 3.8  
0002688: aNumber = (aNumber + 0 i) answer false
  should: 1 = (1 + 0 i)
  description: 'due to a premature
       isNumber ifFalse: [^false].
    this message answer false'.

self should: ((1+0i)=1) = (1=(1+0i)
  description: 'equality test should be commutative'.
aComplex cannot answer true to isNumber because it is not kindOf: Number.

isNumber test should be replaced with isArithmeticValue, and Complex Quaternion or whatever RealNumber extension should answer true to this one.

Note that VW has ArithmeticValue as superclass of both Complex and Number.
related to 0002689new  isComplex method name is bad 
related to 0003725closed  [FIX] ComplexTest>>testEquality 
related to 0004262closed KenCausey SUnit test ComplexTest>>testEquality fails for an collection 
related to 0004261closed  SUnit test ComplexTest>>testEquality fails for nil 
related to 0003311new  Complex Numbers are Wacky 
 ComplexEqualTest.3.cs [^] (763 bytes) 02-08-06 22:29
 ComplexEqualPatch.1.cs [^] (2,494 bytes) 02-08-06 22:29

nicolas cellier   
02-08-06 22:34   
I propose a test and a patch.

implement isNumberExtension in Object Complex Number (and future Quaternion Octonion etc... if any).

in = message, test isNumberExtension instead of isNumber.
if false, answer false.
if true, then proceed with current code (will fallback in adaptTo... and succeed).

Complex are Number extension, they can be equal to a number...
02-11-06 19:24   
added test to 3.9
nicolas cellier   
03-26-06 21:42   
Just to remind that proposed patch also cover this bug:

1 i = nil

(see '[BUG] Complex equality problem' on squeak-dev)
nicolas cellier   
05-08-06 10:33   
Another solution is discussed at [^]
10-19-06 06:37   
Note that the alternate implementation available via 0003311 ( [^] does NOT have this bug.

nicolas cellier   
10-19-06 21:04   
Hi Ken.

If you define (Complex>>isNumber ^true), then you suppress the bug, but you might also introduce new bugs for applications expecting only real numbers and testing that using message isNumber...

This is for thess backward compatibility reasons that i introduced a new message.
Alternatively, it would be necessary to add a isRealNumber message to Number, then replace some of the isNumber senders with isRealNumber...

Another reason is that ComplexNumber are not the only Number extensions as shown with my Quaternion example. In order to avoid same bug (1+0i+0j+0k)=0, Quaternion isNumber should also answer true, something that we could agree on, but which sounds less obvious than ComplexNumber (We do not name it QuaternionNumber...).
10-20-06 03:45   
Hi nicolas,

Exact reals might be implemented as continued fractions, linear fractional transforms... Reals might use interval math, ...

I don't see how having complex numbers not be numbers fixes the case where users of reals numbers expect a floating point representation.

There may be other bugs introduced, but I don't buy the "keep backward compatible bugs" argument.
nicolas cellier   
10-20-06 17:05   
Hi again,

1) exact real numbers are out of scope
2) i do not want the bug to survive, but proposed a more local cosmetic change than yours (message isNumberExtension).

Main advantage of my own patch is that it is cosmetic: it has very few chance of breaking current images and applications.
But on longer term, for sure i adhere to the deeper refactorings you are claiming.

The facts:
- isNumber is so far implemented and interpreted as a short cut for (isKindOf: Number).
- Complex is so far not a subclass of Number.

So isNumber is now synonym to (belong to R), and you propose a semantic change (belong to C).

This potentially is dangerous for existing applications. What would you buy for 2 imaginary euros on your bank account?
This is why if we adopt your semantic, we would need a different message telling that imaginary part is null (my isRealNumber proposal which would be true also for Integer and Fraction)

Other facts:
- (2 imaginaryPart) and (-1 sqrt) are not understood as Complex extensions
- instead, we have to explicitely create a Complex to obtain this behavior
- For this reason, complex with null imaginary part are not converted automatically to real Number part... (as would a Fraction with denominator 1 being converted to Integer).

If we want to change these behaviours, we should think of all implications, and refactorings it will imply.

I am not sure Complex should be a subclass of Number, considering some details like order relationship #< properties.
Another possibility would be the reverse class hierarchy. Every number is a complex number (eventually with null imaginary part)...

  ImaginaryNumber (Complex concrete class)

Maybe AlgebraicNumber should be automatically converted to Fraction when they are rational...
Where to put Float in this hierarchy is not that obvious... Float representation is just a special case of Rational... Except that operations are inexact.
FixedPoint are pure rational with different Display properties...

If we want to introduce Quaternion in such a scheme, we put AbstractQuaternion above AbstractComplexNumber and concrete Quaternion aside AbstractComplexNumber... Something powerfull, but not really lightweight...

Another possibility is to use Traits instead of inheritance...

So my point of view is that just changing isNumber semantic has not enough benefits by itself in order to justify backward compatibility problems it would introduce. Complex maybe deserve deeper changes so as to have a consistant model.

Finally should Quaternion isNumber return true?

10-21-06 04:27   
Ah, I am coming from a background of dynamic languages (Scheme, Lisp, Dylan) where: integer C rational C real C complex.

I am surprised to find someone that thinks differently.

E.g. in the Dylan class hierarchy:


What do non-squeak Smalltalks do? ANSI?