On Thursday, August 31, 2017 14:09:55 H. S. Teoh via Digitalmars-d-learn wrote: > On Thu, Aug 31, 2017 at 01:34:39PM -0600, Jonathan M Davis via > Digitalmars-d-learn wrote: [...] > > > In general, byLine does not work with other range-based algorithms > > precisely because it reuses the buffer. I think that it does manage to > > work for some, but IMHO, it should have just supported foreach via > > opApply and not been a range at all. It's great for efficiency in a > > loop but horrible for range chaining. > > [...] > > Transient ranges are tricky to work with, I agree, but I don't agree > that they're "horrible for range chaining". I argue that many range > algorithms that assume the persistence of .front are inherently wrong, > and ought to be implemented in a way that does *not* make this > assumption. Many std.algorithm algorithms *can* in fact be written in > this way, and those that aren't, are arguably buggy. > > For example, some std.algorithm functions take a forward range but then > tries to save .front to a local variable. Rather, they should use .save > to save the previous position of the range so that they can call .front > on that to access the previous element, instead of making the unfounded > assumption that whatever the local variable refers to will still remain > valid after calling .popFront. It's just sloppy coding IMNSHO.
I know. We've had this argument before. Personally, I think that the range spec should require that front _not_ be transient and that any ranges that are be considered non-conformant. Yes, under some set of circumstances, they can be made to work, but IMHO, it's simply not worth it. As it is, simply calling save when it's supposed to be called gets totally botched all the time even if ranges with transient front aren't involved. And adding such ranges just makes it too complicated. What we have currently with the range API allows for a lot of stuff to work correctly as long as certain assumptions are bet, but as soon as folks start doing stuff that doesn't behave the same way that a dynamic array does, things start falling apart. Even copying ranges in generic code does not have defined behavior, because different types have different semantics even if they follow the range API and pass isInputRange, isForwardRange, etc. The status quo works well enough that we get by, but it's a mess when you get into the details - especially if you want code that's actually generic. And IMHO, trying to add ranges with a transient front into the mix is taking it way to far. It's simply not worth it. But I know that you don't agree with that. - Jonathan M Davis