June 20, 2012
On 06/20/2012 08:02 PM, Artur Skawina wrote:
> On 06/20/12 15:58, Christophe Travert wrote:
>> Artur Skawina , dans le message (digitalmars.D:170305), a écrit :
>>> On 06/20/12 09:31, Christophe Travert wrote:
>>>> Artur Skawina , dans le message (digitalmars.D:170191), a écrit :
>>>>>> The proper way to do this is not cast, it is to give the proper
>>>>>> constness for all types and methods :
>>>>>>
>>>>>>     struct S {
>>>>>>        int i; this(int i) { this.i = i; }
>>>>>>        T* p;
>>>>>>        void f(int i) const { this.i = i; /*p.i++;*/ }
>>>>>> // the commented part is illegal because S.f is const
>>>>
>>>> I missed that. Then I disagree with your use of delegates. The solution
>>>> here is to make the free f function to take a non const T*, since the
>>>> function tries to modify variables from that T instance (via a
>>>> delegate).
>>>
>>> The issue is the delegate definition - what exactly is a delegate?
>>> My first message in this thread started with this sentence:
>>> "It's fine, if you view a delegate as opaque". Because if you do, then
>>> accesses via a delegates context pointer are no different from using
>>> an external reference. That message also contained a program to show
>>> how trivial bypassing const is, at least for impure functions. So
>>> banning "unsafe" delegates wouldn't really change the situation.
>>
>> Having opaque delegate and no holes in the langage is a possibility, but
>> not without changing the langage spec.
>>
>> With opaque delegates, you can't have a pure delegate, only pure
>> function pointers, because pure means you do not access external data,
>> and accessing data pointed by a the opaque frame pointer of the delegate
>> would be accessing external data.
>>
>> You may then redefine pure for delegate as delegates having only
>> immutable external data (const is not enough).
>>
>> I'm definitely not in favor of that solution.
>
> I agree with all of the above, maybe except the last sentence.
> The choice is between a) status quo, where the delegates are treated
> similarly to impure free functions, and b) handled "correctly".
> With scheme "a" I would expect to encounter genuine bugs extremely rarely,
> if ever; while if "b" would be enforced, the bugs directly or indirectly
> caused by working around the limitations would be plenty...
> Having a "cleaner" design, but one that results in more bugs is not really
> an improvement. Maybe there is a middle ground.
>

The type system must be sound. Some type system constraints can be
loosened, however.

> Anyway, that problem is not likely to get fixed quickly. In the mean time,
> there are serious compiler bugs related to the thread subject, which likely
> could. For example:
>
>     import std.stdio;
>
>     struct S {
>        int i; this(int i) { this.i = i; }
>        auto mutable() pure { return&i; }
>        void iAintAfraidOfNoConst() const pure { *(&mutable)()=-1813; }
>     }
>
>     void main() {
>        auto s = new immutable(S)(42);
>        writeln(*s);
>        s.iAintAfraidOfNoConst();
>        writeln(*s);
>     }
>
> The '&const(this).mutable' operation is clearly bogus and should not be
> allowed. But the compiler happily creates a delegate from a method and
> an incompatible instance reference, which in this case results in 'const'
> being dropped.
>
> (I have no DMD

http://dlang.org/download.html

> - can't test if the problem is still there, hence can't
> file a bug report)
>
> artur

It is still there.
June 21, 2012
Le 20/06/2012 20:08, Timon Gehr a écrit :
>> This set of rule prevent safe closure rebinding.
>
> There is no such thing as safe closure rebinding.

In D and ATM no. But this exists, and should be considered, as what you proposed totally exclude from being added later on.
June 25, 2012
On Mon, 18 Jun 2012 01:36:26 -0400, Mehrdad <wfunction@hotmail.com> wrote:

> Is it just me, or did I subvert the type system here?
>
>
> import std.stdio;
>
> struct Const
> {
> 	this(void delegate() increment)
> 	{ this.increment = increment; }
> 	int a;
> 	void delegate() increment;
> 	void oops() const { this.increment(); }
> }
>
> void main()
> {
> 	Const c;
> 	c = Const({ c.a++; });
> 	writeln(c.a);
> 	c.oops();
> 	writeln(c.a);
> }

This is quite a long thread, and I didn't read everything, but here is my take on this:

1. The issue is that the context pointer of the delegate, even though it is stored as part of the struct data, is not affected by coloring the containing struct as 'const'.

2. The issue is simply with delegate implicit casting, which the compiler does just about nothing with today.

Consider the following struct:

struct S
{
   int x;
   void foo() {++x;}
   void fooconst() const {}
}

Now, consider the following function:

void callit(void delegate() dg) { dg(); }

One of the *really* cool benefits of delegates is that you can pass both foo and fooconst to callit -- callit doesn't have to care what attributes are applied to the delegate's context pointer, it simply calls them.

However, consider if we *want* to make sure dg doesn't modify its context pointer, how can we write dg's type?  You could do this (if it worked):

void callit(void delegate() const dg) { dg(); }

What should this mean?  In my interpretation, it should mean that only a delegate that uses a const context pointer should be able to be bound to dg.  So &foo should *not* be able to be passed to callit.

If we can implement something like this, I think the problem would be solved.  What would happen to your original code?  oops would not compile, because you could not automatically convert a delegate to a const delegate (unless it was marked as const).  And I think it would be possible to keep the nifty feature of not caring what the context parameter is marked as.

-Steve
June 25, 2012
On 06/25/2012 04:08 PM, Steven Schveighoffer wrote:
> ...
>
> This is quite a long thread, and I didn't read everything, but here is
> my take on this:
>
> 1. The issue is that the context pointer of the delegate, even though it
> is stored as part of the struct data, is not affected by coloring the
> containing struct as 'const'.
>
> 2. The issue is simply with delegate implicit casting, which the
> compiler does just about nothing with today.
>
> Consider the following struct:
>
> struct S
> {
>     int x;
>     void foo() {++x;}
>     void fooconst() const {}
> }
>
> Now, consider the following function:
>
> void callit(void delegate() dg) { dg(); }
>
> One of the *really* cool benefits of delegates is that you can pass both
> foo and fooconst to callit -- callit doesn't have to care what
> attributes are applied to the delegate's context pointer, it simply
> calls them.
>
> However, consider if we *want* to make sure dg doesn't modify its
> context pointer, how can we write dg's type?  You could do this (if it
> worked):
>
> void callit(void delegate() const dg) { dg(); }
>
> What should this mean?  In my interpretation, it should mean that only a
> delegate that uses a const context pointer should be able to be bound to
> dg.  So &foo should *not* be able to be passed to callit.
>

It depends on what 'const' means. If 'const' means 'this reference cannot be used to change the data', then this is the only valid
interpretation.

> If we can implement something like this, I think the problem would be
> solved.  What would happen to your original code?  oops would not
> compile, because you could not automatically convert a delegate to a
> const delegate (unless it was marked as const).  And I think it would be
> possible to keep the nifty feature of not caring what the context
> parameter is marked as.
>
> -Steve

This is essentially the conclusion reached in the other parts of the discussion as well.

The issue is that implementing delegate context qualifiers correctly requires some changes, eg:
currently 'pure' for function literals means 'cannot access
non-immutable free variables', while actually it should mean 'cannot
access non-immutable static variables'.

Last time I asked, Walter made clear that such a change is not planned.
June 26, 2012
On Monday, 25 June 2012 at 17:33:18 UTC, Timon Gehr wrote:
> On 06/25/2012 04:08 PM, Steven Schveighoffer wrote:
> Last time I asked, Walter made clear that such a change is not planned.


Assuming that's still true today, do we have a proposal for fixing this?

(If not, then is it safe to say that the compiler may not optimize code based on purity/const-ness?)
3 4 5 6 7 8 9 10 11 12 13
Next ›   Last »