March 25, 2014
On Tuesday, 25 March 2014 at 21:16:22 UTC, Nordlöw wrote:
>> You have no guarantees that you'll have "stability" of the returned type.
>
> What do you mean with "stability" of the return type?
>
>> More often than not, it *is* stable, but there are cases where it is not.
>
> Could you gives examples of when it's stable and when it's not?

Actually, not with a trivial use case.

I think I'm over-engineering.
March 25, 2014
> Actually, not with a trivial use case.
>
> I think I'm over-engineering.

Do you have a sample implementation on Github I can test?

/Per
March 25, 2014
On Tuesday, 25 March 2014 at 21:27:45 UTC, Nordlöw wrote:
>> Actually, not with a trivial use case.
>>
>> I think I'm over-engineering.
>
> Do you have a sample implementation on Github I can test?
>
> /Per

You can test my re-implementation of fold/reduce here if you want:
https://github.com/D-Programming-Language/phobos/pull/2033

It contains code that tests the "stability" thing I was talking about, but I think I'm going to remove it.
https://github.com/D-Programming-Language/phobos/pull/2033/files#diff-ff74a46362b5953e8c88120e2490f839R992

I think it's better to simply require that:
give: alias S = typeof(r.front, r.front);
isAssignable!(S, typeof(fun(S.init, r.front))
March 25, 2014
> You can test my re-implementation of fold/reduce here if you want:
> https://github.com/D-Programming-Language/phobos/pull/2033

Thx!
March 26, 2014
On 2014-03-25 21:16, "Nordlöw" wrote:
>> You have no guarantees that you'll have "stability" of the returned type.
>
> What do you mean with "stability" of the return type?
>
>> More often than not, it *is* stable, but there are cases where it is not.
>
> Could you gives examples of when it's stable and when it's not?

I'm not entirely certain if this is what monarch_dodra meant, but it's my understanding of the terms:


Stable:

    double[] arr = [1, 2, 3, 4];
    auto a = arr[0] * arr[1];
    auto b = a * arr[2];

a is of type double, b is of type double.

Unstable:
Consider a range of imaginary numbers, reduced with *.

    idouble[] arr = [1i, 2i, 3i, 4i];
    auto a = arr[0] * arr[1];
    auto b = a * arr[2];

a is of type double, b is of type idouble. When you consume the next element, the result would be double again, and it oscillates like that.

--
  Simen
March 26, 2014
On Wednesday, 26 March 2014 at 15:18:36 UTC, Simen Kjærås wrote:
> On 2014-03-25 21:16, "Nordlöw" wrote:
>>> You have no guarantees that you'll have "stability" of the returned type.
>>
>> What do you mean with "stability" of the return type?
>>
>>> More often than not, it *is* stable, but there are cases where it is not.
>>
>> Could you gives examples of when it's stable and when it's not?
>
> I'm not entirely certain if this is what monarch_dodra meant, but it's my understanding of the terms:
> ---
>   Simen

That's what I meant. Good example!
March 26, 2014
> a is of type double, b is of type idouble. When you consume the next element, the result would be double again, and it oscillates like that.

I guess the return is CommonType!(double,idouble) in that case, right?

Is that so hard to figure out...Hmm, there seems to be a limitation in D's builtin handling of complex numbers.

import std.stdio, std.algorithm, std.traits;
void main(string args[])
{
    double re;
    idouble im;
    alias C = CommonType!(double, idouble);
    C c;
    writeln(typeof(re).stringof, ",", typeof(im).stringof, ",", C.stringof);
}

prints

double,idouble,double

This is *not* what we want.

We want to print something like

double,idouble,cdouble (or Complex!double!)

I guess that's why it's deprecated in favour of std.complex...
March 27, 2014
On Tuesday, 25 March 2014 at 17:22:45 UTC, monarch_dodra wrote:
> I think this is wrong. popping an empty range is an *Error*, and should be validated by the programmer. Because of this, it is currently not possible to use "reduce(range)" in nothrow context.

Popping an empty range is indeed an error, but that's not the issue here. The issue is whether or not it should check for empty, i.e. whether an empty input is valid. Other looping eager algorithms - like `sum` and indeed `copy` - do accept empty inputs.

I understand the issue of nothrow of course; I think it's likely that in most real-world use cases, reduce/fold will be used on guaranteed non-empty inputs, *but not always*, and I'd hate for release-build-only dangerous bugs to sneak into programs because of it.

Maybe we should have some kind of NonEmpty higher-order range type that algorithms can overload on, ala how std.container deals with Take? It could be initialized with `assumeNonEmpty(r)` and/or `checkNonEmpty(r)`.

March 27, 2014
On Thursday, 27 March 2014 at 02:08:04 UTC, Jakob Ovrum wrote:
> On Tuesday, 25 March 2014 at 17:22:45 UTC, monarch_dodra wrote:
>> I think this is wrong. popping an empty range is an *Error*, and should be validated by the programmer. Because of this, it is currently not possible to use "reduce(range)" in nothrow context.
>
> Popping an empty range is indeed an error, but that's not the issue here. The issue is whether or not it should check for empty, i.e. whether an empty input is valid. Other looping eager algorithms - like `sum` and indeed `copy` - do accept empty inputs.
>
> I understand the issue of nothrow of course; I think it's likely that in most real-world use cases, reduce/fold will be used on guaranteed non-empty inputs, *but not always*, and I'd hate for release-build-only dangerous bugs to sneak into programs because of it.
>
> Maybe we should have some kind of NonEmpty higher-order range type that algorithms can overload on, ala how std.container deals with Take? It could be initialized with `assumeNonEmpty(r)` and/or `checkNonEmpty(r)`.

I'm not sure I understand this right, but are you or Monarch
proposing to disallow calling it with an empty range? I believe
this would be really bad, especially for generic code.
Folding/reducing an empty range should just return the seed
value, not be an error.
March 27, 2014
On Thursday, 27 March 2014 at 10:42:56 UTC, Marc Schütz wrote:
> I'm not sure I understand this right, but are you or Monarch
> proposing to disallow calling it with an empty range? I believe
> this would be really bad, especially for generic code.
> Folding/reducing an empty range should just return the seed
> value, not be an error.

We are talking about the case when there *is* no seed. What should this do?

//----
int[] arr;
reduce!max(arr);
//----