Issue with forward ranges which are reference types

Lars T. Kyllingstad public at kyllingen.NOSPAMnet
Wed Aug 17 11:53:53 PDT 2011


On Wed, 17 Aug 2011 14:15:52 -0400, Steven Schveighoffer wrote:

> On Wed, 17 Aug 2011 13:15:27 -0400, Lars T. Kyllingstad
> <public at kyllingen.nospamnet> wrote:
> 
>> On Wed, 17 Aug 2011 10:19:31 -0400, Steven Schveighoffer wrote:
>>
>>> On Wed, 17 Aug 2011 00:05:54 -0400, Jonathan M Davis
>>> <jmdavisProg at gmx.com> wrote:
>>>
>>>> So, the question is, should a range-based function have the same
>>>> behavior for
>>>> all forward ranges regardless of whether they're value types or
>>>> reference types? Or should the caller be aware of whether a range is
>>>> a value type or a
>>>> reference type and call save if necessary? Or should the caller just
>>>> always
>>>> call save when passing a forward range to a function?
>>>>
>>>>
>>> Probably not helpful, since the establishment seems to be set in their
>>> opinions, but I'd recommend saying ranges are always structs, and get
>>> rid of the save concept, replacing it with an enum solution.  The
>>> current save regime is a fallacy, because it's not enforced.  It's as
>>> bad as c++ const.
>>>
>>> At the very least, let's wait until someone actually comes up with a
>>> valid use case for reference-based forward ranges before changing any
>>> code.  So far, all I've seen is boilerplate *RangeObject, no real
>>> usages.
>>
>> As long as most functions in std.algorithm don't take the ranges as ref
>> arguments, you need to use a reference-based range whenever you want
>> the function to consume the original range.
>>
>> BTW, this is why I suggested earlier that we add a byRef range.  If you
>> absolutely want the function foo() to consume your range, write
>>
>>    foo(byRef(myRange));
> 
> Do you have a real example besides foo which makes sense on both byRef
> and by value ranges?

Well, I did try my hand at writing a parser for a wiki-style markup 
language a while ago, which got its input from an input range.

It would look at the front of the range, determine what kind of element 
was there (paragraph, heading, bullet list, etc.), and pass the range on 
to a specialised function for dealing with that kind of element 
(parseHeading(), etc.).

Of course, those functions had to consume the original range, otherwise 
the same element would be repeated over and over again.  For simple 
cases, this was only a matter of parseWhatever() taking the range by ref, 
and everything would work nicely.  Sometimes, however, the range would be 
wrapped by another range (such as Take or Until).  If I wanted these to 
keep consuming the original range, I had to wrap it with byRef().

This happened often enough, and became annoying enough, that I ended up 
using InputRange objects everywhere instead.

-Lars


More information about the Digitalmars-d mailing list