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