Thread overview
'out' contracts accessing initial parameter values
Feb 08, 2005
Derek Parnell
Feb 09, 2005
Derek Parnell
Feb 09, 2005
Alex Stevenson
Feb 09, 2005
Regan Heath
Feb 09, 2005
Alex Stevenson
Feb 09, 2005
Regan Heath
February 08, 2005
I suspect that I'm trying to do something that can't be done (yet?).

I have a routine that is not a function (i.e. it returns void). I want to test in the 'out' condition that the inout parameter has indeed been effected by the routine. This means that I need to access the contents of the parameter as it was at the time of the 'in' condition, from within the 'out' condition. For example (this doesn't compile BTW) ...


 //----------------------------------------------------------
 void ReplaceChar(inout char[] pText, dchar pFrom, dchar pTo)
 //----------------------------------------------------------
 in {
    char[] lOldText;
    lOldText = pText.dup;

 }
 out {
    if ( (pFrom != pTo) && (pText.length > 0) )
        assert(pText != lOldText);
 }
 body {
    dchar[] lTemp;

    // Do nothing if the replacement char is
    // the same as the search char.
    if (pFrom == pTo)
        return;

    // Convert the utf8 string to utf32, call the utf32 routine,
    // then convert it back to utf8.
    lTemp = toUTF32(pText);
    ReplaceChar( lTemp, pFrom, pTo);
    pText = toUTF8(lTemp);

 }


-- 
Derek
Melbourne, Australia
8/02/2005 4:35:06 PM
February 09, 2005
On Tue, 8 Feb 2005 16:47:27 +1100, Derek Parnell wrote:

> I suspect that I'm trying to do something that can't be done (yet?).
> 
> I have a routine that is not a function (i.e. it returns void). I want to test in the 'out' condition that the inout parameter has indeed been effected by the routine. This means that I need to access the contents of the parameter as it was at the time of the 'in' condition, from within the 'out' condition. For example (this doesn't compile BTW) ...
> 
>  //----------------------------------------------------------
>  void ReplaceChar(inout char[] pText, dchar pFrom, dchar pTo)
>  //----------------------------------------------------------
>  in {
>     char[] lOldText;
>     lOldText = pText.dup;
> 
>  }
>  out {
>     if ( (pFrom != pTo) && (pText.length > 0) )
>         assert(pText != lOldText);
>  }
>  body {
>     dchar[] lTemp;
> 
>     // Do nothing if the replacement char is
>     // the same as the search char.
>     if (pFrom == pTo)
>         return;
> 
>     // Convert the utf8 string to utf32, call the utf32 routine,
>     // then convert it back to utf8.
>     lTemp = toUTF32(pText);
>     ReplaceChar( lTemp, pFrom, pTo);
>     pText = toUTF8(lTemp);
> 
>  }

It looks like this is a no-comment zone, so I changed the routine to be a function so I could write a reasonable 'out' contract. I prefer this anyhow as functions that alter the input parameters decrease the legibility of programs (and increase the chance of bugs).

But wouldn't it be useful if the 'out' contract could reference the values of the original parameters?


//----------------------------------------------------------
char[] ReplaceChar(char[] pText, dchar pFrom, dchar pTo)
//----------------------------------------------------------
in {
    // Only string references are permitted.
    assert( ! (pText is null) );

}
out (theResult){

    String lTempA;
    String lTempB;

    // We must return a string reference.
    assert( ! (pResult is null) );

    // Standardize strings to utf32 form.
    lTempA = toUTF32(pText);
    lTempB = toUTF32(pResult);

    // The lengths must be identical.
    assert(lTempA.length == lTempB.length);

    if ( pFrom != pTo)
    {
        // From and To are not the same so there might be changes.
        foreach (uint i, dchar c; lTempA)
        {
            if (c == pFrom)
            {
                // Each From char must now be a To char.
                assert(pTo == lTempB[i]);
            }
            else
            {
                // Each non-From char must be unchanged.
                assert(lTempA[i] == lTempB[i]);
            }
        }
    }
    else
        // From and To are the same so there should be no changes.
        assert(lTempA == lTempB);
}
body {

    if (pFrom == pTo)
        // From and To are the same, so do nothing.
        return pText;

    // Convert to utf32, call utf32 replace function, convert back to utf8
    return toUTF8( ReplaceChar( toUTF32(pText), pFrom, pTo) );

}


-- 
Derek
Melbourne, Australia
9/02/2005 10:22:08 AM
February 09, 2005
On Wed, 9 Feb 2005 11:57:48 +1100, Derek Parnell <derek@psych.ward> wrote:

> On Tue, 8 Feb 2005 16:47:27 +1100, Derek Parnell wrote:
> <snip lumps o' reply>
>
> It looks like this is a no-comment zone, so I changed the routine to be a
> function so I could write a reasonable 'out' contract. I prefer this anyhow
> as functions that alter the input parameters decrease the legibility of
> programs (and increase the chance of bugs).
>
> But wouldn't it be useful if the 'out' contract could reference the values
> of the original parameters?
>

For contracts of class methods a private/debug only member variable could store the contract information, but free functions with contracts wouldn't have any safe equivalent. Also I'm not sure if there are issues with multithreading here - simultaneous calls to the same object method might overwrite the stored contract data.

Perhaps something like Eiffel, where 'old' gives the original value i.e.

.out
.{
.	assert( bufferLength == old.bufferLength + 1 );
.}

This probably isn;t feasible to do automatically in D, since it would require the compiler to identify and copy all 'old' references used by the out contract and copy them someplace safe, perhaps as an automagically generated part of an in contract. This brings up issues of deep and shallow copying etc etc as well.

It might be possible to have some way of letting the in contract specify things to be stored - I can't thing of a clean way to do that though.

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
February 09, 2005
On Wed, 09 Feb 2005 01:10:20 -0000, Alex Stevenson <ans104@cs.york.ac.uk> wrote:
> On Wed, 9 Feb 2005 11:57:48 +1100, Derek Parnell <derek@psych.ward> wrote:
>
>> On Tue, 8 Feb 2005 16:47:27 +1100, Derek Parnell wrote:
>> <snip lumps o' reply>
>>
>> It looks like this is a no-comment zone, so I changed the routine to be a
>> function so I could write a reasonable 'out' contract. I prefer this anyhow
>> as functions that alter the input parameters decrease the legibility of
>> programs (and increase the chance of bugs).
>>
>> But wouldn't it be useful if the 'out' contract could reference the values
>> of the original parameters?
>>
>
> For contracts of class methods a private/debug only member variable could store the contract information, but free functions with contracts wouldn't have any safe equivalent. Also I'm not sure if there are issues with multithreading here - simultaneous calls to the same object method might overwrite the stored contract data.
>
> Perhaps something like Eiffel, where 'old' gives the original value i.e.
>
> .out
> .{
> .	assert( bufferLength == old.bufferLength + 1 );
> .}
>
> This probably isn;t feasible to do automatically in D, since it would require the compiler to identify and copy all 'old' references used by the out contract and copy them someplace safe, perhaps as an automagically generated part of an in contract. This brings up issues of deep and shallow copying etc etc as well.
>
> It might be possible to have some way of letting the in contract specify things to be stored - I can't thing of a clean way to do that though.

Why not simply by defining them in the 'in' contract, i.e.

void foo(inout char[] a)
in {
  char[] original = a.dup;
}
out {
  assert(original != a);
}
body {
  ..etc..
}

Another way to look at it is that 'in' and 'out' are in the same scope, with a break in between to process the function body. I suspect this is incompatible with how they're currently implemented, which I suspect is as calls to functions.

Regan
February 09, 2005
On Wed, 09 Feb 2005 14:28:59 +1300, Regan Heath <regan@netwin.co.nz> wrote:

> On Wed, 09 Feb 2005 01:10:20 -0000, Alex Stevenson <ans104@cs.york.ac.uk> wrote:
>> On Wed, 9 Feb 2005 11:57:48 +1100, Derek Parnell <derek@psych.ward> wrote:
>>
>>> On Tue, 8 Feb 2005 16:47:27 +1100, Derek Parnell wrote:
>>> <snip lumps o' reply>
>>>
>>> It looks like this is a no-comment zone, so I changed the routine to be a
>>> function so I could write a reasonable 'out' contract. I prefer this anyhow
>>> as functions that alter the input parameters decrease the legibility of
>>> programs (and increase the chance of bugs).
>>>
>>> But wouldn't it be useful if the 'out' contract could reference the values
>>> of the original parameters?
>>>
>>
>> For contracts of class methods a private/debug only member variable could store the contract information, but free functions with contracts wouldn't have any safe equivalent. Also I'm not sure if there are issues with multithreading here - simultaneous calls to the same object method might overwrite the stored contract data.
>>
>> Perhaps something like Eiffel, where 'old' gives the original value i.e.
>>
>> .out
>> .{
>> .	assert( bufferLength == old.bufferLength + 1 );
>> .}
>>
>> This probably isn;t feasible to do automatically in D, since it would require the compiler to identify and copy all 'old' references used by the out contract and copy them someplace safe, perhaps as an automagically generated part of an in contract. This brings up issues of deep and shallow copying etc etc as well.
>>
>> It might be possible to have some way of letting the in contract specify things to be stored - I can't thing of a clean way to do that though.
>
> Why not simply by defining them in the 'in' contract, i.e.
>
> void foo(inout char[] a)
> in {
>    char[] original = a.dup;
> }
> out {
>    assert(original != a);
> }
> body {
>    ..etc..
> }
>
> Another way to look at it is that 'in' and 'out' are in the same scope, with a break in between to process the function body. I suspect this is incompatible with how they're currently implemented, which I suspect is as calls to functions.
>
> Regan

This sounds like a rather more practical approach :-)

As I understood it contracts are functions called as the follows:

call in contract;
return from in contract;
call function;
return from function;
call out contract;
return from out contract;

So the stack frame of the in contract would have disappeared into the wild blue yonder by the time the out contract was called.

I suppose if the in contract called the function and the out contract it could be done, with some stack hackery to let the out contract access the in contract bits and to get the function return right:

call in contract function;
execute in contract statements;
call function;
return from function, storing return value;
call out contract;
return from out contract;
return from in contract (returning function return value);

Of course this is just vague speculation since I don't actually know anything about the implementation, just a little (very) basic knowledge of compilers and some guesswork.

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/m2/
February 09, 2005
On Wed, 09 Feb 2005 01:31:01 -0000, Alex Stevenson <ans104@cs.york.ac.uk> wrote:
> On Wed, 09 Feb 2005 14:28:59 +1300, Regan Heath <regan@netwin.co.nz> wrote:
>
>> On Wed, 09 Feb 2005 01:10:20 -0000, Alex Stevenson <ans104@cs.york.ac.uk> wrote:
>>> On Wed, 9 Feb 2005 11:57:48 +1100, Derek Parnell <derek@psych.ward> wrote:
>>>
>>>> On Tue, 8 Feb 2005 16:47:27 +1100, Derek Parnell wrote:
>>>> <snip lumps o' reply>
>>>>
>>>> It looks like this is a no-comment zone, so I changed the routine to be a
>>>> function so I could write a reasonable 'out' contract. I prefer this anyhow
>>>> as functions that alter the input parameters decrease the legibility of
>>>> programs (and increase the chance of bugs).
>>>>
>>>> But wouldn't it be useful if the 'out' contract could reference the values
>>>> of the original parameters?
>>>>
>>>
>>> For contracts of class methods a private/debug only member variable could store the contract information, but free functions with contracts wouldn't have any safe equivalent. Also I'm not sure if there are issues with multithreading here - simultaneous calls to the same object method might overwrite the stored contract data.
>>>
>>> Perhaps something like Eiffel, where 'old' gives the original value i.e.
>>>
>>> .out
>>> .{
>>> .	assert( bufferLength == old.bufferLength + 1 );
>>> .}
>>>
>>> This probably isn;t feasible to do automatically in D, since it would require the compiler to identify and copy all 'old' references used by the out contract and copy them someplace safe, perhaps as an automagically generated part of an in contract. This brings up issues of deep and shallow copying etc etc as well.
>>>
>>> It might be possible to have some way of letting the in contract specify things to be stored - I can't thing of a clean way to do that though.
>>
>> Why not simply by defining them in the 'in' contract, i.e.
>>
>> void foo(inout char[] a)
>> in {
>>    char[] original = a.dup;
>> }
>> out {
>>    assert(original != a);
>> }
>> body {
>>    ..etc..
>> }
>>
>> Another way to look at it is that 'in' and 'out' are in the same scope, with a break in between to process the function body. I suspect this is incompatible with how they're currently implemented, which I suspect is as calls to functions.
>>
>> Regan
>
> This sounds like a rather more practical approach :-)
>
> As I understood it contracts are functions called as the follows:
>
> call in contract;
> return from in contract;
> call function;
> return from function;
> call out contract;
> return from out contract;
>
> So the stack frame of the in contract would have disappeared into the wild blue yonder by the time the out contract was called.

That's exactly what I imagined was going on :)

> I suppose if the in contract called the function and the out contract it could be done, with some stack hackery to let the out contract access the in contract bits and to get the function return right:
>
> call in contract function;
> execute in contract statements;
> call function;
> return from function, storing return value;
> call out contract;
> return from out contract;
> return from in contract (returning function return value);

I wonder if it could be done in the same was nested functions work, i.e.

incontract() {
  function() {
    ..contents of function..
  }
  outcontract() {
    ..contents of out contract..
  }
  ..contents of in contract..
  function();
  outcontract();
}

> Of course this is just vague speculation since I don't actually know anything about the implementation, just a little (very) basic knowledge of compilers and some guesswork.

That's all I'm working with :)

Regan