Communicating between in and out contracts

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Fri Oct 16 14:07:35 PDT 2009


Rainer Deyke wrote:
> Andrei Alexandrescu wrote:
>> class A {
>>     int fun() { ... }
>>     int gun(int) { ... }
>>
>>     int foo()
>>     in {
>>     }
>>     out(result) {
>>         if (old.fun())
>>            assert(old.gun(5));
>>         else
>>            assert(old.fun() + old.gun(6));
>>         foreach (i; 1 .. old.fun())
>>            assert(gun(i * i));
>>     }
>>     ...
>> }
>>
>> Now please tell what's cached and in what order.
> 
> The following are cached, in this order:
>   fun()
>   gun(5)
>   gun(6)
> Old values are calculated in the order in which they appear in the
> function, but only once each.

Rats, I meant assert(old.gun(i * i)). That's what compounds the 
difficulty of the example.

> However, I strongly prefer the following syntax:
> 
>   class A {
>       int fun() { ... }
>       int gun(int) { ... }
> 
>       int foo()
>       in {
>       }
>       out(result) {
>           if (old(fun()))
>              assert(old(gun(5)));
>           else
>              assert(old(fun()) + old(gun(6)));
>           foreach (i; 1 .. old(fun()))
>              assert(gun(i * i));
>       }
>       ...
>   }
> 
> This lets you distinguish between the following cases:
>   old(f().g())
>   old(f()).g()
> 
> It also lets you cache non-members:
>   old(arg);
>   old(global_var);
> 
> For example:
> 
>   void increment_global_counter() out {
>     global_counter = old(global_counter) + 1;
>   }

I honestly believe the whole "old" thing can't be made to work. Shall we 
move on to other possibilities instead of expending every effort on 
making this bear dance?


Andrei




More information about the Digitalmars-d mailing list