>> But `popFront()` changes an internal state with visible, external >> effects: it changes `front` return value and in the end, it will >> affect `empty` return value. >> So no, I don't consider `popFront` to be pure. > > None of that matters for pure. _All_ that matters for pure is that the > function does not access global, mutable state - so no mutable global or > static variables. _Strong_ purity requires more, but you're not going to get > that with a member function anyway, unless it's immutable, which is almost > never the case. > > If you're trying to think about functional purity when dealing with pure, > you're definitely going to misunderstand it, because functional purity really > has very little to do with D's pure. At this point, pure is all about > indicating that the function does not access anything mutable that you don't > pass to it.
I know the difference between functional purity and D purity. It's just I consider the range internal state to *be* something mutable that I don't pass to the member. I never considered that code like this: auto a = range.front(); auto temp = a; range.popFront(); // pure popFront()? a = range.front(); assert(temp != a); // pure popFront() modified range.front() value! could be authorized. Maybe that's because, until now, I only *read* about D purity and never tried to use it in my code. > I think that the typical approach at this point is to just drop purity for the > moment, but if you want you really want it, you are indeed going to have to > implement it yourself. But we'll get there with Phobos eventually. The primary > holdup is some compiler improvements, and we'll get them. It's just a question > of when. I implemented it myself without problem (~ 10 LoC). The trouble really came from `joiner` using an internal struct. I wanted to keep purity, if only to get a feeling of the kind of constraints it adds to my coding style. I regularly try to 'limit' myself to CTFE-compatible code, since I often use my code at compile-time. I would like to also learn to write pure code, as fas as possible (and drop it when it's not reasonable, of course).