April 22, 2015
On Wed, 22 Apr 2015 03:00:18 +0000, Jesse Phillips wrote:

> On Tuesday, 21 April 2015 at 19:53:47 UTC, ketmar wrote:
>> here's the interesting oversight for isInputRange: https://issues.dlang.org/show_bug.cgi?id=14478
>>
>> so be careful: ranges with non-copyable elements aren't input ranges for now. ;-)
> 
> 
> The problem with allowing the inability to copy elements to be an input range is that you must then preven an algorithm from copying the range elements, how do you do that without preventing input ranges from having copyable elements?

many algorithms in std.algo doesn't copy if you'll use `(ref a)` labmdas.

April 22, 2015
<snip>
> from the very beginning. This isn't new. And given that the C++ STL gets
> away with its containers not working with non-copyable elements, I think
> that that proves that you can have a major component in the standard library
> - containers no less - not support copyable elements and have it work and be
> acceptable.

Semi-acceptable, and even then, no longer the case in C++. Before move semantics, yes, C++ containers were limited to copyable elements, which meant using raw pointers since auto_ptr couldn't be copied. It was a royal pain.

But for 4 years now I've been able to do this:

    std::vector<std::unique_ptr<MyClass>> stuff;
    stuff.emplace_back(new MyClass);
    auto ptr = std::unique_ptr<MyClass>(new MyClass);
    stuff.push_back(std::move(ptr));

Which won't compile with the `std::move` because unique_ptr isn't copyable. D has move semantics. C++98/03 did not. The comparison with C++ is no longer justified.

Ketmar has a point though. So do you. The worst part of D move semantics is not being able to copy a const variable, since copying is move + postblit and you can't move from a const object.

Atila

April 22, 2015
On Tuesday, 21 April 2015 at 23:33:38 UTC, ketmar wrote:
> On Tue, 21 Apr 2015 15:48:25 -0700, Jonathan M Davis via Digitalmars-d wrote:
>> auto h = r.front;
>
> the thing is that chain, or filter, or other algorithms are perfectly
> able to work with such ranges, yet it is forbidden now. it looks like
> arbitrary limitation to me.

why not introducing a new trait "isNonCopyingInputRange" with the old definition and define "isInputRange = isNonCopyingInputRange and compiles( auto h = r.front)" and then make filters and chain and all algorithms that don't need copying requiring only the new trait?
April 22, 2015
On Wed, 22 Apr 2015 08:41:38 +0000, Dominikus Dittes Scherkl wrote:

> On Tuesday, 21 April 2015 at 23:33:38 UTC, ketmar wrote:
>> On Tue, 21 Apr 2015 15:48:25 -0700, Jonathan M Davis via Digitalmars-d wrote:
>>> auto h = r.front;
>>
>> the thing is that chain, or filter, or other algorithms are perfectly able to work with such ranges, yet it is forbidden now. it looks like arbitrary limitation to me.
> 
> why not introducing a new trait "isNonCopyingInputRange" with the old definition and define "isInputRange = isNonCopyingInputRange and compiles( auto h = r.front)" and then make filters and chain and all algorithms that don't need copying requiring only the new trait?

i already suggested that. but the thing is that:
1. someone has to code that.
2. it has to convince at least W&A to accept the code.

that won't be me, especially considering "2".

April 22, 2015
On 4/21/15 7:31 PM, ketmar wrote:
> On Tue, 21 Apr 2015 18:57:50 -0400, Steven Schveighoffer wrote:
>
>> On 4/21/15 3:53 PM, ketmar wrote:
>>> here's the interesting oversight for isInputRange:
>>> https://issues.dlang.org/show_bug.cgi?id=14478
>>>
>>> so be careful: ranges with non-copyable elements aren't input ranges
>>> for now. ;-)
>>
>> This does seem like an incorrect limitation, and I'm not sure if it was
>> intentional. However, there is a lot of code out there that expects this
>> to work when isInputRange is true. I don't know if we should change it,
>> as the range definition is pretty clear in the documentation that auto h
>> = r.front is a required feature for ranges. What is the use case for
>> this?
>
> one possible use case was shown in bugreport. array of non-copyable
> struct, yet i still want chain 'em, for example. or filter. or...
>
> struct S {
>    int n;
>    @disable this (this);
> }
>
> void main () {
>    S[2] arr;
>    arr[0].n = 1;
>    arr[1].n = 2;
>    foreach (ref el; arr[].filter!((ref a) => a.n > 1)) {
>      writeln(el.n);
>    }
> }
>
>
> this code is perfectly valid, it doesn't require copying at all, yet it
> is invalid now.
>

Yes, I agree this is a valid use case. I don't think we can change isInputRange, because other code may depend on that requirement of copyability, but it is probably possible to alter algorithms so they can accept these "not-quite" input ranges. Definitely proxy or decorator type adapters that provide a proxy for front shouldn't be restricted to using only copyable range elements.

1st step is we need a trait to define what we are looking for, then the next step is to simply alter all the appropriate algorithms to use it. It shouldn't hinder any code that exists if we do that.

So what should be the name of this beast?

-Steve
April 22, 2015
On Wednesday, 22 April 2015 at 16:02:51 UTC, Steven Schveighoffer wrote:
> On 4/21/15 7:31 PM, ketmar wrote:
>> On Tue, 21 Apr 2015 18:57:50 -0400, Steven Schveighoffer wrote:
>>
>>> On 4/21/15 3:53 PM, ketmar wrote:
>>>> here's the interesting oversight for isInputRange:
>>>> https://issues.dlang.org/show_bug.cgi?id=14478
>>>>
>>>> so be careful: ranges with non-copyable elements aren't input ranges
>>>> for now. ;-)
>>>
>>> This does seem like an incorrect limitation, and I'm not sure if it was
>>> intentional. However, there is a lot of code out there that expects this
>>> to work when isInputRange is true. I don't know if we should change it,
>>> as the range definition is pretty clear in the documentation that auto h
>>> = r.front is a required feature for ranges. What is the use case for
>>> this?
>>
>> one possible use case was shown in bugreport. array of non-copyable
>> struct, yet i still want chain 'em, for example. or filter. or...
>>
>> struct S {
>>   int n;
>>   @disable this (this);
>> }
>>
>> void main () {
>>   S[2] arr;
>>   arr[0].n = 1;
>>   arr[1].n = 2;
>>   foreach (ref el; arr[].filter!((ref a) => a.n > 1)) {
>>     writeln(el.n);
>>   }
>> }
>>
>>
>> this code is perfectly valid, it doesn't require copying at all, yet it
>> is invalid now.
>>
>
> Yes, I agree this is a valid use case. I don't think we can change isInputRange, because other code may depend on that requirement of copyability, but it is probably possible to alter algorithms so they can accept these "not-quite" input ranges. Definitely proxy or decorator type adapters that provide a proxy for front shouldn't be restricted to using only copyable range elements.
>
> 1st step is we need a trait to define what we are looking for, then the next step is to simply alter all the appropriate algorithms to use it. It shouldn't hinder any code that exists if we do that.
>
> So what should be the name of this beast?
>
> -Steve

We could just add a flag as a second argument to isInputRange.
April 22, 2015
On Wed, 22 Apr 2015 12:02:51 -0400, Steven Schveighoffer wrote:

> So what should be the name of this beast?

isRestrictedInputRange? ;-)

no, really, it's not a fully valid input range, so let's name the trait with a long word to indicate that something is very unusual with it.

April 22, 2015
On Wednesday, 22 April 2015 at 05:31:03 UTC, ketmar wrote:
> many algorithms in std.algo doesn't copy if you'll use `(ref a)` labmdas.

I understand that, but the compiler won't complain "hey that isn't valid for all input ranges!" when it sees that someone copied front.
April 22, 2015
On Wed, 22 Apr 2015 18:32:55 +0000, Jesse Phillips wrote:

> On Wednesday, 22 April 2015 at 05:31:03 UTC, ketmar wrote:
>> many algorithms in std.algo doesn't copy if you'll use `(ref a)`
>> labmdas.
> 
> I understand that, but the compiler won't complain "hey that isn't valid for all input ranges!" when it sees that someone copied front.

yes, that's why introducing new trait is better. i was trying to minify support burden with changes to `isInputRange`, yet it seems to bring more problems that it is intended to solve, and i was wrong.

but i still believe that allowing "proxying algos" work on such "restriced" ranges is a viable addition. think about `Unique`, for example, as Peter noted in bugzilla.

April 22, 2015
On 4/22/15 12:10 PM, John Colvin wrote:
> On Wednesday, 22 April 2015 at 16:02:51 UTC, Steven Schveighoffer wrote:
>> Yes, I agree this is a valid use case. I don't think we can change
>> isInputRange, because other code may depend on that requirement of
>> copyability, but it is probably possible to alter algorithms so they
>> can accept these "not-quite" input ranges. Definitely proxy or
>> decorator type adapters that provide a proxy for front shouldn't be
>> restricted to using only copyable range elements.
>>
>> 1st step is we need a trait to define what we are looking for, then
>> the next step is to simply alter all the appropriate algorithms to use
>> it. It shouldn't hinder any code that exists if we do that.
>>
>> So what should be the name of this beast?
>>
> We could just add a flag as a second argument to isInputRange.

Yeah, I like this. But now we have to name the flag :)

I don't think it should be a bool, because:

isInputRange!(R, true)

Is pretty obtuse. I'd rather see something like:

isInputRange!(R, RangeOption.NonCopyable)

Or whatever name we come up with.

The nice thing about this solution is that the range options could be passed down the trait chain, so isForwardRange easily gets this ability as well.

-Steve