www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - R.filter!(..).sort!(..)

reply Arjan <arjan ask.me.to> writes:
When applying a sort!() on a filtered range I get this compiler 
error:

Error: template std.algorithm.sorting.sort cannot deduce function 
from argument types !((a, b) => a.name < 
b.name)(FilterResult!(__lambda3, RangeT!(Array!(IssueType)))), 
candidates are:
C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\sorting.d(1851,1):       
std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss =
SwapStrategy.unstable, Range)(Range r) if ((ss == SwapStrategy.unstable &&
(hasSwappableElements!Range || hasAssignableElements!Range) || ss !=
SwapStrategy.unstable && hasAssignableElements!Range) &&
isRandomAccessRange!Range && hasSlicing!Range && hasLength!Range)

But it seems the problem is with the filter!() result not being a 
isRandomAccessRange!Range because:
R.filter!(..).array.sort!(..) just works (by copying the filter 
results in a array).

Iaw is the compiler error msg wrong? Or i'm I wrong?
Nov 28 2017
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Tuesday, 28 November 2017 at 13:10:15 UTC, Arjan wrote:
 Iaw is the compiler error msg wrong? Or i'm I wrong?
filter isn't random access because it doesn't even know how many elements are in there, much less where they are, until it loops through and does the comparisons to know which items pass the filter. The .array call will buffer it and also evaluate how many items are actually still there after the filter, and sort uses that buffer too.
Nov 28 2017
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/28/17 8:10 AM, Arjan wrote:
 When applying a sort!() on a filtered range I get this compiler error:
 
 Error: template std.algorithm.sorting.sort cannot deduce function from 
 argument types !((a, b) => a.name < b.name)(FilterResult!(__lambda3, 
 RangeT!(Array!(IssueType)))), candidates are:
 C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\sorting.d(1851,1):        
 std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss = 
 SwapStrategy.unstable, Range)(Range r) if ((ss == SwapStrategy.unstable 
 && (hasSwappableElements!Range || hasAssignableElements!Range) || ss != 
 SwapStrategy.unstable && hasAssignableElements!Range) && 
 isRandomAccessRange!Range && hasSlicing!Range && hasLength!Range)
 
 But it seems the problem is with the filter!() result not being a 
 isRandomAccessRange!Range because:
 R.filter!(..).array.sort!(..) just works (by copying the filter results 
 in a array).
 
 Iaw is the compiler error msg wrong? Or i'm I wrong?
The library is correctly telling you that your filtered range is not random access. It can't be, because it lazily applies the filter (that is, it filters on each element as you popFront them). So how can it know what the e.g. 3rd element is, if you haven't run any filters yet? The array version works because you are applying the filter completely and storing the results elsewhere in one step. -Steve
Nov 28 2017
parent reply Arjan <arjan ask.me.to> writes:
On Tuesday, 28 November 2017 at 13:24:09 UTC, Steven 
Schveighoffer wrote:
 On 11/28/17 8:10 AM, Arjan wrote:
 [...]
The library is correctly telling you that your filtered range is not random access. It can't be, because it lazily applies the filter (that is, it filters on each element as you popFront them). So how can it know what the e.g. 3rd element is, if you haven't run any filters yet? The array version works because you are applying the filter completely and storing the results elsewhere in one step. -Steve
Well I would have liked an error msg something like: isRandomAccessRange!Range for Range=.. failed! Or unable to sort!() a lazy Range.
Nov 28 2017
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/28/17 8:57 AM, Arjan wrote:
 On Tuesday, 28 November 2017 at 13:24:09 UTC, Steven Schveighoffer wrote:
 On 11/28/17 8:10 AM, Arjan wrote:
 [...]
The library is correctly telling you that your filtered range is not random access. It can't be, because it lazily applies the filter (that is, it filters on each element as you popFront them). So how can it know what the e.g. 3rd element is, if you haven't run any filters yet? The array version works because you are applying the filter completely and storing the results elsewhere in one step.
Well I would have liked an error msg something like: isRandomAccessRange!Range for Range=.. failed! Or unable to sort!() a lazy Range.
Sure, the error messages could be more specific about WHY it's failing. This has been discussed many times, but no action has been taken. Would be an awesome project to add to D. -Steve
Nov 28 2017
parent Timoses <timosesu gmail.com> writes:
On Tuesday, 28 November 2017 at 14:04:40 UTC, Steven 
Schveighoffer wrote:
 Would be an awesome project to add to D.
Oh yes, it sounds yummy..
Nov 28 2017