On Tuesday, March 06, 2018 15:23:52 Adam D. Ruppe via Digitalmars-d-announce wrote: > On Tuesday, 6 March 2018 at 03:21:47 UTC, Nick Sabalausky > > (Abscissa) wrote: > > Wait, seriously? Phobos frequently passes ranges by value? > > You *should* pass most ranges by value, just like how you should > rarely use `ref T[]` or `T[]*`. Ranges, like slices, are > typically already small references to some other container. > > Where Phobos effs it up is not follow its own rules on range.save > in most cases... Jonathan talked about this at dconf IIRC in 2015.
Yeah. If you're dealing with generic code rather than a specific range type that you know is implicitly saved when copied, you have to use save so often that it's painful, and almost no one does it. e.g. equal(lhs.save, rhs.save) or immutable result = range.save.startsWith(needle.save); How well Phobos has done with this has improved over time as more and better testing has been added (testing for reference type ranges is probably the most critical to finding this particular problem), but I doubt that Phobos has it right everywhere, and I'm sure that the average programmer's code has tons of these problems. Code mostly just works because most code really isn't used with arbitrary ranges, and a large percentage of ranges implicitly save on copy. It's not that hard to get a piece of code working with a particular range or just a few similar range types. It's when it needs to work with _any_ range type that matches the template constraint that things start getting hairy, and without thorough testing, it simply doesn't happen unless the code is very simple and the programmer in question is very mindful of stuff like save (which most programmers aren't). And of course, since most testing is done with dynamic arrays, issues with other range types simply aren't found unless the programmer is really putting in the effort to do their due diligence. Ranges are wonderfully powerful, but they become a royal pain to get right with truly generic code. And that's without getting into all of the arguments about whether stuff like whether transitive fronts should be allowed... Ranges are definitely one area where we could really use some redesign to iron out some of the issues that we've found over time, but their success makes them almost impossible to fix, because changing them would break tons of code. But annoyingly, that's often what happens when you implement a new idea. You simply don't have enough knowledge about it ahead of time to avoid mistakes; those are easy enough to make when you really know what you're doing, let alone with something new. - Jonathan M Davis