Jump to page: 1 2
Thread overview
std.algorithm sort() and reverse() confusion
Jan 30, 2015
Paul
Jan 30, 2015
Kagamin
Jan 30, 2015
Paul
Jan 30, 2015
Tobias Pankrath
Jan 30, 2015
FG
Jan 30, 2015
FG
Jan 30, 2015
Jonathan M Davis
Jan 30, 2015
Ali Çehreli
Jan 30, 2015
Paul
Jan 30, 2015
Jonathan M Davis
Feb 02, 2015
bearophile
January 30, 2015
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
writeln("Sorted, reversed: ", retro(sort(myVals)));
?
January 30, 2015
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
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
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
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
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
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
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
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


« First   ‹ Prev
1 2