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