Jump to page: 1 2 3
Thread overview
oversight with input ranges
Apr 21, 2015
ketmar
Apr 21, 2015
Jonathan M Davis
Apr 21, 2015
ketmar
Apr 22, 2015
Jonathan M Davis
Apr 22, 2015
ketmar
Apr 22, 2015
Jonathan M Davis
Apr 22, 2015
Atila Neves
Apr 22, 2015
Jonathan M Davis
Apr 22, 2015
ketmar
Apr 21, 2015
ketmar
Apr 22, 2015
John Colvin
Apr 22, 2015
ketmar
Apr 22, 2015
Jesse Phillips
Apr 22, 2015
ketmar
Apr 22, 2015
Jesse Phillips
Apr 22, 2015
ketmar
April 21, 2015
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. ;-)

April 21, 2015
On Tuesday, April 21, 2015 19:53:47 ketmar via Digitalmars-d 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. ;-)

If

auto h = r.front;

doesn't work, then I don't think that it can be a range. And if that means that elements have to be copyable to be in a range, then I think that they're going to have to be copyable. There is going to be _way_ too much code out there that does

auto h = r.front;

for it to work to try and claim that something is an input range when that line doesn't work. And IIRC, C++ STL containers require that their elements be copyable in order to work, so it's not like we'd be the first to require this sort of thing.

- Jonathan M Davis

April 21, 2015
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?

-Steve
April 21, 2015
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.

April 21, 2015
On Tue, 21 Apr 2015 15:48:25 -0700, Jonathan M Davis via Digitalmars-d wrote:

> On Tuesday, April 21, 2015 19:53:47 ketmar via Digitalmars-d 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. ;-)
> 
> If
> 
> auto h = r.front;
> 
> doesn't work, then I don't think that it can be a range. And if that means that elements have to be copyable to be in a range, then I think that they're going to have to be copyable. There is going to be _way_ too much code out there that does
> 
> auto h = r.front;
> 
> for it to work to try and claim that something is an input range when that line doesn't work. And IIRC, C++ STL containers require that their elements be copyable in order to work, so it's not like we'd be the first to require this sort of thing.

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.

April 22, 2015
On Tuesday, April 21, 2015 23:33:38 ketmar via Digitalmars-d wrote:
> On Tue, 21 Apr 2015 15:48:25 -0700, Jonathan M Davis via Digitalmars-d wrote:
>
> > On Tuesday, April 21, 2015 19:53:47 ketmar via Digitalmars-d 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. ;-)
> >
> > If
> >
> > auto h = r.front;
> >
> > doesn't work, then I don't think that it can be a range. And if that means that elements have to be copyable to be in a range, then I think that they're going to have to be copyable. There is going to be _way_ too much code out there that does
> >
> > auto h = r.front;
> >
> > for it to work to try and claim that something is an input range when that line doesn't work. And IIRC, C++ STL containers require that their elements be copyable in order to work, so it's not like we'd be the first to require this sort of thing.
>
> 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.

Just because a few algorithms happen to work with non-copyable elements doesn't meant that it works in general. I can understand why you'd want to be able to do it, but not being able to do

auto h = r.front;

is such a huge limitation that I don't think that it's even vaguely acceptable. I can guarantee that there is a lot of code out there that does it. Just grepping Phobos quickly finds a few cases, let alone digging into all of the code that exists in the wild. If anything, the problem that we've run into is folks who keep front around after popFront has been called (which doesn't always work with input ranges - e.g. byLine), and to do that, you have to be able to copy front, so clearly, folks have been doing that.

The definition of input ranges has quite clearly included

auto h = r.front;

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. Also, AFAIK, this is the first time anyone has ever brought up this complaint for D ranges. So, while I'm sure that it's a limitation that might be irritating in some cases, I also think that it's pretty clear that it affects a very small percentage of the users out there.

If we were starting over, then maybe we could have something like hasCopyableElements and indicate that range elements aren't guaranteed to be copyable without that, but that would break too much code at this point, and honestly, we have too many traits like that already. Writing fully correct range code that takes into all of the stray cases is ridiculously hard - especially if you try and wrap a range without losing any of its capabilities while wrapped. We really need the common case to be easy, and disallowing copying range elements without testing for that capability first is not user-friendly at all. Even if it were considered more correct from a technical standpoint, folks just wouldn't do it.

And since isInputRange has guaranteed that elements have been copyable, I think that it's perfectly reasonable that it's been assumed that they would be, and changing that at this point just isn't worth it.

- Jonathan M Davis

April 22, 2015
I should also point out that std.array.array can't work with non-copyable elements, and that's a pretty major function in Phobos. So, if we _were_ going to support non-copyable elements, we couldn't do it simply by making isInputRange accept them, but regardless, I don't think that it's worth the extra complication to support non-copyable elements.

- Jonathan M Davis

April 22, 2015
On Tue, 21 Apr 2015 18:30:44 -0700, Jonathan M Davis via Digitalmars-d wrote:

> And since isInputRange has guaranteed that elements have been copyable, I think that it's perfectly reasonable that it's been assumed that they would be, and changing that at this point just isn't worth it.

yet disallowing some algorithms on ranges that are (algos) working ok is limiting too. fixing `isInputRange` was the easiest way i found to allow usage of such algorithms.

another possibility is to check all algo implementations and see if they can be used with ranges that have non-copyable elements, and then mark them as such, replacing `isInputRange` to newly created trait. this can be automated, i believe -- at least checking.

i understand that this will add another trait to the pile, but i believe that this will make std.algorithm better, as it will accept more range types. from the user POV i don't care about "range definition purity", the only thing i see is that std.algorithm is rejecting a perfectly valid range, and i'm doing no copies at all -- so i must forget about all std.algo niceties and fall back to stupid loops.

i.e. allowing such ranges in std.algo (where appropriate) will be a win for end-user. i understand that it will add some support burden, though. but it shouldn't be that big, considering that implementations are more or less stable now.

April 22, 2015
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?
April 22, 2015
On Wednesday, April 22, 2015 02:05:38 ketmar via Digitalmars-d wrote:
> On Tue, 21 Apr 2015 18:30:44 -0700, Jonathan M Davis via Digitalmars-d wrote:
>
> > And since isInputRange has guaranteed that elements have been copyable, I think that it's perfectly reasonable that it's been assumed that they would be, and changing that at this point just isn't worth it.
>
> yet disallowing some algorithms on ranges that are (algos) working ok is limiting too. fixing `isInputRange` was the easiest way i found to allow usage of such algorithms.
>
> another possibility is to check all algo implementations and see if they can be used with ranges that have non-copyable elements, and then mark them as such, replacing `isInputRange` to newly created trait. this can be automated, i believe -- at least checking.
>
> i understand that this will add another trait to the pile, but i believe that this will make std.algorithm better, as it will accept more range types. from the user POV i don't care about "range definition purity", the only thing i see is that std.algorithm is rejecting a perfectly valid range, and i'm doing no copies at all -- so i must forget about all std.algo niceties and fall back to stupid loops.
>
> i.e. allowing such ranges in std.algo (where appropriate) will be a win for end-user. i understand that it will add some support burden, though. but it shouldn't be that big, considering that implementations are more or less stable now.

An alternative would be to create a range of pointers to the non-copyable objects and operate on those instead. That may not be quite what you want, but it should work, and it avoids having to complicate ranges any further for what amounts to a very uncommon use case.

- Jonathan M Davis

« First   ‹ Prev
1 2 3