View mode: basic / threaded / horizontal-split · Log in · Help
April 30, 2009
Fixing the imaginary/complex mess
D currently allows some conversions between complex/imaginary types and 
real types, which are highly dubious.

Given creal z, ireal y, these casts are legal:
real x = cast(real)z;
x = cast(real)y; // always sets x==0, regardless of the value of y.
But I believe that should not be legal.

For the first case, it should be written as:   real x = z.re;
(which is shorter and clearer), and the second case is probably a bug, 
and should be x = y.im; (unless the intention really was to set x=0!).

By the same logic, we could have sqrt(-1)==0, since the real part is 0.

The most important effect of disallowing these casts would be to fix a 
host of bugs and wierd behaviour. All the A op= B operations involve a 
cast to A. If those nonsensical casts become illegal, the nonsensical 
op= operations become illegal automatically.

Eg, ireal y;
y *= y; // mathematically nonsense, y*y is real, so can't be stored in a 
pure imaginary type!

There are a few segfault/ICE bugs (eg 718, 2839) which involve 
int/=complex, an operation which never makes any sense anyway.

I think we're just making problems for ourselves by allowing these 
useless operations. I think they should be killed.
Does anyone object? (If not, I'll create a patch to do it; it's not very 
difficult).
April 30, 2009
Re: Fixing the imaginary/complex mess
== Quote from Don (nospam@nospam.com)'s article
> D currently allows some conversions between complex/imaginary types and
> real types, which are highly dubious.
> Given creal z, ireal y, these casts are legal:
> real x = cast(real)z;
> x = cast(real)y; // always sets x==0, regardless of the value of y.
> But I believe that should not be legal.
> For the first case, it should be written as:   real x = z.re;
> (which is shorter and clearer), and the second case is probably a bug,
> and should be x = y.im; (unless the intention really was to set x=0!).
> By the same logic, we could have sqrt(-1)==0, since the real part is 0.
> The most important effect of disallowing these casts would be to fix a
> host of bugs and wierd behaviour. All the A op= B operations involve a
> cast to A. If those nonsensical casts become illegal, the nonsensical
> op= operations become illegal automatically.
> Eg, ireal y;
> y *= y; // mathematically nonsense, y*y is real, so can't be stored in a
> pure imaginary type!
> There are a few segfault/ICE bugs (eg 718, 2839) which involve
> int/=complex, an operation which never makes any sense anyway.
> I think we're just making problems for ourselves by allowing these
> useless operations. I think they should be killed.
> Does anyone object? (If not, I'll create a patch to do it; it's not very
> difficult).

I'm totally ok with you creating such a patch and applying it, as I don't use
complex numbers anyhow, but if we're going to look at fixing complex numbers,
shouldn't we discuss whether they even still belong in the core language?  IMHO
they don't because D's user defined types have advanced pretty significantly since
the decision was made to put them in, and they're a *very* niche feature.  The
only people who need complex and imaginary numbers are scientific computing
people, and not all or even most scientific computing people need them.

Show of hands, how many people here actually use D's complex numbers on a regular
enough basis that you would miss them if they were removed from the core language
completely?
April 30, 2009
Re: Fixing the imaginary/complex mess
Don wrote:
> D currently allows some conversions between complex/imaginary types and 
> real types, which are highly dubious.
> 
> Given creal z, ireal y, these casts are legal:
> real x = cast(real)z;
> x = cast(real)y; // always sets x==0, regardless of the value of y.
> But I believe that should not be legal.
> 
> For the first case, it should be written as:   real x = z.re;
> (which is shorter and clearer), and the second case is probably a bug, 
> and should be x = y.im; (unless the intention really was to set x=0!).
> 
> By the same logic, we could have sqrt(-1)==0, since the real part is 0.
> 
> The most important effect of disallowing these casts would be to fix a 
> host of bugs and wierd behaviour. All the A op= B operations involve a 
> cast to A. If those nonsensical casts become illegal, the nonsensical 
> op= operations become illegal automatically.
> 
> Eg, ireal y;
> y *= y; // mathematically nonsense, y*y is real, so can't be stored in a 
> pure imaginary type!
> 
> There are a few segfault/ICE bugs (eg 718, 2839) which involve 
> int/=complex, an operation which never makes any sense anyway.
> 
> I think we're just making problems for ourselves by allowing these 
> useless operations. I think they should be killed.
> Does anyone object? (If not, I'll create a patch to do it; it's not very 
> difficult).

Since you're looking into this already, I suggest we move for the kill 
and eliminate built-in complex.

Andrei
April 30, 2009
Re: Fixing the imaginary/complex mess
Don:
> I think we're just making problems for ourselves by allowing these useless operations. I think they should be killed. Does anyone object? (If not, I'll create a patch to do it; it's not very difficult).<

I agree to disallow/fix those things.
And thanks for your work!

-------------

dsimcha:
>Show of hands, how many people here actually use D's complex numbers on a regular enough basis that you would miss them if they were removed from the core language completely?<

D is in a flux state still, so I think very few engineer/scientists are using it (I am not using complex numbers). So probably the answers your will receive will not be enough to judge future true usages of the D language.
A possible solution is to remove complex types now from D2 (moving them in Phobos and Tango), and later if enough people ask for them, to put them back into the built-ins.
Are there problems in adding them back later if they are asked for and regarded as useful?

-------------

Andrei Alexandrescu:
>Since you're looking into this already, I suggest we move for the kill and eliminate built-in complex.<

Is the current semantics fully doable with std lib complex numbers?

Bye,
bearophile
April 30, 2009
Re: Fixing the imaginary/complex mess
Andrei Alexandrescu wrote:
> Don wrote:
>> D currently allows some conversions between complex/imaginary types 
>> and real types, which are highly dubious.
>>
>> Given creal z, ireal y, these casts are legal:
>> real x = cast(real)z;
>> x = cast(real)y; // always sets x==0, regardless of the value of y.
>> But I believe that should not be legal.
>>
>> For the first case, it should be written as:   real x = z.re;
>> (which is shorter and clearer), and the second case is probably a bug, 
>> and should be x = y.im; (unless the intention really was to set x=0!).
>>
>> By the same logic, we could have sqrt(-1)==0, since the real part is 0.
>>
>> The most important effect of disallowing these casts would be to fix a 
>> host of bugs and wierd behaviour. All the A op= B operations involve a 
>> cast to A. If those nonsensical casts become illegal, the nonsensical 
>> op= operations become illegal automatically.
>>
>> Eg, ireal y;
>> y *= y; // mathematically nonsense, y*y is real, so can't be stored in 
>> a pure imaginary type!
>>
>> There are a few segfault/ICE bugs (eg 718, 2839) which involve 
>> int/=complex, an operation which never makes any sense anyway.
>>
>> I think we're just making problems for ourselves by allowing these 
>> useless operations. I think they should be killed.
>> Does anyone object? (If not, I'll create a patch to do it; it's not 
>> very difficult).
> 
> Since you're looking into this already, I suggest we move for the kill 
> and eliminate built-in complex.
> 
> Andrei

Ehhh.... why not leave complex and just kill imaginary? That'd solve 
most of the problems.
April 30, 2009
Re: Fixing the imaginary/complex mess
Robert Fraser:
> Ehhh.... why not leave complex and just kill imaginary? That'd solve 
> most of the problems.

You can't remove only half of a feature of the language, so I don't like this idea.
I accept to remove them fully if their semantics can be fully replaced by the std lib. Otherwise just let Don fix the broken things.

Bye,
bearophile
April 30, 2009
Re: Fixing the imaginary/complex mess
Don wrote:
> D currently allows some conversions between complex/imaginary types and 
> real types, which are highly dubious.
> 
> Given creal z, ireal y, these casts are legal:
> real x = cast(real)z;
> x = cast(real)y; // always sets x==0, regardless of the value of y.
> But I believe that should not be legal.
> 
> For the first case, it should be written as:   real x = z.re;
> (which is shorter and clearer), and the second case is probably a bug, 
> and should be x = y.im; (unless the intention really was to set x=0!).
> 
> By the same logic, we could have sqrt(-1)==0, since the real part is 0.
> 
> The most important effect of disallowing these casts would be to fix a 
> host of bugs and wierd behaviour. All the A op= B operations involve a 
> cast to A. If those nonsensical casts become illegal, the nonsensical 
> op= operations become illegal automatically.
> 
> Eg, ireal y;
> y *= y; // mathematically nonsense, y*y is real, so can't be stored in a 
> pure imaginary type!
> 
> There are a few segfault/ICE bugs (eg 718, 2839) which involve 
> int/=complex, an operation which never makes any sense anyway.
> 
> I think we're just making problems for ourselves by allowing these 
> useless operations. I think they should be killed.
> Does anyone object? (If not, I'll create a patch to do it; it's not very 
> difficult).

It might be a good idea to write in the docs why these operations are 
missing. Even better would of course be if the user got a message 
stating that this operation isn't implemented because it doesn't make 
mathematical sense.

If the latter isn't done, then many people will just think there's 
something wrong with the compiler/language. Bad press we don't need.
April 30, 2009
Re: Fixing the imaginary/complex mess
bearophile wrote:
> Robert Fraser:
>> Ehhh.... why not leave complex and just kill imaginary? That'd solve 
>> most of the problems.
> 
> You can't remove only half of a feature of the language, so I don't like this idea.
> I accept to remove them fully if their semantics can be fully replaced by the std lib. Otherwise just let Don fix the broken things.
> 
> Bye,
> bearophile

It's not necessarily "removing half a feature". Imaginary numbers aren't 
closed under many operations. The idea is that imaginary literals are 
turned into complex. So "ireal x = 10i;" becomes "creal x = 0 + 10i;". 
Since complex numbers are closed under all the builtin operators, it 
eliminates many of the problems (casts from complex to real).

Putting it in a library eliminates the ability to use complex/imaginary 
literals (unless it's a runtime type).
April 30, 2009
Re: Fixing the imaginary/complex mess
Robert Fraser wrote:
> Ehhh.... why not leave complex and just kill imaginary? That'd solve
> most of the problems.

The reasons for a separate imaginary type are listed in the D docs at
<http://digitalmars.com/d/2.0/cppcomplex.html>, referencing William
Kahan’s “Branch Cuts for Complex Elementary Functions, or Much Ado About
Nothing’s Sign Bit”.

It just doesn’t have to be a built-in type anymore.

—Joel Salomon
April 30, 2009
Re: Fixing the imaginary/complex mess
Robert Fraser wrote:
> Putting it in a library eliminates the ability to use complex/imaginary 
> literals (unless it's a runtime type).

Yah, but then I'm thinking: how many numeric literals are in a program 
at all? I think the vision of the mad scientist that uses one imaginary 
literal every five lines of code is quite unreal :o).

Andrei
« First   ‹ Prev
1 2 3 4
Top | Discussion index | About this forum | D home