std.array suggestion

Kevin Bealer Kevin_member at pathlink.com
Thu Mar 9 13:24:35 PST 2006


In article <dup8rj$68s$1 at digitaldaemon.com>, Don Clugston says...
>
>Oskar Linde wrote:
>> Hello,
>> 
>> With the new IFTI support I have been looking at ways of upgrading the 
>> standard library with new and more generic functions. 
>
>[snip]
> > Is there in general even any interest in adding generic functions to the
> > standard library?
>
>Some of these functions are the last thing remaining in std.math2 (but 
>they definitely don't below there, none of them are truly mathematical). 
>We definitely want to remove std.math2 prior to 1.0, std.array sounds 
>good to me.
>
>I'll just comment on one function:
>
> > T sum(T[] arr)
> >
> > Returns the sum of the element in arr as defined by the + operator.
>
>This one has an interesting twist. I'm not sure that the sum should 
>necessarily be of type T. I've been playing around with the concept of 
>what I've called the Archetype of a type, which is the largest type with 
>the same semantics as T (possibly with the same calculation speed). (ie,
>Archetype!(byte)= Archetype!(short)
>Archetype!(int) = long
>Archetype!(float) = Archetype!(double) = real,
>Archetype!(cfloat)= creal, etc). Obviously it's a trivial template.
>
>I think that at least,  sum(double[] ) should internally use a real 
>while accumulating the sum, so that it can satisfy this test (at least 
>on x86 platforms):
>
>unittest {
>    const double a = [ double.max, double.max, -double.max];
>    assert(sum(a) == double.max);
>}
>
>After all, this is one of the reasons why reals exist. I'm still not 
>sure if sum(double []) should return a double or a real, although I'm 
>inclined to think that *any* function that returns a single floating 
>point value should return a real (on x87, the 80-bit result is just left 
>on the FPU stack anyway). But, I'm less confident about how a sum of 
>ints should behave.
>
>However, all the other functions seem to be free of mathematical 
>subtleties. sum() is the only one which involves arithmetic operators, 
>and therefore it might not belong with the rest.

I would prefer a syntax like this, instead of (or in addition to) the
archetype version:

void sum(in T1 a, out T2 b)

This way, I can sum ints into a double or doubles into a float if that's what I
really want to do.  A user who is worried about overflow of int, can sum into a
long.

Otherwise, most users will do a cast of the return value back to T, which means
there is cast proliferation.

One can imagine a "product" version:

void product(int T1 a, out T2 b);

In this case, "long" won't cut it for many cases - but a user can supply a
variable length integer type of their own design, so long as it provides a
method like "opAddAssign(int foo)".

Also note:  I deliberately use T1 instead of T1[] here.  I think the container
should not be restrained to a regular array.  This code (template syntax
omitted):

: void sum(T1 inp, T2 outp)
: {
:     foreach(auto sub; inp) {
:         outp += sub;
:     }
: }

. is more flexible than:

: void sum(T1[] inp, T2 outp)
: {
:     foreach(T1 sub; inp) {
:         outp += sub;
:     }
: }

Because it works with any class that can do opApply(), not just a vanilla array.

Kevin





More information about the Digitalmars-d mailing list