foreach() behavior on ranges
Steven Schveighoffer
schveiguy at gmail.com
Wed Aug 25 11:49:18 UTC 2021
On 8/25/21 7:26 AM, Alexandru Ermicioi wrote:
> On Wednesday, 25 August 2021 at 11:04:35 UTC, Steven Schveighoffer wrote:
>> It never has called `save`. It makes a copy, which is almost always
>> the equivalent `save` implementation.
>>
>
> Really?
>
> Then what is the use for .save method then?
> The only reason I can find is that you can't declare constructors in
> interfaces hence the use of the .save method instead of copy constructor
> for defining forward ranges.
The `save` function was used to provide a way for code like
`isForwardRange` to have a definitive symbol to search for. It's also
opt-in, whereas if we used copying, it would be opt-out.
Why a function, and not just some enum? Because it should be something
that has to be used, not just a "documenting" attribute if I recall
correctly.
Keep in mind, UDAs were not a thing yet, and compile-time introspection
was not as robust as it is now. I'm not even sure you could disable copying.
>
> We have now two ways of doing the same thing, which can cause confusion.
> Best would be then for ranges to hide copy constructor under private
> modifier (or disable altoghether), and force other range wrappers call
> .save always, including foreach since by not doing so we introduce
> difference in behavior between ref and value forward ranges (for foreach
> use).
There would be a huge hole in this plan -- arrays. Arrays are the most
common range anywhere, and if a forward range must not be copyable any
way but using `save`, it would mean arrays are not forward ranges.
Not to mention that foreach on an array is a language construct, and
does not involve the range interface.
-Steve
More information about the Digitalmars-d-learn
mailing list