std.complex

Joseph Rushton Wakeling joseph.wakeling at webdrake.net
Fri Jan 3 09:04:33 PST 2014


On 03/01/14 14:32, Stewart Gordon wrote:
> I wasn't asking for it to go beyond the existing complex implementation or any
> other.  I was proposing that the arbitrary restriction be removed so that the
> implementation we already have would work on them.

Yes, but it isn't an arbitrary restriction.  Template constraints are 
fundamentally a promise to users about what can be expected to work.  Integral 
types, or library types, won't work without significant modifications to the 
internals of the code.  It would be a false promise to relax those constraints.

> FPTemporary is a template.  At the moment it's defined only for the built-in
> floating point types.  So what we really need is to define FPTemporary for other
> types.  For int and smaller integral types, we can define it as real just as we
> do for float/double/real.  Whether it's adequate for long would be
> platform-dependent.  For other types, I suppose we can reference a property of
> the type, or just use the type itself if such a property isn't present.
>
> One possible idea (untested):
> -----
> template FPTemporary(F)
>          if (is(typeof(-F.init + F.init * F.init - F.init))) {
>      static if (isFloatingPoint!F || isIntegral!F) {
>          alias real FPTemporary;
>      } else static if (is(F.FPTemporary)) {
>          alias F.FPTemporary FPTemporary;
>      } else {
>          alias F FPTemporary;
>      }
> }
> -----

Yes, it ought to be possible to redefine FPTemporary (or define an alternative) 
to determine proper internal temporaries for any "float-esque" case.  I was 
toying with something along the lines of,

     template FPTemporary(F)
         if (isNumeric!F || isFloatLike!F)
     {
         alias typeof(real.init * F.init) FPTemporary;
     }

... where isFloatLike would test for appropriate floating-point-like properties 
of F -- although this is probably far too simplistic.  E.g. how do you handle 
the case of a float-like library type implemented as a class, not a struct?

In any case, absent an appropriate test-case in Phobos, it would be premature to 
generalize the constraints for Complex or the design of FPTemporary.

> Oh yes, and it would be crazy to try and make it work for unsigned integer
> types.  But even if we were to resolve the issues with FPTemporary and that, it
> would still fall under my earlier suggestion of making it so that if people want
> to use Complex on an unsupported type then they can explicitly suppress the type
> restriction, but should understand that it might not work properly.

People who want to use Complex on an unsupported type can quite readily 
copy-paste the code and remove the constraints, if that's what they want to do. 
  I think that's better than giving them an option which is essentially an 
invitation to shoot themselves in the foot, and which has very little chance of 
actually working.

It doesn't matter if you document it as "This might not work", by providing the 
option you are still essentially saying, "This is an OK way to use the type."

I think that's essentially an encouragement of bad code and a violation of the 
design principle that the easy thing to do should be the right thing to do.

> Really, I was just thinking that somebody who wants a quick-and-dirty
> hypercomplex number implementation for some app might try to do it that way.

I understand that, but quick-and-dirty solutions are often bad ones, and in this 
case, it just wouldn't work given the internals of Complex.

If you would like to revise std.complex to support this approach, I'm sure your 
pull request will be considered carefully, but personally I don't see it as an 
effective way to pursue hypercomplex number support when there are other options 
on the table.


More information about the Digitalmars-d mailing list