pure-ifying my code

Jonathan M Davis jmdavisProg at gmx.com
Sun Nov 17 02:55:57 PST 2013


On Sunday, November 17, 2013 11:25:33 Philippe Sigaud wrote:
> On Sun, Nov 17, 2013 at 11:17 AM, Jonathan M Davis <jmdavisProg at 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


More information about the Digitalmars-d-learn mailing list