Transient ranges

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Tue May 31 11:31:05 PDT 2016


On 5/31/16 11:45 AM, Jonathan M Davis via Digitalmars-d wrote:
> On Monday, May 30, 2016 09:57:29 H. S. Teoh via Digitalmars-d wrote:
>> I'd argue that range-based generic code that assumes non-transience is
>> inherently buggy, because generic code ought not to make any
>> assumptions beyond what the range API guarantees. Currently, the range
>> API does not guarantee non-transience, therefore code that assumes so is
>> broken by definition.  Just because they happen to work most of the time
>> does not change the fact that they're written wrongly.
>
> Technically, the range API doesn't even require that front return the same
> value every time that it's called, because isInputRange can't possibly test
> for it.

The API doesn't require it mechanically, but the API does require it 
semantically (what does popFront mean if front changes automatically?). 
If front returns different things, I'd say that's a bug in your range 
construction.

> That doesn't mean that we don't expect that ranges behave that way.
> It's never been the case that we agreed that transient ranges were
> acceptable.

I want to note here that transient ranges are different from what you 
identified above (front returning different values each time). I know 
that you know that, but the way you said this implies that's what 
transient ranges are.

> In fact, it's pretty much the opposite. There was some
> discussion that maybe we'd consider it legitimate for basic input ranges
> given that we already had byLine doing it, and we didn't want to require
> that it copy its buffer, but previous discussions on it made it quite clear
> that most of us (Andrei included) thought that it should not be allowed for
> forward ranges.

I can see why forward ranges make it easier to avoid transience, since 
by definition the data should be available even if another range has 
already popFront'd by. But I don't think this needs to be a requirement. 
What I'd say is that as long as you haven't called popFront on the 
range, front should be stable. What happens elsewhere is implementation 
defined.

> It's been the case for ages now that ranges with a transient front are not
> explicitly supported. They happen to work with some algorithms (and you made
> changes to Phobos to make them work with more algorithms there), but they're
> not checked for, and there are algorithms that they don't and can't work
> with. The simple fact that std.array.array doesn't work with them is pretty
> damning IMHO.

array can work with them, you just have to copy each element as you 
iterate it (or otherwise transform the data into something that's 
persistent when copied).

But there is no requirement I know of that says a range has to always 
provide the expected outcome with std.array.array.

> We already have too many problems with unspecified behavior in ranges
> without adding transient front into the mix. It should be killed with fire
> IMHO.

It can't be killed, because it's ALREADY supported. Way too much code 
would break, and I think you would piss off a lot of D developers 
(myself included).

But I don't think transient ranges are that horrific. For instance, 
stdin.byLine.array probably doesn't do what you want. But it does 
actually work and do something that's defined and reproducible and will 
not corrupt memory. It's a bug needing to be fixed because you didn't 
understand what it was doing.

-Steve


More information about the Digitalmars-d mailing list