Le 19/06/2012 16:16, Artur Skawina a écrit :
On 06/19/12 15:29, deadalnix wrote:
Le 19/06/2012 14:30, Artur Skawina a écrit :
Due to D concept of weak purity, this doesn't ensure the required what we need 
here.

Actually, it does - if it can be proved that the delegate can't alter the object
via the context pointer (eg because whatever it points to is not mutable) then
even D's "pure" is enough. Because the delegate would need to be passed a 
mutable
ref to be able to alter the object, which then could hardly be constructed as
"breaking" constness.

But such a limit (const/immutable context) would be a problem for the cases 
where
the delegate needs to alter some state (like export the result of some 
operation),
but does _not_ modify the object it's embedded in. Note that the current object 
may
very well be reachable (and mutable) from the delegate - but at some point you 
have
to trust the programmer. Sure, fixing this hole would be great, but /how/ - w/o
incurring unacceptable collateral damage?


This isn't a problem as long as the delegate isn't a member of the object. If 
it is, transitivity is broken, which is something you don't want.

Relying on the trust on the programmer is a dumb idea. Human do mistake, way 
more than computers. The basic behavior MUST be a safe one.

Transitivity has been introduced for good reason and language already provide a 
way to break it via cast. So it is unacceptable to rely on programmer on that 
point.

It is possible to get the error when trying to call the delegate instead of 
preventing to make it const, as I said in the post you quote. It is probably a 
better solution.

Any delegate?


No, any delegate that have type that isn't covariant with the expected delegate 
type.

    struct S {
       int i; this(int i) { this.i = i; }
       T* p;
       void f(int i) { this.i = i; /*p.i++;*/ }
    }
    struct T {
       int i; this(int i) { this.i = i; }
       void delegate(int i) f;
    }

    void main() {
       auto t = new T(42);
       auto s = new S(17);
       s.p = t;
       t.f =&s.f;
       f(t);
    }

    void f(const (T)* t) {
       t.f(t.i*2);
    }

You're proposing to make the last 'f' function illegal, just because the
commented out part could happen. I'm saying that this is unlikely to happen
*by accident*, and of course would still be possible by casting away the
constness.

I think you are overcomplicating things. Yes, the call would be illegal.

But banning "unsafe" delegates would result in casts *when using "safe" ones*
- which is not a real improvement because this would make the "bad" casts much
harder to spot.


I think you don't understand the benefice of transitive type qualifier.

Reply via email to