Range Redesign: Copy Semantics
Paul Backus
snarwin at gmail.com
Tue Jan 23 00:57:49 UTC 2024
On Monday, 22 January 2024 at 23:07:28 UTC, Jonathan M Davis
wrote:
> In practice, basic input ranges don't work with the vast
> majority of algorithms anyway. Some do (e.g. map), but pretty
> much anything that needs to do more than a simple
> transformation on the elements ends up needing a forward range.
> I really don't think that we're going to lose much by forcing
> basic input ranges to be separate.
Here's a very rough approximation of the number of algorithms in
Phobos that work with basic input ranges:
$ grep 'isInputRange' std/algorithm/*.d | wc -l
153
For comparison, here are the other range types:
$ grep 'isForwardRange' std/algorithm/*.d | wc -l
141
$ grep 'isBidirectionalRange' std/algorithm/*.d | wc -l
42
$ grep 'isRandomAccessRange' std/algorithm/*.d | wc -l
62
So, I would say that your hypothesis is not supported by the
data, in this case.
> Do they? Non-copyable types do not work with ranges right now.
> They don't work with foreach right now. Non-copyable types have
> their uses to be sure, but they're also fairly niche.
Work is being done to make ranges work with non-copyable types
(e.g. [1]).
Foreach works if the elements are rvalues, or the elements are
lvalues and you use ref for the loop variable. This is the
correct, expected behavior.
I think a big part of the reason non-copyable types are not
widely used is that a lot of existing library code was written
without support for them in mind. Since we have an opportunity to
start from scratch with Phobos v3, there is no reason to repeat
this mistake.
[1] https://github.com/dlang/phobos/pull/8721
> trying to support non-copyable types will actively make
> range-base code worse in many cases, because it will require
> calling front multiple times, and many range-based algorithms
> do real work in front rather than simply returning a value
> (e.g. map works that way).
Have you ever actually written generic code that works with
non-copyable types? I have, and it mostly involves (a) passing
things by ref, (b) using 'auto ref' and core.lifetime.forward a
lot, and (c) checking isCopyable!T before trying to copy things.
I have no idea why you think this would require calling front
multiple times, or doing extra work. Perhaps you could try
writing out some example code to clarify?
> Personally, I think that we should make it very explicit that
> non-copyable types are not supported by ranges. They don't work
> with them now, and I don't think that it's even vaguely worth
> it to try to make ranges work with them. The cost is too high
> for too little benefit.
First, as a general rule, I don't think that we, as
standard-library authors, should be in the business of telling
our users that their use-cases are illegitimate just because it
makes our jobs more difficult.
Second...how do you know the benefit is too little? You thought
earlier that "the vast majority of algorithms" didn't work with
basic input ranges, even though the actual data shows that isn't
true. Unless you have concrete evidence, I think it is better to
avoid making assumptions about which use-cases are important and
which aren't.
More information about the Digitalmars-d
mailing list