On Thursday, January 25, 2024 1:57:56 AM MST Jim Balter via Digitalmars-d- learn wrote: > The specification of ranges, which is independent of > the D language, says that the way to copy a range is to use > save().
I'm sorry, but you're misunderstanding the range specification if you think that save is the only way to copy a range or that the range specification makes any such guarantee. And if there is any official documentation that makes any such claim, then it needs to be fixed, because ranges have never worked that way, and they cannot work that way unless ranges in general are non-copyable, which is not the case at all. What save does is give you a guaranteed way to get a copy which can be independently iterated. However, it's perfectly valid to simply copy a range and then use the copy. They're not non-copyable types, and range-based code in general copies ranges all over the place - both with basic input ranges and with forward ranges. They're copied when they're passed to functions. They're copied when they're wrapped by other ranges. They're copied when they're passed to foreach. This is all falls within the expected use of ranges. What you don't get from those copies is the guarantee that the copy is independent, which is why save is necessary in cases where you need to be sure that you're getting an independent copy of a range. I gave that long explanation to try to get across what was happening with the copy semantics of ranges and what the consequences of that are. If that wasn't helpful to you, then I'm sorry. Either way, if you think that it goes against the range API to copy a range any way other than by calling save, then you are misunderstanding how ranges work, and looking at how Phobos uses ranges should make that clear, because it copies them all over the place, including with code that works on basic input ranges. The range API guarantees that copying a range will result in the copy having the same elements in the same order as the original would have had had it not been copied, because without that guarantee, range-based code in general simply wouldn't work. Range-based code in general relies on that ability to copy a range when passing it around. Now, what happens to the original after the copy has been made is not specified by the range API, and that's why save is necessary. But you can still copy a range and use that copy in generic code so long as you don't touch the original again. So, I've tried to explain to you why the current behavior is expected and does not violate the range specification. If that's not enough for you, then I'm sorry. Maybe someone else can help you out, but if what you've said about save were correct, then Phobos as a whole would be violating the range specification - as would the language itself with foreach. But they've been working this way for well over a decade. We would like to improve the situation with the next major version of Phobos so that the copy semantics of ranges are cleaner, and the range API will likely see a redesign to fix that issue, among others, but the current range API is as I've explained it to you, warts and all. - Jonathan M Davis