How do "pure" member functions work?
Jonathan M Davis
jmdavisProg at gmx.com
Sat Aug 20 17:18:05 PDT 2011
On Saturday, August 20, 2011 16:53:51 Sean Eskapp wrote:
> == Quote from Timon Gehr (timon.gehr at gmx.ch)'s article
>
> > On 08/20/2011 06:24 PM, Sean Eskapp wrote:
> > > == Quote from David Nadlinger (see at klickverbot.at)'s article
> > >
> > >> On 8/20/11 5:13 PM, Sean Eskapp wrote:
> > >>> Does marking a member function as pure mean that it will return
> > >>> the same result given the same parameters, or that it will give
> > >>> the same result, given the same parameters and given the same
> > >>> class/struct members?> >>
> > >> The second one, the implicit this parameter is just considered a
> > >> normal argument as far as purity is concerned.
> > >> David
> > >
> > > Wait, references and pointers are now valid for pure function
> > > arguments?>
> > There are different forms of pure functions:
> > weakly pure:
> > no mutable globals are read or written. the function may however change
> > its arguments. weakly pure functions are useful mainly for the
> > implementation of functions with stronger purity guarantees.
> > const pure/strongly pure:
> > All function arguments are values or const/immutable.
> >
> > From the type signature of a function, you can always tell which form
> >
> > of pure function it is:
> > int foo(ref int, int) pure; // weakly pure, could change first argument
> > int bar(const(int)*, int) pure; // const pure
> > int qux(immutable(int)*, int) pure; // strongly pure
> > Weakly pure member functions can therefore change the other members:
> > struct S{
> >
> > int x;
> > int foo() pure; // weakly pure, could change x
> > int bar() pure const; // const pure, cannot change x
> > int qux() pure immutable; // strongly pure, only works with
> >
> > immutable instances
> > }
> > The rationale of this:
> > Consider
> > int baz(int x) pure{
> >
> > S s=S(x);
> > S.foo();
> > return s;
> >
> > }
> > This is clearly strongly pure code. If we had no weakly pure, this could
> > not be written in that way.
>
> Oh, I see, thanks! This isn't documented in the function documentation!
The documentation takes the approach of saying what functions can be pure but
not how they can be optimized. Essentially, any function which doesn't access
any mutable global state and doesn't call any functions which aren't pure can
be pure. Weak and string purity come in when optimizing. Additional calls to
weakly pure functions can't be optimized out, because they can alter their
arguments. Additional calls to strongly pure functions _can_ be optimized out,
because the compiler can guarantee that its arguments aren't altered.
At present, a strongly pure function is a pure function where all of its
parameters (including the invisible this parameter) are either immutable or
implicitly convertible to immutable. But that could be expanded to include
pure functions whose parameters are all either const or implicitly convertible
to const in cases where the compiler knows that the function is being passed
immutable variables. So, right now, David is incorrect in thinking that
int bar(const(int)*, int) pure;
is strongly pure, but in the future, it probably will be in cases where it's
passed an immutable pointer.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list