August 26, 2016
On 08/26/2016 09:51 PM, Patrick Schluter wrote:
> On Friday, 26 August 2016 at 14:03:13 UTC, Meta wrote:
[...]
>> class Test
>> {
>>     int n;
>>
>>     void setN(int val) pure
>>     {
>>         n = val;
>>     }
>>
>>     int getN() const pure
>>     {
>>         return n;
>>     }
>> }
>
> getN() is not pure, simple as that (and an ideal compiler should
> complain in that case). A function is pure if it depends only of the
> state passed as parameter. If it touches memory that is set outside its
> scope it is NOT PURE!!!

You can rewrite that code like this:

----
class Test {/* ... as before but without getN ... */}
int getN(const Test test) pure { return test.n; }
----

Is getN pure now? It only touches memory via the parameter.

For methods we can think of `this` as a hidden parameter. If the method is tagged `const` or `immutable`, it's really that hidden parameter that is being qualified.
August 26, 2016
On Friday, 26 August 2016 at 19:58:47 UTC, ag0aep6g wrote:
> On 08/26/2016 09:51 PM, Patrick Schluter wrote:
>> On Friday, 26 August 2016 at 14:03:13 UTC, Meta wrote:
> [...]
>>> class Test
>>> {
>>>     int n;
>>>
>>>     void setN(int val) pure
>>>     {
>>>         n = val;
>>>     }
>>>
>>>     int getN() const pure
>>>     {
>>>         return n;
>>>     }
>>> }
>>
>> getN() is not pure, simple as that (and an ideal compiler should
>> complain in that case). A function is pure if it depends only of the
>> state passed as parameter. If it touches memory that is set outside its
>> scope it is NOT PURE!!!
>
> You can rewrite that code like this:
>
> ----
> class Test {/* ... as before but without getN ... */}
> int getN(const Test test) pure { return test.n; }
> ----
>
> Is getN pure now? It only touches memory via the parameter.
>
> For methods we can think of `this` as a hidden parameter. If the method is tagged `const` or `immutable`, it's really that hidden parameter that is being qualified.

Yes. The optimisation of removing the second call is only possible if there is no access using the this pointer. The call to setN() (or any member function using the mutable this pointer), will mandate the compiler to call getN() again.


August 26, 2016
On 08/26/2016 10:09 PM, Patrick Schluter wrote:
> Yes. The optimisation of removing the second call is only possible if
> there is no access using the this pointer. The call to setN() (or any
> member function using the mutable this pointer), will mandate the
> compiler to call getN() again.

If setN is called or not does not affect getN's purity, though. You wrote that (the method) getN is not pure and should be rejected by the compiler, but both variants (method and function) are equally pure or impure.
August 26, 2016
On Friday, 26 August 2016 at 20:35:13 UTC, ag0aep6g wrote:
> On 08/26/2016 10:09 PM, Patrick Schluter wrote:
>> Yes. The optimisation of removing the second call is only possible if
>> there is no access using the this pointer. The call to setN() (or any
>> member function using the mutable this pointer), will mandate the
>> compiler to call getN() again.
>
> If setN is called or not does not affect getN's purity, though. You wrote that (the method) getN is not pure and should be rejected by the compiler, but both variants (method and function) are equally pure or impure.

Yeah, I was wrong, the function getN() is pure (but not const). The thing is, that the compiler can remove a second call to a pure function only if it can make sure that there are no memory changes via one of the pointers of the functions. To give an example coming from C (sorry, I'm nearly only a C man).
strlen(p) is pure. A second call to strlen(p) can only by removed if the compiler can guarantee that no change was done to the memory pointed to by p. Unfortunately that does not happen really that often. Even a simple call to strcpy(whatever, p) will break the optimisation (char * are always potentially aliased).
So again, sorry for posting too quickly, shouldn't post after drinking Belgian beer ;-)
August 26, 2016
On 08/26/2016 10:48 PM, Patrick Schluter wrote:
> the function getN() is pure (but not const).

How is it not const? It doesn't alter the object. setN is the non-const one.
August 27, 2016
On Friday, 26 August 2016 at 19:51:02 UTC, Patrick Schluter wrote:
> On Friday, 26 August 2016 at 14:03:13 UTC, Meta wrote:
>> On Friday, 26 August 2016 at 10:51:15 UTC, Johan Engelen wrote:
>>> On Thursday, 25 August 2016 at 14:42:28 UTC, Basile B. wrote:
>>>> 
>>>> I'll add
>>>>
>>>> * create temporaries based on the const function attribute.
>>>
>>> Struct method constness (as in your example) does not mean that the return value is constant when calling it twice in a row. As pointed out by others, the function needs to be pure. Dlang pureness is not a strong enough guarantee.
>>> For example, this is explicitly allowed by the spec:
>>> ```
>>> pure int foo()
>>> {
>>>     debug writeln("in foo()"); // ok, impure code allowed in debug statement
>>>     return 1;
>>> }
>>> ```
>>> That makes it illegal to transform `foo()+foo()` to `a=foo(); a+a`, at least in debug builds.
>>>
>>> David discusses your proposed optimization, and why it cannot be done in general (!) on Dlang pure functions.
>>> http://klickverbot.at/blog/2012/05/purity-in-d/
>>>
>>> -Johan
>>
>> Here's an example that doesn't even need to use debug statements, and is perfectly legal.
>>
>> class Test
>> {
>>     int n;
>>
>>     void setN(int val) pure
>>     {
>>         n = val;
>>     }
>>
>>     int getN() const pure
>>     {
>>         return n;
>>     }
>> }
>
> getN() is not pure, simple as that (and an ideal compiler should complain in that case). A function is pure if it depends only of the state passed as parameter. If it touches memory that is set outside its scope it is NOT PURE!!!
>
>>
>> import std.stdio;
>>
>> void main()
>> {
>>     auto t = new Test();
>>     writeln(t.getN()); //Prints 0
>>     t.setN(1);
>>     writeln(t.getN()); //Prints 1
>
> It has to, as getN() is not pure.
>
>> }
>
> In case you didn't get it, getN() is not pure. Marking it as such is a BUG!.

Not according to the D spec.
August 29, 2016
Am Thu, 25 Aug 2016 11:45:40 +0000
schrieb Cauterite <cauterite@gmail.com>:

> - if a function is pure and called with constexpr parameters, the compiler could potentially execute that call in the CTFE engine (automatically), as part of the constant-folding phase I guess. Such a technique will hopefully one day be practical, once the CTFE engine's performance improves.

Just a note on where compiler technology stands right now: Const-folding after inlining will have this effect for small pure functions. I've also seen GCC duplicate functions to remove one of the arguments with a constant if it figured it could optimize the function around that argument. This is effectively the same as having a 2nd version of the function that takes the run-time argument as a compile-time argument.

-- 
Marco

1 2 3 4
Next ›   Last »