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

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

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/

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

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/

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.