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.
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.
artur