Transience of .front in input vs. forward ranges

Jonathan M Davis jmdavisProg at gmx.com
Mon Nov 12 14:34:23 PST 2012


On Monday, November 12, 2012 23:01:22 Tommi wrote:
> On Monday, 12 November 2012 at 20:52:07 UTC, Jonathan M Davis
> 
> wrote:
> > That wouldn't work. It's the complete opposite of what a
> > generative range would require if it generates the return value
> > in front. Narrow strings in particularly would be screwed by
> > it, because their front is calculated, and
> > since it's a free function, as is popFront, there's no way
> > to save the return value of front in popFront. It has to
> > be calculated in front, and it's not at all transient.
> > 
> > It also screws with the ability to have sealed containers,
> > since in that case, something like front would never
> > return by ref.
> > 
> > The refness of front's type really shouldn't have anything
> > to do with its transience. They're completely unrelated.
> 
> I didn't understand any of those arguments, so perhaps I still
> don't fully comprehend this issue.
> 
> Persistence
> -----------
> I thought persistent X means that there's a dedicated storage
> space for X where it will exist after front returns and X's value
> will not be tampered with by calling popFront. That notion of
> persistence led to me into thinking that persistent front could
> (and really should) return either a reference to X or a const
> reference if the range doesn't want to allow mutation through
> front.
> 
> Transience
> ----------
> The other side of the coin in my thinking was that transient
> means that X doesn't have a dedicated storage space. So transient
> X could be a variable that's local to function front, or it could
> be that X is stored in a buffer and will exist there after front
> returns, but the buffer would be overwritten by a call to
> popFront. And that notion of transience led me into thinking that
> transient front could never return a reference.

With regards to this discussion, transience means that front is a reference 
type which gets overwritten when popFront is called. So, when popFront is 
called any references to the return value of front which the caller has kept 
will change rather than staying the same as they were before popFront. That 
has _nothing_ to do with returning by ref.

It's perfectly possible for a front which is non-transient to return by ref. 
front for arrays does that. On the other hand, front on narrow strings doesn't 
and _can't_ return by ref, because front is calculated on every call. There is 
no persistent storage for it. But it's _not_ transient like ByLine is. A range 
like ByLine _could_ return its front by ref. There's nothing stopping it, and 
it could work just fine. It's just that it doesn't benefit it any, and it would 
have to make sure that the retun value was still usable on each call to 
popFront (e.g. if ByLine returned by ref, it would have to worry about whether 
the buffer was then non-null or sufficiently large or whatever - but it could 
still work). So, it's unlikely that a range with a transient front would ever 
return by ref, but it can if it really wants to.

> NOTE: All of the above assumes that D were designed so that all
> types had value semantics.

Which will never happen. So, any discussion based on that premise is pretty 
pointless. And this discussion would never have happened in the first place if 
D had no reference types, because you'll never have a transient front with a 
value type.

- Jonathan M Davis


More information about the Digitalmars-d mailing list