Jump to page: 1 2
Thread overview
[Issue 8755] Change the order of reduce arguments
Jan 25, 2014
Martin Nowak
Feb 19, 2014
Martin Nowak
Mar 21, 2014
wihkman
January 25, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=8755


Martin Nowak <code@dawg.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |code@dawg.eu


--- Comment #7 from Martin Nowak <code@dawg.eu> 2014-01-24 21:23:16 PST ---
Haskell has a function call flip for this. http://hackage.haskell.org/package/base-4.6.0.1/docs/Prelude.html#v:flip

It turns a function taking (a, b) into one taking (b, a) instead.

In phobos this is called binaryReverseArgs. http://dlang.org/phobos/std_functional.html#.binaryReverseArgs

So one can use
    rng.binaryReverseArgs!(reduce!fun)(seed);

Maybe we could rename it to flipArgs to make it useable?

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 25, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=8755



--- Comment #8 from bearophile_hugs@eml.cc 2014-01-25 02:20:53 PST ---
(In reply to comment #7)

> Maybe we could rename it to flipArgs to make it useable?

Beside changing the order of reduce arguments you can also shorten the name of that flipping function. But "flipArgs" seems a nice name for a function that works on 2, 3, ... arguments.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 19, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=8755



--- Comment #9 from monarchdodra@gmail.com 2014-02-19 14:00:05 PST ---
(In reply to comment #7)
> Haskell has a function call flip for this. http://hackage.haskell.org/package/base-4.6.0.1/docs/Prelude.html#v:flip
> 
> It turns a function taking (a, b) into one taking (b, a) instead.
> 
> In phobos this is called binaryReverseArgs. http://dlang.org/phobos/std_functional.html#.binaryReverseArgs
> 
> So one can use
>     rng.binaryReverseArgs!(reduce!fun)(seed);
> 
> Maybe we could rename it to flipArgs to make it useable?

Yeah... but who would actually use that in our code? I don't think it's an acceptable solution.

After having thought and worked on this for about a year, I *think* the only solution that wouldn't silently break code, is a rename. That or drop the issue as "won't fix".

I suggest we use "accumulate". It's the perfect synonym.

Can we agree to go with this solution?

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 19, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=8755



--- Comment #10 from Martin Nowak <code@dawg.eu> 2014-02-19 14:05:12 PST ---
How about "fold" instead, that's the classical functional programming name for that. Also there is foldl and foldr in Haskell.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 19, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=8755



--- Comment #11 from monarchdodra@gmail.com 2014-02-19 14:53:47 PST ---
(In reply to comment #10)
> How about "fold" instead, that's the classical functional programming name for that. Also there is foldl and foldr in Haskell.

Took a quick look at the doc, and I like what I see. I'm convinced with fold. It also has documented variants, which we could also implement.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 21, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=8755



--- Comment #12 from monarchdodra@gmail.com 2014-02-21 13:56:43 PST ---
(In reply to comment #10)
> How about "fold" instead, that's the classical functional programming name for that. Also there is foldl and foldr in Haskell.

"Introduce fold to algorithm": https://github.com/D-Programming-Language/phobos/pull/1955

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 20, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=8755



--- Comment #13 from monarchdodra@gmail.com 2014-03-20 12:32:49 PDT ---
(In reply to comment #12)
> (In reply to comment #10)
> > How about "fold" instead, that's the classical functional programming name for that. Also there is foldl and foldr in Haskell.
> 
> "Introduce fold to algorithm": https://github.com/D-Programming-Language/phobos/pull/1955

Attempt 2: https://github.com/D-Programming-Language/phobos/pull/2033

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 21, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=8755



--- Comment #14 from bearophile_hugs@eml.cc 2014-03-20 18:28:41 PDT ---
>Furthermore, it also improves usability by making the seeds passed by parameter pack, instead of forcing the use of a tuple.<

OK. (Despite in a modern language tuples should be built-in, so using them should be natural, common, and syntactically very cheap. In Python/Haskell/Scala code you don't see functions that refrain from accepting a tuple).


>Finally, it allows using only 1 seed, in which case, the same seed is replicated and is used for all the functions.<

This is from the unittests:

    // Compute sum and sum of squares in one pass.
    // This can be used to compute get the average and standard deviation.
    // A single seed (0.0) is passed, but it is optional
    // if the range is not empty.
    r = a.fold!("a + b", "a + b * b")(0.0);
    assert(approxEqual(r[0], 35));  // sum
    assert(approxEqual(r[1], 233)); // sum of squares

This is ambiguous, it seems that "a + b" has a seed while "a + b * b" doesn't have a seed. So in my opinion if you give N function then you need to give 0 seeds, or one N-tuple, or N seeds. So I don't like this.


>Oh yeah, also, I made it so that when no seed is given, it is an Error to use an empty range. This is the only case of deviation, but I think having nothrow justifies it.<

I am not sure this is a good idea. Throwing when you give no seed is probably acceptable. But I am not sure.


> "iterables" are not supported anymore.

I don't understand what this means.

The ddocs of fold say:

>Note: $(D fold) replaces $(D reduce): It retains the same functionality and
behavior, but uses an updated and more convenient interface.<

So you retain the same functionality or you don't.

If by "iterables" you mean that fold doesn't accept opApply-based iterables then I am against this change, I have plenty of code that opApply-based and I sometimes use reduce on them.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 21, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=8755



--- Comment #15 from wihkman <daniel350@bigpond.com> 2014-03-20 20:02:07 PDT ---
Why is reduce (sorry, fold) allowing multiple function arguments in the first
place?

If you want to compose functions to avoid another O(n) iteration, then you should compose the reduce function to return a tuple yourself.

That way it is clear what the code is doing, instead of this magic N-tuple special case return type.

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 21, 2014
https://d.puremagic.com/issues/show_bug.cgi?id=8755



--- Comment #16 from monarchdodra@gmail.com 2014-03-21 01:44:56 PDT ---
(In reply to comment #15)
> Why is reduce (sorry, fold) allowing multiple function arguments in the first
> place?
> 
> If you want to compose functions to avoid another O(n) iteration, then you should compose the reduce function to return a tuple yourself.
> 
> That way it is clear what the code is doing, instead of this magic N-tuple special case return type.

You shouldn't have to need to look at what the code is doing. It's a library.

We accept multiple function arguments because:
auto minmax = myRange.reduce!(min, max)();

Is incredibly straight forward and convenient.

That said, the design doesn't actually prevent you from doing it as you are
asking for:
//-----
auto first = tuple(myRange.front, myRange.front);
myRange.popFront();
auto minmax = reduce!((a, b) => tuple(min(a[0], b), max(a[1], b)))(first,
myRange);
writeln(minmax);
//----

It works, but you'll have a tough time selling it to me.

The only argument in favor of this approach, is if you need the return type to be different from the tuple type. But as I said, both approaches can co-exist, so why hold out?

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2