April 09, 2013
On 4/9/13 3:56 AM, Manu wrote:
> Are you saying the example above is not actually valid code?
>
> struct Foo {
>      int a = 0;
>      pure int bar( int n ) { // Weakly pure
>          a += n;
>          return a;
>      }
> }
>
> That's not pure. Call it twice with the same args, you'll different
> answers.

The values reachable from "this" are different in the two calls.

Andrei
April 09, 2013
On 4/9/13 4:04 AM, Dicebot wrote:
> On Tuesday, 9 April 2013 at 07:57:37 UTC, Manu wrote:
>> Are you saying the example above is not actually valid code?
>>
>> struct Foo {
>> int a = 0;
>> pure int bar( int n ) { // Weakly pure
>> a += n;
>> return a;
>> }
>> }
>>
>> That's not pure. Call it twice with the same args, you'll different
>> answers. How can that possibly be considered pure in any sense?
>> And it's useless in terms of optimisation, so why bother at all? What
>> does
>> it offer?
>
> It is valid code. It is "weak pure". "pure' keyword means both
> "strong pure" or "weak pure" depending on function body. Crap.

s/body/signature/
s/Crap/Awesome/


Andrei
April 09, 2013
On 4/9/13 4:43 AM, Simen Kjærås wrote:
> On Tue, 09 Apr 2013 10:33:45 +0200, Manu <turkeyman@gmail.com> wrote:
>> I suggest that no D language newbie would ever reasonably expect that
>> behaviour.
>
> And with that, I absolutely have to agree.

Me too. But then any innovation by definition has an element of surprise.

Andrei
April 09, 2013
On 4/9/13 6:48 AM, deadalnix wrote:
> On Tuesday, 9 April 2013 at 03:36:28 UTC, Walter Bright wrote:
>> On 4/8/2013 5:39 AM, Manu wrote:
>>> But D makes no further guarantee. I don't see how const in D is any
>>> different
>>> than const in C++ in that sense? That's basically the concept of
>>> const, it's not
>>> a useful concept for optimisation, only immutable is.
>>
>> In C++, it is legal to cast away const and mutate it. That is
>> undefined behavior in D.
>>
>> A D compiler can assume, for example, that a const reference passed to
>> a pure function will not mutate that reference, nor anything
>> transitively referred to by that reference. No such assumption can be
>> made like that in C++.
>
> No, D have holes in its type system and so can't ensure anything. It has
> been show many many many times, especially by Timon and myself, and I'm
> kind of fed up to have to repeat that again and again, especiallt since
> fix proposal have recieved no attention at all.
>
> Stop claiming that such possibility exists, or take a serious look at
> how to really ensure it.

Agreed. In parallel with work on improving quality, we also need to carefully address all holes in the type system.

Andrei
April 09, 2013
On Tuesday, 9 April 2013 at 11:27:57 UTC, Manu wrote:
> The only optimisation possibility is for strong pure functions that are
> also nothrow, right? Was that the conditions for pure function refactoring?

No as no guarantee can exists as long as type qualifier transitivity isn't ensured.
April 09, 2013
On 04/09/13 13:47, Simen Kjærås wrote:
> On Tue, 09 Apr 2013 13:10:16 +0200, Artur Skawina <art.08.09@gmail.com> wrote:
> 
>> A function that both directly depends on global mutable state (and modifies it) can hardly be called pure. Can you (anybody) give a D "pure" definition that allows for the program that I've posted and still makes "pure" useful?
> 
> Functions that are pure may only mutate mutable state explicitly passed to them, or created within.

   struct S;
   int f(S* p) pure;
   S* n();

   int g = 0;

   int main() {
      S* s = n();
      f(s);
      return g;
   }

Is main() guaranteed to return '0'?

artur
April 09, 2013
>
>    struct S;
>    int f(S* p) pure;
>    S* n();
>
>    int g = 0;
> 
>    int main() {
>       S* s = n();
>       f(s);
>       return g;
>    }
>
> Is main() guaranteed to return '0'?
> 
> artur

Dunno, how this makes an example if you use at least 2, probably 3 non pure functions (main, n, constructor of S).
April 09, 2013
On 04/09/2013 03:18 PM, Artur Skawina wrote:
> On 04/09/13 13:47, Simen Kjærås wrote:
>> On Tue, 09 Apr 2013 13:10:16 +0200, Artur Skawina <art.08.09@gmail.com> wrote:
>>
>>> A function that both directly depends on global mutable state (and
>>> modifies it) can hardly be called pure. Can you (anybody) give a
>>> D "pure" definition that allows for the program that I've posted
>>> and still makes "pure" useful?
>>
>> Functions that are pure may only mutate mutable state explicitly passed
>> to them, or created within.
>
>     struct S;
>     int f(S* p) pure;
>     S* n();
>
>     int g = 0;
>
>     int main() {
>        S* s = n();
>        f(s);
>        return g;
>     }
>
> Is main() guaranteed to return '0'?
>
> artur
>

No. What is the point?
April 09, 2013
On Tuesday, 9 April 2013 at 12:56:04 UTC, Andrei Alexandrescu wrote:
>> It is valid code. It is "weak pure". "pure' keyword means both
>> "strong pure" or "weak pure" depending on function body. Crap.
>
> s/body/signature/
> s/Crap/Awesome/

Not gonna argue latter but former is just wrong.

struct Test
{
    int a;
    pure int foo1() // strong pure
    {
        return 42;
    }

    pure int foo2() // weak pure
    {
        return a++;
    }
}

Signature is the same for both functions.
April 09, 2013
On Tuesday, 9 April 2013 at 13:49:12 UTC, Dicebot wrote:
> On Tuesday, 9 April 2013 at 12:56:04 UTC, Andrei Alexandrescu wrote:
>>> It is valid code. It is "weak pure". "pure' keyword means both
>>> "strong pure" or "weak pure" depending on function body. Crap.
>>
>> s/body/signature/
>> s/Crap/Awesome/
>
> Not gonna argue latter but former is just wrong.
>
> struct Test
> {
>     int a;
>     pure int foo1() // strong pure
>     {
>         return 42;
>     }
>
>     pure int foo2() // weak pure
>     {
>         return a++;
>     }
> }
>
> Signature is the same for both functions.

Think of all your member functions as non-member functions taking the object as a ref parameter.

pure int foo1(ref Test this) {
    return 42;
}

shouldn't be strongly pure (as it can access mutable non local state).