I'm confused about ranges (input and forward in practice, in algorithms)

Alex Parrill via Digitalmars-d digitalmars-d at puremagic.com
Thu Aug 13 18:58:20 PDT 2015


On Friday, 14 August 2015 at 00:33:30 UTC, Luís Marques wrote:
> ...

Yea, it would be nice if all ranges were reference types, and 
calling `save` made a duplicate of the cursor (or whatever the 
range is supposed to be). However, that would mean that they 
would have to be allocated and garbage collected, which a lot of 
overhead that D is working to avoid. Or perhaps there's another 
solution that I can't think of.

Bitwise copying of a struct `rng` isn't necessarily the same as 
doing the same thing as `rng.save` though. Just because something 
is a struct, doesn't mean it has value semantics. 
`std.stdio.File` is technically a struct, but it's just a 
refcounted wrapper around a pointer to an internal file object, 
so it technically has reference semantics (hence why version(two) 
in your example is the output). This also applies to wrapper 
ranges like map and filter, if they wrap reference-semantic 
objects. Also consider a barebones range that contains only an 
`int` file descriptor.

Right now, I mostly treat it as if passing a range through a 
non-`ref` parameter consumes the original range.

I don't know if `startsWith` should take the range by reference, 
though. On one hand, it would allow you to use the range 
afterwards if it matches, but it would have weird, unexpected 
effects on code like this:

     string mystring = "Hello World";
     if(mystring.startsWith("Hello"))
         writeln(mystring) // This would print " World" because 
startsWith modified mystring

I do think `startsWith` not popping off the last character is a 
bit of a bug though.


More information about the Digitalmars-d mailing list