Re: Pure delegate not quite pure?

2015-07-01 Thread Tofu Ninja via Digitalmars-d-learn
On Wednesday, 1 July 2015 at 12:34:35 UTC, Steven Schveighoffer 
wrote:
immutable is probably incorrect without a cast, since immutable 
cannot be applied implicitly to non-immutable data, and if the 
data is all immutable already, no sense in tagging it immutable.


I really see use in allowing const.

inout is sketchy, I'm trying to think of how this applies, 
since inout is really for data types that are varied in their 
constancy. A function has only one addressable instance.


shared, well... I don't think we need it. Function stacks 
shouldn't be shared.


One thing you CAN do as a workaround, is put all your data to 
return into a static struct, and return delegates that address 
your data:


auto foo()
{
static struct Storage
{
int x = 4;
pure int dg() immutable { return x * x;} // should be 
strong-pure

}
immutable(Storage) s;
auto d = &s.dg; // I *think* this allocates a closure, but 
if not, that's a bug.

writeln(d());
// s.x = 5; // invalid
return d;
}

Really, a delegate on a function stack is like a 
single-instance private-defined struct like written above.


-Steve


The benefit of tagging it immutable would be to require the 
delegate to always have an immutable context, for instance, I am 
accepting a delegate as an argument to a function, but currently 
right now I have no way to guarantee that the context i receive 
is immutable. If it was marked immutable, then the supplier of 
the delegate would be forced to use only immutable things in the 
context. That's the primary benefit I see.


ie: void doSomethingWithDelegate(int delegate() pure @nogc @safe 
nothrow immutable del)


That actually compiles, but it will only accept delegates to 
member functions. ._.


I dont really know enough about shared and inout to comment on if 
they could be useful, I only mentioned them because you can put 
them on member functions.




Re: Pure delegate not quite pure?

2015-07-01 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/30/15 9:29 PM, Tofu Ninja wrote:

On Wednesday, 1 July 2015 at 00:13:36 UTC, Jesse Phillips wrote:

On Tuesday, 30 June 2015 at 22:23:40 UTC, Tofu Ninja wrote:

On Tuesday, 30 June 2015 at 22:05:43 UTC, Steven Schveighoffer wrote:

Have you tried placing const on the function signature? i.e.:

pure int delegate() const d = () const {...

That's how you'd do it (I think, didn't test) if the delegate
context pointer was a class/struct.



Nah, says its only available for non-static member functions.


hmm, it seems that this would be an appropriate enhancement. It
doesn't make sense on a function, but as it relates to delegates I'd
say it makes sense to allow const to be added.


const, immutable, shared, inout. Not sure if they all make sense on
delegates, but those are the options for member functions, so they might
apply to delegates as well.


immutable is probably incorrect without a cast, since immutable cannot 
be applied implicitly to non-immutable data, and if the data is all 
immutable already, no sense in tagging it immutable.


I really see use in allowing const.

inout is sketchy, I'm trying to think of how this applies, since inout 
is really for data types that are varied in their constancy. A function 
has only one addressable instance.


shared, well... I don't think we need it. Function stacks shouldn't be 
shared.


One thing you CAN do as a workaround, is put all your data to return 
into a static struct, and return delegates that address your data:


auto foo()
{
static struct Storage
{
int x = 4;
pure int dg() immutable { return x * x;} // should be strong-pure
}
immutable(Storage) s;
auto d = &s.dg; // I *think* this allocates a closure, but if not, 
that's a bug.

writeln(d());
// s.x = 5; // invalid
return d;
}

Really, a delegate on a function stack is like a single-instance 
private-defined struct like written above.


-Steve


Re: Pure delegate not quite pure?

2015-06-30 Thread Jesse Phillips via Digitalmars-d-learn

On Tuesday, 30 June 2015 at 22:23:40 UTC, Tofu Ninja wrote:
On Tuesday, 30 June 2015 at 22:05:43 UTC, Steven Schveighoffer 
wrote:

Have you tried placing const on the function signature? i.e.:

pure int delegate() const d = () const {...

That's how you'd do it (I think, didn't test) if the delegate 
context pointer was a class/struct.


-Steve


Nah, says its only available for non-static member functions.


hmm, it seems that this would be an appropriate enhancement. It 
doesn't make sense on a function, but as it relates to delegates 
I'd say it makes sense to allow const to be added.


Re: Pure delegate not quite pure?

2015-06-30 Thread Tofu Ninja via Digitalmars-d-learn

On Wednesday, 1 July 2015 at 00:13:36 UTC, Jesse Phillips wrote:

On Tuesday, 30 June 2015 at 22:23:40 UTC, Tofu Ninja wrote:
On Tuesday, 30 June 2015 at 22:05:43 UTC, Steven Schveighoffer 
wrote:

Have you tried placing const on the function signature? i.e.:

pure int delegate() const d = () const {...

That's how you'd do it (I think, didn't test) if the delegate 
context pointer was a class/struct.


-Steve


Nah, says its only available for non-static member functions.


hmm, it seems that this would be an appropriate enhancement. It 
doesn't make sense on a function, but as it relates to 
delegates I'd say it makes sense to allow const to be added.


const, immutable, shared, inout. Not sure if they all make sense 
on delegates, but those are the options for member functions, so 
they might apply to delegates as well.


Re: Pure delegate not quite pure?

2015-06-30 Thread Tofu Ninja via Digitalmars-d-learn
On Tuesday, 30 June 2015 at 22:05:43 UTC, Steven Schveighoffer 
wrote:

Have you tried placing const on the function signature? i.e.:

pure int delegate() const d = () const {...

That's how you'd do it (I think, didn't test) if the delegate 
context pointer was a class/struct.


-Steve


Nah, says its only available for non-static member functions.


Re: Pure delegate not quite pure?

2015-06-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/30/15 5:44 PM, Tofu Ninja wrote:

On Tuesday, 30 June 2015 at 21:31:05 UTC, Steven Schveighoffer wrote:

On 6/30/15 5:23 PM, Tofu Ninja wrote:

On Sunday, 28 June 2015 at 10:19:05 UTC, anonymous wrote:

[...]


Is there any way to annotate the context as const?


const x = 4 ;)

But even if you could annotate just the *reference* as const, it
doesn't stop foo from changing it as you did in the example.



Yeah, but I am more worried about d changing x by itself(though foo
changing it is still a problem), I have a piece of code that takes a
delegate and I want to ensure that it runs in the same way every time
once it's given to me.


Have you tried placing const on the function signature? i.e.:

pure int delegate() const d = () const {...

That's how you'd do it (I think, didn't test) if the delegate context 
pointer was a class/struct.


-Steve


Re: Pure delegate not quite pure?

2015-06-30 Thread Tofu Ninja via Digitalmars-d-learn

On Tuesday, 30 June 2015 at 22:23:40 UTC, Tofu Ninja wrote:
On Tuesday, 30 June 2015 at 22:05:43 UTC, Steven Schveighoffer 
wrote:

Have you tried placing const on the function signature? i.e.:

pure int delegate() const d = () const {...

That's how you'd do it (I think, didn't test) if the delegate 
context pointer was a class/struct.


-Steve


Nah, says its only available for non-static member functions.


Also wouldn't being able to annotate it immutable(also doesn't 
work) solve both problems. If the context was immutable then 
everything in it would have to be as well, d couldn't change it 
and foo wouldn't be able to as well because every thing in the 
context would have to be immutable. Or maybe I am understanding 
it wrong.


Re: Pure delegate not quite pure?

2015-06-30 Thread Tofu Ninja via Digitalmars-d-learn
On Tuesday, 30 June 2015 at 21:31:05 UTC, Steven Schveighoffer 
wrote:

On 6/30/15 5:23 PM, Tofu Ninja wrote:

On Sunday, 28 June 2015 at 10:19:05 UTC, anonymous wrote:

[...]


Is there any way to annotate the context as const?


const x = 4 ;)

But even if you could annotate just the *reference* as const, 
it doesn't stop foo from changing it as you did in the example.


-Steve


Yeah, but I am more worried about d changing x by itself(though 
foo changing it is still a problem), I have a piece of code that 
takes a delegate and I want to ensure that it runs in the same 
way every time once it's given to me.


Re: Pure delegate not quite pure?

2015-06-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/30/15 5:23 PM, Tofu Ninja wrote:

On Sunday, 28 June 2015 at 10:19:05 UTC, anonymous wrote:

[...]


Is there any way to annotate the context as const?


const x = 4 ;)

But even if you could annotate just the *reference* as const, it doesn't 
stop foo from changing it as you did in the example.


-Steve


Re: Pure delegate not quite pure?

2015-06-30 Thread Tofu Ninja via Digitalmars-d-learn

On Sunday, 28 June 2015 at 10:19:05 UTC, anonymous wrote:

[...]


Is there any way to annotate the context as const?


Re: Pure delegate not quite pure?

2015-06-28 Thread anonymous via Digitalmars-d-learn

On Sunday, 28 June 2015 at 09:19:16 UTC, Tofu Ninja wrote:

module main;
import std.stdio;
void main(string[] args)
{
auto d = foo();
writeln(d()); // prints 25
}

auto foo()
{
int x = 4;
pure int delegate() d = delegate()
{
return x*x;
};
writeln(d()); // prints 16
x = 5;
writeln(d()); // prints 25
return d;
}

I can see that after foo returns, then d will truly be pure as 
x will no longer be modifiable, but just before that, it seems 
d is not actually pure. Is this the intended behavior?


Here's a similar example where it's a bit clearer what's going on:

struct S
{
int x = 0;
int d() pure {return ++this.x;}
}
void main()
{
S s;
int delegate() pure d = &s.d;
import std.stdio;
writeln(d()); /* prints "1" */
writeln(d()); /* prints "2" */
writeln(d()); /* prints "3" */
}


`d` isn't all that pure, right? You're seeing the concept of 
"weak purity" in action. In D, the attribute `pure` really just 
means "doesn't access global mutable state". The function is 
still allowed to mutate any arguments it gets, including hidden 
ones. Here the method `d` has a hidden `this` parameter, and it 
can mutate data through it. With a nested function, the enclosing 
context is passed via a hidden parameter.


Properly/mathematically/strongly pure functions have additional 
requirements on top of being marked `pure`. Read more here:

http://klickverbot.at/blog/2012/05/purity-in-d/


Re: Pure delegate not quite pure?

2015-06-28 Thread via Digitalmars-d-learn

On Sunday, 28 June 2015 at 09:19:16 UTC, Tofu Ninja wrote:

module main;
import std.stdio;
void main(string[] args)
{
auto d = foo();
writeln(d()); // prints 25
}

auto foo()
{
int x = 4;
pure int delegate() d = delegate()
{
return x*x;
};
writeln(d()); // prints 16
x = 5;
writeln(d()); // prints 25
return d;
}

I can see that after foo returns, then d will truly be pure as 
x will no longer be modifiable, but just before that, it seems 
d is not actually pure. Is this the intended behavior?


Just guessing: The context is treated as an implicit parameter of 
`d` (analogous to `this` for a struct/class). Access to `x` 
counts a access through a parameter and therefore doesn't violate 
purity.


Pure delegate not quite pure?

2015-06-28 Thread Tofu Ninja via Digitalmars-d-learn

module main;
import std.stdio;
void main(string[] args)
{
auto d = foo();
writeln(d()); // prints 25
}

auto foo()
{
int x = 4;
pure int delegate() d = delegate()
{
return x*x;
};
writeln(d()); // prints 16
x = 5;
writeln(d()); // prints 25
return d;
}

I can see that after foo returns, then d will truly be pure as x 
will no longer be modifiable, but just before that, it seems d is 
not actually pure. Is this the intended behavior?