Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 30, 2015 std.algorithm sort() and reverse() confusion | ||||
---|---|---|---|---|
| ||||
Given that myVals is a dynamic array of ints... writeln("Array contents: ", myVals); writeln("Sorted: ", sort(myVals)); writeln("Sorted, reversed: ", reverse(myVals)); Gives me... Error: template std.stdio.writeln cannot deduce function from argument types !()(string, void) But, if I bring the reverse out of the call to writeln() it works as expected: writeln("Array contents: ", myVals); writeln("Sorted: ", sort(myVals)); reverse(myVals); writeln("Sorted, reversed: ", myVals); Can someone give me a simple explanation as to why this is so? I guess it might be because reverse is 'in place' and the target is undefined at compile time but surely that would still be the case in the second instance. Somehow it doesn't seem logical to a noob like me. |
January 30, 2015 Re: std.algorithm sort() and reverse() confusion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul | writeln("Sorted, reversed: ", retro(sort(myVals))); ? |
January 30, 2015 Re: std.algorithm sort() and reverse() confusion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Friday, 30 January 2015 at 16:21:24 UTC, Kagamin wrote:
> writeln("Sorted, reversed: ", retro(sort(myVals)));
> ?
Or...
writeln("Reverse sorted: ", sort!("a > b")(vals));
but I still don't understand the original 'error'.
|
January 30, 2015 Re: std.algorithm sort() and reverse() confusion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul | On Friday, 30 January 2015 at 17:07:17 UTC, Paul wrote:
> On Friday, 30 January 2015 at 16:21:24 UTC, Kagamin wrote:
>> writeln("Sorted, reversed: ", retro(sort(myVals)));
>> ?
>
> Or...
>
> writeln("Reverse sorted: ", sort!("a > b")(vals));
>
> but I still don't understand the original 'error'.
Take a look at the return type of reverse.
|
January 30, 2015 Re: std.algorithm sort() and reverse() confusion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul | On 2015-01-30 at 17:07, Paul wrote:
> writeln("Sorted, reversed: ", reverse(myVals));
>
> Gives me...
>
> Error: template std.stdio.writeln cannot deduce function from argument types !()(string, void)
As it should, because reverse returns nothing, void.
But you may wonder what the design choice behind that was that reverse doesn't return the range itself while sort does (a SortedRange, specifically).
|
January 30, 2015 Re: std.algorithm sort() and reverse() confusion | ||||
---|---|---|---|---|
| ||||
Posted in reply to FG | On 2015-01-30 at 18:42, FG wrote:
> But you may wonder what the design choice behind that was that reverse doesn't return the range itself while sort does (a SortedRange, specifically).
Although, after thinking about it, it makes sense. sort is used mostly to enforce that something is sorted in case it isn't already, so chaining it with other functions is reasonable, while in case of reverse you don't normally call it very often, it's cheaper to wrap the range in a retro range and iterate backwards when required, without touching the original.
|
January 30, 2015 Re: std.algorithm sort() and reverse() confusion | ||||
---|---|---|---|---|
| ||||
Posted in reply to FG | On Friday, January 30, 2015 18:42:57 FG via Digitalmars-d-learn wrote:
> On 2015-01-30 at 17:07, Paul wrote:
> > writeln("Sorted, reversed: ", reverse(myVals));
> >
> > Gives me...
> >
> > Error: template std.stdio.writeln cannot deduce function from argument types !()(string, void)
>
> As it should, because reverse returns nothing, void.
> But you may wonder what the design choice behind that was that reverse doesn't return the range itself while sort does (a SortedRange, specifically).
sort returns a different type rather than the original type, and that type indicates that its sorted, and some algoritms are able to take advantage of that. No algorithm is going to care that the data was reversed at some point, so there's no benefit it returning a new range type from reverse. And it's arguably better that a function that mutates something in place does not return it - especially with ranges - because that very easily gives the impression that the original is not mutated (since most range-based functions don't alter their arguments - they just wrap them in a new range type or return a portion of the original range).
Regardless, I think that the difference between sort and reverse comes down to the fact that there's a definite benefit in returning a new type from sort, whereas there is no such benefit with reverse, so there's no need to return anything. So, whether it _should_ return anything is then a very different question than it is with sort.
- Jonathan M Davis
|
January 30, 2015 Re: std.algorithm sort() and reverse() confusion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 01/30/2015 09:55 AM, Jonathan M Davis via Digitalmars-d-learn wrote: > sort returns a different type rather than the original type, and that type > indicates that its sorted, and some algoritms are able to take advantage of > that. I covered that a little bit during DConf 2014, at around 4:30 minute mark here: http://www.youtube.com/watch?x-yt-cl=85114404&v=oF8K4-bieaw&feature=player_detailpage&x-yt-ts=1422579428#t=267 > there is no such benefit with reverse, so there's no need to > return anything. Still, returning the original range would help with chaining calls: arr.reverse.map!sqrt Side note: There is the confusion between the .reverse property of arrays and std.algorithm.reverse. :-/ Ali |
January 30, 2015 Re: std.algorithm sort() and reverse() confusion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Friday, 30 January 2015 at 18:46:55 UTC, Ali Çehreli wrote:
> > there is no such benefit with reverse, so there's no need to
> > return anything.
>
> Still, returning the original range would help with chaining calls:
>
> arr.reverse.map!sqrt
>
> Side note: There is the confusion between the .reverse property of arrays and std.algorithm.reverse. :-/
>
> Ali
Thanks all, I now understand why this happens, although as a newcomer, it seems a little odd that these 'utility functions' have to be handled differently.
Paul
|
January 30, 2015 Re: std.algorithm sort() and reverse() confusion | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Friday, January 30, 2015 10:46:54 Ali Çehreli via Digitalmars-d-learn wrote:
> On 01/30/2015 09:55 AM, Jonathan M Davis via Digitalmars-d-learn wrote:
> > there is no such benefit with reverse, so there's no need to
> > return anything.
>
> Still, returning the original range would help with chaining calls:
>
> arr.reverse.map!sqrt
Yes, but arguably, chaining calls in this case is bad, because normally when you're chaining calls with range-based functions, you're not mutating the original range, whereas with reverse, you are. So, it could easily give the impression that it's doing what retro does rather than reversing the elements in place.
- Jonathan M Davis
|
Copyright © 1999-2021 by the D Language Foundation