On Mon, 18 Jun 2012 01:36:26 -0400, Mehrdad <wfunct...@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

Reply via email to