Communicating between in and out contracts

Lutger lutger.blijdestijn at gmail.com
Wed Oct 14 14:34:02 PDT 2009


Andrei Alexandrescu wrote:

> Lutger wrote:
>> Between sharing the whole object and sharing scope lies specifying
>> exactly what to share, I'd think.
>> 
>> Here is one possible syntax, like regular function calls. Parameter types
>> can possibly be inferred and omitted:
>> 
>> void push(T value);
>> in {
>>    out(length());
>> }
>> out(size_t oldLength) {
>>    assert(value == top());
>>    assert(length == oldLength + 1);
>> }
> 
> 
> I think this could work. One of Walter's ideas was to pass the entire
> old object as an argument to out. Passing handpicked data is more work
> for the user but faster.
> 
> Perhaps this would simplify things a bit:
> 
> void push(T value);
> in {
>     auto oldLength = length;
> }
> out(oldLength) {
>     assert(value == top());
>     assert(length == oldLength + 1);
> }
> 
> Whatever parameters you pass to out they'd be matched by name with stuff
> defined in the "in" contract. That poses a problem because until now
> out(whatever) automatically passed the result to the out contract under
> the name "whatever".
> 
> 
> Andrei

Right, I forgot about that, you do need that return variable or have to 
invent a magic name. Jeremie's proposal doesn't have that problem, taking 
the reverse route of letting in{} define which variabeles are to be passed 
to the out function.

So either would work:
  in{
      auto oldLength = length;
      out(oldLength);    
  }
or:
  in{
      out auto oldLength = length;
  }

Whatever syntax is chosen, it doesn't strike me as cumbersome to handpick 
variables considering what you get from it. Also, some conditions may depend 
on calculated values, in those cases it may even be more straightforward  
than checking an old copy of the object.



More information about the Digitalmars-d mailing list