March 27, 2014 Re: "fold": a replacement for "reduce" | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 2014-03-25 17:22, monarch_dodra wrote:
> I'm taking this naming-changing event as an opportunity to "cleanup"
> reduce too. One thing that gets on my nerves is that "range.reduce()" is
> not nothrow, because it throws an exception if the range is empty.
>
> 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.
>
> This however, even with a name change, it *is* change of behavior. Do
> you feel this is acceptable? Do you want this change at all? Or do you
> think an Exception is fine?
Your new fold (foldl? Should we have foldr as well?) should be nothrow. As for updating reduce, I'm slightly in favor of making it nothrow as well, but is this really necessary? The cases where it's already used will gain nothing from it, and new code would use fold instead. Or do I misunderstand?
Even with that argument though, I'd say make it nothrow. Like Meta said, it's probably remnants from elder times.
--
Simen
|
March 27, 2014 Re: "fold": a replacement for "reduce" | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On Thursday, 27 March 2014 at 12:48:41 UTC, Simen Kjærås wrote: > Your new fold (foldl? Should we have foldr as well?) "fold" (from what I understood) is what you call "foldl". It was discussed to not introduce "foldr", as it's just "fold!(binaryReverseArgs!Fun)(range.retro);". I'm not sure I was able to understand what the difference between "fold" and "foldl" is... |
March 27, 2014 Re: "fold": a replacement for "reduce" | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Thursday, 27 March 2014 at 13:23:27 UTC, monarch_dodra wrote:
> On Thursday, 27 March 2014 at 12:48:41 UTC, Simen Kjærås wrote:
>> Your new fold (foldl? Should we have foldr as well?)
>
> "fold" (from what I understood) is what you call "foldl". It was discussed to not introduce "foldr", as it's just "fold!(binaryReverseArgs!Fun)(range.retro);".
>
> I'm not sure I was able to understand what the difference between "fold" and "foldl" is...
In functional languages,
fold_left(f, a, [b1, ..., bn]) is
f((... (f, (f, a, b1), b2) ...), bn)
as you can see, the innermost f call is on the leftmost sequence element, and
fold_right(f, [a1, ..., an], b) is
f(a1, (f a2 (... f(an, b) ...)))
That's how I think of them.
|
March 27, 2014 Re: "fold": a replacement for "reduce" | ||||
---|---|---|---|---|
| ||||
Posted in reply to Brian Rogoff | On Thursday, 27 March 2014 at 14:41:19 UTC, Brian Rogoff wrote:
> On Thursday, 27 March 2014 at 13:23:27 UTC, monarch_dodra wrote:
>> On Thursday, 27 March 2014 at 12:48:41 UTC, Simen Kjærås wrote:
>>> Your new fold (foldl? Should we have foldr as well?)
>>
>> "fold" (from what I understood) is what you call "foldl". It was discussed to not introduce "foldr", as it's just "fold!(binaryReverseArgs!Fun)(range.retro);".
>>
>> I'm not sure I was able to understand what the difference between "fold" and "foldl" is...
>
> In functional languages,
>
> fold_left(f, a, [b1, ..., bn]) is
> f((... (f, (f, a, b1), b2) ...), bn)
>
> as you can see, the innermost f call is on the leftmost sequence element, and
>
> fold_right(f, [a1, ..., an], b) is
> f(a1, (f a2 (... f(an, b) ...)))
>
> That's how I think of them.
Right, but what about "fold" vs "fold_left"? Is there a difference?
|
March 27, 2014 Re: "fold": a replacement for "reduce" | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Thursday, 27 March 2014 at 13:23:27 UTC, monarch_dodra wrote:
> "fold" (from what I understood) is what you call "foldl". It was discussed to not introduce "foldr", as it's just "fold!(binaryReverseArgs!Fun)(range.retro);".
Rolls right off the tongue. We seriously need a better alias for binaryReverseArgs.
|
March 27, 2014 Re: "fold": a replacement for "reduce" | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Thursday, 27 March 2014 at 15:33:39 UTC, Meta wrote:
> On Thursday, 27 March 2014 at 13:23:27 UTC, monarch_dodra wrote:
>> "fold" (from what I understood) is what you call "foldl". It was discussed to not introduce "foldr", as it's just "fold!(binaryReverseArgs!Fun)(range.retro);".
>
> Rolls right off the tongue. We seriously need a better alias for binaryReverseArgs.
Arguably, we could just have a generic "reverseArgs". Not sure why it's restrained to "binary" to begin with.
In any case, I don't disagree, but the point is that "fold" is not special in that regard. If "foldr" was justified, then so would "filterr", "joinerr", "mapr" etc...
|
March 27, 2014 Re: "fold": a replacement for "reduce" | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On 2014-03-27 15:33, Meta wrote: > On Thursday, 27 March 2014 at 13:23:27 UTC, monarch_dodra wrote: >> "fold" (from what I understood) is what you call "foldl". It was >> discussed to not introduce "foldr", as it's just >> "fold!(binaryReverseArgs!Fun)(range.retro);". > > Rolls right off the tongue. We seriously need a better alias for > binaryReverseArgs. Is it even necessary to specifically have a binary version of that? This seems to be a working generalization of binaryReverseArgs: template reverseArgs(alias pred) { import std.typetuple : Reverse; auto reverseArgs(Args...)(Args args) if (is(typeof(pred(Reverse!args)))) { return pred(Reverse!args); } } unittest { import std.functional; alias gt = reverseArgs!(binaryFun!("a < b")); assert(gt(2, 1) && !gt(1, 1)); int x = 42; bool xyz(int a, int b) { return a * x < b / x; } auto foo = &xyz; foo(4, 5); alias zyx = reverseArgs!(foo); assert(zyx(5, 4) == foo(4, 5)); int abc(int a, int b, int c) { return a * b + c; } alias cba = reverseArgs!abc; assert(abc(91, 17, 32) == cba(32, 17, 91)); } On the same note, binaryFun and unaryFun seem to me unnecessary specializations of a more general 'fun' template. Philippe Sigaud has an implementation in his dranges called naryFun (https://github.com/PhilippeSigaud/dranges). That code has apparently not been touched for at least two years, so YMMV. -- Simen |
March 27, 2014 Re: "fold": a replacement for "reduce" | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Thursday, 27 March 2014 at 14:45:05 UTC, monarch_dodra wrote:
> On Thursday, 27 March 2014 at 14:41:19 UTC, Brian Rogoff wrote:
>> On Thursday, 27 March 2014 at 13:23:27 UTC, monarch_dodra wrote:
>>> On Thursday, 27 March 2014 at 12:48:41 UTC, Simen Kjærås wrote:
>>>> Your new fold (foldl? Should we have foldr as well?)
>>>
>>> "fold" (from what I understood) is what you call "foldl". It was discussed to not introduce "foldr", as it's just "fold!(binaryReverseArgs!Fun)(range.retro);".
>>>
>>> I'm not sure I was able to understand what the difference between "fold" and "foldl" is...
>>
>> In functional languages,
>>
>> fold_left(f, a, [b1, ..., bn]) is
>> f((... (f, (f, a, b1), b2) ...), bn)
>>
>> as you can see, the innermost f call is on the leftmost sequence element, and
>>
>> fold_right(f, [a1, ..., an], b) is
>> f(a1, (f a2 (... f(an, b) ...)))
>>
>> That's how I think of them.
>
> Right, but what about "fold" vs "fold_left"? Is there a difference?
There's just fold_left and fold_right, or foldl and foldr if you prefer, though if f is associative they're both the same.
|
March 27, 2014 Re: "fold": a replacement for "reduce" | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On Thursday, 27 March 2014 at 15:54:46 UTC, Simen Kjærås wrote: > On 2014-03-27 15:33, Meta wrote: > Is it even necessary to specifically have a binary version of that? > This seems to be a working generalization of binaryReverseArgs: In binaryReverseArgs's defense, it was written before "Reverse!". But yes, it's just a question of time before binaryReverseArgs is replaced. It's just a matter of having someone tackle the issue and submit a proposal *hint* ;) > On the same note, binaryFun and unaryFun seem to me unnecessary specializations of a more general 'fun' template. Philippe Sigaud has an implementation in his dranges called naryFun (https://github.com/PhilippeSigaud/dranges). That code has apparently not been touched for at least two years, so YMMV. Also yes, but the general feeling around here, is that "string functions" are a thing of the past, and should be replaced by "real" lambda functions. As such, even if "naryFun" works, it promotes the use of something that is unpopular, and that some would like to see disappear. |
March 27, 2014 Re: "fold": a replacement for "reduce" | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Thursday, 27 March 2014 at 16:33:53 UTC, monarch_dodra wrote:
> Also yes, but the general feeling around here, is that "string functions" are a thing of the past, and should be replaced by "real" lambda functions.
>
> As such, even if "naryFun" works, it promotes the use of something that is unpopular, and that some would like to see disappear.
Don't forget this use case:
//Error
alias fun = (a) => a + 1;
//Ok
alias fun = unaryFun!(a => a + 1);
This is the main reason I think naryFun is a good idea.
|
Copyright © 1999-2021 by the D Language Foundation