[phobos] [D-Programming-Language/phobos] 4f28db: not really pure
Steve Schveighoffer
schveiguy at yahoo.com
Tue Jun 28 06:47:22 PDT 2011
By definition, a strong-pure function must have all parameters immutable or implicitly convertible to immutable. This function does not pass this test.
However, the function call *could* be considered strong pure if the S instance itself is immutable (at the call site). Which means S s would have to be immutable, and the original assignment to &w does not compile. It was you who brought up this idea in the first place, if you recall :)
This means whether a function that takes const parameters is weak-pure or strong-pure can depend on what values you call it with.
But, Walter's changes to phobos seems to imply that member functions cannot even be weak-pure. I don't see any reason to disallow the member functions as weak-pure (and I think you are saying the same thing). If this is Walter's case, I think it has no merit, but I'll reserve judgment until I know that this is in fact Walter's concern.
BTW, immutable member functions could definitely be strong-pure (depending on the other parameters).
-Steve
----- Original Message -----
> From: Don Clugston <dclugston at googlemail.com>
> To: Discuss the phobos library for D <phobos at puremagic.com>
> Cc:
> Sent: Tuesday, June 28, 2011 8:34 AM
> Subject: Re: [phobos] [D-Programming-Language/phobos] 4f28db: not really pure
>
> My guess is that Walter is concerned about cases like this:
>
> struct S
> {
> int *p;
> void foo() pure const
> {
> return *p;
> }
> }
>
> static int w;
>
> void blah()
> {
> S s;
> s.p = &w;
> s.foo();
> }
>
> Although foo's only parameter is 'this', which is const, it still
> reads from a global variable.
> This means is that it's very difficult for a member function to be
> strongly pure. In fact, we wouldn't lose much by assuming that member
> functions are NEVER strongly pure.
>
> *But* this doesn't mean that they can't be weakly pure. If foo() is
> called from inside a strongly pure function, there is just no way that
> it can be impure, because there is no way that a global variable can
> be smuggled into it. The global would have to pass through the
> strongly pure function, and there is no way of doing that.
>
>
> On 28 June 2011 13:49, Steve Schveighoffer <schveiguy at yahoo.com> wrote:
>> I looked at the changes you made to phobos. Let me examine one of them:
>>
>> struct Complex(T) if (isFloatingPoint!T)
>> {
>> /** The real part of the number. */
>> T re;
>>
>> /** The imaginary part of the number. */
>> T im;
>>
>>
>> @safe nothrow /* removed attribute: pure */ // The following functions
> depend only on std.math.
>> {
>>
>> /** Calculate the absolute value (or modulus) of the number. */
>> @property T abs() const
>> {
>> return hypot(re, im);
>> }
>> In fact, the abs function *is* pure (since hypot is pure). Which is why
> I'm confused. It does not modify any global or shared state.
>>
>> If the compiler no longer compiles this as pure, then it does *NOT*
> implement weak-pure semantics. So I'm not sure what you mean by "I
> agree". This is a step backwards.
>>
>> I'll examine it directly. Complex!T.abs takes one parameter, a ref
> Complex!T. Given the definition of weak-pure, a function is allowed to accept
> and access references to mutable data -- even change them -- as long as the data
> is not typed as shared. It also does not call any impure functions or access
> any global variables. I think you are completely wrong in thinking this cannot
> be pure. If the compiler does not accept this, then the compiler has not
> implemented weak-pure.
>>
>> Do you have another case (even a theoretical one) that would have
> incorrectly compiled before this change? Certainly the changes I looked at were
> not accepts-invalid cases, given the context that weak-pure was implemented.
>>
>> The other option is you simply don't want weak-pure. Which is a design
> decision I don't agree with, but it's your decision. It might be hard
> to get those worms back in the can now!
>>
>> -Steve
>>
>>
>> ----- Original Message -----
>>> From: Walter Bright <walter at digitalmars.com>
>>> To: phobos at puremagic.com
>>> Cc:
>>> Sent: Monday, June 27, 2011 2:28 PM
>>> Subject: Re: [phobos] [D-Programming-Language/phobos] 4f28db: not
> really pure
>>>
>>> I understand and agree, but the previous code was so broken it would
> allow
>>> assignment through the 'this' pointer.
>>>
>>> On 6/27/2011 3:51 AM, Steve Schveighoffer wrote:
>>>> ----- Original Message -----
>>>>
>>>>> From: Walter Bright<walter at digitalmars.com>
>>>>>
>>>>>
>>>>>
>>>>> On 6/25/2011 8:25 PM, Jonathan M Davis wrote:
>>>>>> On 2011-06-25 20:23, Walter Bright wrote:
>>>>>>> On 6/25/2011 8:01 PM, Jonathan M Davis wrote:
>>>>>>>> If they're not really pure, they
> shouldn't
>>> compile with
>>>>> pure.
>>>>>>> They won't in the upcoming checkin.
>>>>>>>
>>>>>>>> Also, not being
>>>>>>>>
>>>>>>>> able to use opAssign in pure functions could be
> rather
>>> annoying.
>>>>> Why
>>>>>>>> doesn't that work?
>>>>>>> Pure functions cannot mutate data through pointers
> passed to
>>> them.
>>>>>> Weakly pure functions are supposed to be able to.
>>>>>>
>>>>>>
>>>>> The compiler wasn't checking this at all. It's
> possible we can
>>> loosen
>>>>> things up
>>>>> after we understand the issues better, but we should start
> with being
>>> very
>>>>> conservative about what purity means.
>>>> Don is probably the best to explain it, since he formalized the
> notion of
>>> weak pure, but I wholeheartedly agree with Jonathan, member functions
> that
>>> access or mutate mutable members can and should be pure, as long as
> they
>>> don't access or mutate shared or global data.
>>>>
>>>> If that isn't true, then the whole notion of weak purity that
> allows
>>> pure functions to be useful is out the window. I.e. pure functions
> will be
>>> reserved to the likes of std.math.sin, and nobody will mark any major
> functions
>>> pure.
>>>>
>>>> I thought weak purity had already been scrutinized, accepted, and
>>> purposefully added to the compiler? Were you not part of that
> discussion (I
>>> thought you were)? Does this reverse that decision? If so, I think it
> is the
>>> wrong move. Weak purity made pure functions not only useful, but
> actually
>>> pleasant to work with.
>>>>
>>>> To recap weak purity, a pure function is one that does not access
> mutable
>>> or const data that is shared or global, and it can only call pure
> functions.
>>>> A Strong-pure function is a pure function whose parameters and
> return value
>>> are all immutable or implicitly convertible to immutable.
>>>>
>>>> The compiler can only make pure-related optimizations on
> strong-pure
>>> functions. However, since weak-pure functions are still pure,
> strong-pure
>>> functions can call them.
>>>>
>>>> For instance, a useful idiom would be for a weak-pure function to
> sort an
>>> array in place. Without weak-purity, one has to re-implement sorting
> an array
>>> in every pure function they need it for, or write a functional-style
> sort (not a
>>> very easy or efficient thing).
>>>>
>>>> In other words, weak purity makes pure functions written in an
> imperative
>>> style able to be modular. Without it, you have to resort to functional
> style,
>>> or mixin everything into your local scope.
>>>>
>>>> -Steve
>>>>
>>>> _______________________________________________
>>>> phobos mailing list
>>>> phobos at puremagic.com
>>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>>
>>>>
>>> _______________________________________________
>>> phobos mailing list
>>> phobos at puremagic.com
>>> http://lists.puremagic.com/mailman/listinfo/phobos
>>>
>> _______________________________________________
>> phobos mailing list
>> phobos at puremagic.com
>> http://lists.puremagic.com/mailman/listinfo/phobos
>>
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos
>
More information about the phobos
mailing list