[Issue 16056] immutable delegate can mutate through context pointer

2016-05-24 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16056

Sobirari Muhomori  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |DUPLICATE

--- Comment #7 from Sobirari Muhomori  ---


*** This issue has been marked as a duplicate of issue 1983 ***

--


[Issue 16056] immutable delegate can mutate through context pointer

2016-05-24 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16056

--- Comment #6 from Eyal Lotem  ---
(In reply to ag0aep6g from comment #5)
> (In reply to Eyal Lotem from comment #4)
> > immutable void delegate() pure
> > 
> > vs.
> > 
> > immutable void delegate() immutable pure
> 
> When the delegate is part of an immutable struct instance, it has the former
> type, too:
> 
> 
> struct S { void delegate() pure f; }
> immutable s = S();
> pragma(msg, typeof(s.f)); /* immutable(void delegate() pure) */
> 
> 
> I suppose your point is that it should be the latter type, with two
> "immutable"s.
> 
> Fair enough, but I don't think that distinction is worth having. D doesn't
> have head const with pointers. Why should we make delegates a special case?
> 
> So in my opinion, `immutable void delegate()` should imply an immutable
> context pointer, making it the same type as `immutable void delegate()
> immutable`. Just like `immutable(int*)` is the same as
> `immutable(immutable(int)*)`.
> 
> The compiler agrees (to some extent):
> 
> 
> alias A = immutable int* delegate();
> alias B = immutable int* delegate() immutable;
> static assert(is(A == B)); /* passes */
> 
> 
> But then there's this:
> 
> 
> void main()
> {
> int x = 1;
> const void delegate() dg1 = { ++x; };
> const void delegate() const dg2 = { ++x; };
> }
> 
> 
> That compiles, but when you take the dg1 line away, then the dg2 line isn't
> accepted anymore. And when you swap them around, both lines are rejected.
> There's obviously something wrong here. I've filed a separate issue:
> https://issues.dlang.org/show_bug.cgi?id=16058

I agree `immutable delegate ..`  should imply the context is immutable too
(i.e: no head-const ptrs).
But possibly not the other way around.
It makes sense to have a mutable delegate with an immutable context (like a
mutable ptr to immutable data).

--


[Issue 16056] immutable delegate can mutate through context pointer

2016-05-22 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16056

--- Comment #5 from ag0ae...@gmail.com ---
(In reply to Eyal Lotem from comment #4)
> immutable void delegate() pure
> 
> vs.
> 
> immutable void delegate() immutable pure

When the delegate is part of an immutable struct instance, it has the former
type, too:


struct S { void delegate() pure f; }
immutable s = S();
pragma(msg, typeof(s.f)); /* immutable(void delegate() pure) */


I suppose your point is that it should be the latter type, with two
"immutable"s.

Fair enough, but I don't think that distinction is worth having. D doesn't have
head const with pointers. Why should we make delegates a special case?

So in my opinion, `immutable void delegate()` should imply an immutable context
pointer, making it the same type as `immutable void delegate() immutable`. Just
like `immutable(int*)` is the same as `immutable(immutable(int)*)`.

The compiler agrees (to some extent):


alias A = immutable int* delegate();
alias B = immutable int* delegate() immutable;
static assert(is(A == B)); /* passes */


But then there's this:


void main()
{
int x = 1;
const void delegate() dg1 = { ++x; };
const void delegate() const dg2 = { ++x; };
}


That compiles, but when you take the dg1 line away, then the dg2 line isn't
accepted anymore. And when you swap them around, both lines are rejected.
There's obviously something wrong here. I've filed a separate issue:
https://issues.dlang.org/show_bug.cgi?id=16058

--


[Issue 16056] immutable delegate can mutate through context pointer

2016-05-22 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16056

--- Comment #4 from Eyal Lotem  ---
immutable void delegate() pure(In reply to ag0aep6g from comment #3)
> (In reply to Eyal Lotem from comment #2)
> > This is simpler -- but this simpler example isn't a bug: a pure func that
> > takes a mutable delegate is "weakly pure" because it doesn't take an
> > immutable argument. You could say that the simplified pure func takes an
> > explicitly mutable argument, so it is known to be weakly pure.
> 
> pure_func's parameter isn't mutable. It's explicitly marked immutable.

immutable void delegate() pure

vs.

immutable void delegate() immutable pure

Arguably, you can claim that if you've chosen the former form, you knowingly
forfeited mutability for the delegate.

However, once the delegate is wrapped in a struct, you would expect that
transitivity would take care of full immutability.

--


[Issue 16056] immutable delegate can mutate through context pointer

2016-05-22 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16056

--- Comment #3 from ag0ae...@gmail.com ---
(In reply to Eyal Lotem from comment #2)
> This is simpler -- but this simpler example isn't a bug: a pure func that
> takes a mutable delegate is "weakly pure" because it doesn't take an
> immutable argument. You could say that the simplified pure func takes an
> explicitly mutable argument, so it is known to be weakly pure.

pure_func's parameter isn't mutable. It's explicitly marked immutable.

--


[Issue 16056] immutable delegate can mutate through context pointer

2016-05-22 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16056

--- Comment #2 from Eyal Lotem  ---
(In reply to ag0aep6g from comment #1)
> The struct doesn't really matter here, as far as I see. Simplified code:
> 
> 
> import std.stdio;
> 
> pure void pure_func(immutable void delegate() pure f)
> {
> f();
> }
> 
> void main() {
> int y;
> writeln("Before: ", y);
> pure_func({ y++; });
> writeln("After: ", y);
> }
> 
> 
> Possibly a duplicate of issue 11043 or issue 1983.

This is simpler -- but this simpler example isn't a bug: a pure func that takes
a mutable delegate is "weakly pure" because it doesn't take an immutable
argument. You could say that the simplified pure func takes an explicitly
mutable argument, so it is known to be weakly pure.

When you do take an immutable argument in a pure function -- the immutability
is supposed to be transitive -- so it is supposed to be strongly pure.

--


[Issue 16056] immutable delegate can mutate through context pointer

2016-05-22 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=16056

ag0ae...@gmail.com changed:

   What|Removed |Added

   Keywords||accepts-invalid
 CC||ag0ae...@gmail.com
  Component|dlang.org   |dmd
Summary|[The D Bug Tracker] |immutable delegate can
   ||mutate through context
   ||pointer
   Severity|enhancement |normal

--- Comment #1 from ag0ae...@gmail.com ---
The struct doesn't really matter here, as far as I see. Simplified code:


import std.stdio;

pure void pure_func(immutable void delegate() pure f)
{
f();
}

void main() {
int y;
writeln("Before: ", y);
pure_func({ y++; });
writeln("After: ", y);
}


Possibly a duplicate of issue 11043 or issue 1983.

--