On Sunday, November 17, 2013 11:25:33 Philippe Sigaud wrote: > On Sun, Nov 17, 2013 at 11:17 AM, Jonathan M Davis <jmdavisp...@gmx.com> wrote: > >> DMD tells me `foo` cannot use the impure `joiner`, due to > >> `joiner`'s internal struct (Result) not having pure methods > >> (`empty`/`front`/`popFront`). > >> > >> Now, it seems obvious why these range methods are not pure > >> (`popFront`, at least). > > > > All of them should be able to be pure, as none of them access global or > > static variables. > > 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. Anything approaching functional purity and strong purity is then merely an optimization that can be done under very limited circumstances. And since additional calls to strongly pure functions are only optimized out within a single expression (or maybe statement - I'm not sure which - but certainly not across multiple statements), it's not like calls to strongly pure functions can be optimized out very often anyway. The other big gain from pure is the ability to change the mutability of the return type of a function under some circumstances, making it more flexible, but the whole idea that extra calls to it could be optimized out is more or less a fantasy outside of mathematical functions - and it definitely doesn't work with member functions, since they're almost never immutable like they'd have to be in order to be strongly pure. > >> But I don't use them in my function! I > >> just return a lazy range to iterate on other ranges. My own > >> function do not mutate anything, it just creates an object. A > >> mutable value admittedly, but not one with global state. > >> > >> I know Phobos is not using `pure` as much as it could right now, > >> but I really don't see why it's causing trouble right there. > > > > Likely because it's calling an impure constructor. The compiler does not > > currently properly infer purity for Voldemort types. > > > > https://d.puremagic.com/issues/show_bug.cgi?id=10329 > > > > Really, the compiler's attribute inferrence is pretty pathetic at this > > point. It only manages to infer attributes in the most basic of cases, > > and that's the number one reason that so little of Phobos works with pure > > right now. > Ah right, a Voldemort type, I did not know they could affect purity > determination. I find they regularly cause problems. Whenever I create > one, I then have to extract it from its enclosing father. > > I'll create my own simplified version of joiner for this problem. My > current code use an eager computation and I don't want that. 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. - Jonathan M Davis