D - in/out contracts on function pointers
- Russ Lewis (29/29) May 28 2003 It just occurred to me that in & out contracts on function pointers
- Sean L. Palmer (30/59) May 28 2003 I like the idea, and agree with the point on copying.
- Antti Sykari (5/27) May 28 2003 I'd find it most natural to use an interface with pre- and
- Russ Lewis (25/90) Jun 02 2003 I prefer the typedef idea, from a design perspective. But I don't think...
It just occurred to me that in & out contracts on function pointers would be nice: int (*foo)(int a,int b) in { assert(a>0); assert(b>0); } out(retval) { assert(retval <= a+b); }; The idea, of course, is that when you use the function pointer to call the function, it runs the in an out tests in addition to any in and out contracts specified in the funciton implementation. This would allow you to specify some common requirements on how the functions are called and what they do. Right now, I don't know what to do with assignments. That is, if you have a function pointer with in & out contracts, and you attempt to assign that pointer to another with the same type but different contracts, should that be legal and what should it mean? My thought, at first pass, is that it should be legal and the only binding contracts should be the ones where the function is actually used. Comments, anyone? -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
May 28 2003
I like the idea, and agree with the point on copying. This would move in/out contracts to be part of the function signature, but being unable to copy without identical contracts seems too restrictive. So copying does nothing to contracts, seems like a good solution. For myself this particular form of contract would be better expressed by a limitation on the type of the input itself, such as: typedef 1..MAXINT posint; int (*foo)(posint a, posint b); You'd still need the out contract (but I leave it out here) The compiler would then need to ensure somehow (perhaps by range checking at call time, perhaps inferred) that the range requirement is met. It allows one to clearly and cleanly delineate range of a value *in one place* in the code, and have it automatically enforced. I prefer this to in/out contracts in this particular case, but in/out contracts have other uses which are valid. Just playing with syntax for ranges, I find these. Without the intermediate typedef: int (*foo)(1..MAXINT a, 1..MAXINT b); Even better syntax may be: int (*foo)(1..+ a, 1..+ b); or perhaps: int (*foo)(int a > 0, int > 0 b); Which leads back to: typedef int posint > 0; Or: typedef int > 0 posint; Thoughts? Sean "Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3ED53A84.513DDBDB deming-os.org...It just occurred to me that in & out contracts on function pointers would be nice: int (*foo)(int a,int b) in { assert(a>0); assert(b>0); } out(retval) { assert(retval <= a+b); }; The idea, of course, is that when you use the function pointer to call the function, it runs the in an out tests in addition to any in and out contracts specified in the funciton implementation. This would allow you to specify some common requirements on how the functions are called and what they do. Right now, I don't know what to do with assignments. That is, if you have a function pointer with in & out contracts, and you attempt to assign that pointer to another with the same type but different contracts, should that be legal and what should it mean? My thought, at first pass, is that it should be legal and the only binding contracts should be the ones where the function is actually used. Comments, anyone? -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
May 28 2003
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3ED53A84.513DDBDB deming-os.org...[..]It just occurred to me that in & out contracts on function pointers would be nice: int (*foo)(int a,int b) in { assert(a>0); assert(b>0); } out(retval) { assert(retval <= a+b); }; The idea, of course, is that when you use the function pointer to call the function, it runs the in an out tests in addition to any in and out contracts specified in the funciton implementation. This would allow you to specify some common requirements on how the functions are called and what they do.I'd find it most natural to use an interface with pre- and postconditions. Maybe it's just me but bare function pointers seem like a low-level feature from the ancient C days. -AnttiComments, anyone?
May 28 2003
I prefer the typedef idea, from a design perspective. But I don't think that the types should be named "posint" or anything like that, since that just describes the container. Instead, (IMHO) you should describe the purpose of the type: typedef 1..+ columnIndex; typedef 1..+ rowIndex; void foo(columnIndex col, rowIndex row); The beauty of range-limited types (either typedefs or inline declarations) is that the compiler is entitled to implement it using a type with a larger size and add (implicit) aserts throughout the code that ensure that the value stays within the range. Especially nice when you are modeling something with a relatively small range: typedef 0..7 smallSelector; Presumably, the compiler would implement this as a byte or ubyte. The compiler then adds implicit asserts before each read and after each write. A beautiful side effect of this is that the compiler can implicitly define that: smallSelector.init = 8; meaning that if we ever try to read an unitialized smallSelector variable, we will get a runtime assert "value read was out of valid range". Nice! "Sean L. Palmer" wrote:I like the idea, and agree with the point on copying. This would move in/out contracts to be part of the function signature, but being unable to copy without identical contracts seems too restrictive. So copying does nothing to contracts, seems like a good solution. For myself this particular form of contract would be better expressed by a limitation on the type of the input itself, such as: typedef 1..MAXINT posint; int (*foo)(posint a, posint b); You'd still need the out contract (but I leave it out here) The compiler would then need to ensure somehow (perhaps by range checking at call time, perhaps inferred) that the range requirement is met. It allows one to clearly and cleanly delineate range of a value *in one place* in the code, and have it automatically enforced. I prefer this to in/out contracts in this particular case, but in/out contracts have other uses which are valid. Just playing with syntax for ranges, I find these. Without the intermediate typedef: int (*foo)(1..MAXINT a, 1..MAXINT b); Even better syntax may be: int (*foo)(1..+ a, 1..+ b); or perhaps: int (*foo)(int a > 0, int > 0 b); Which leads back to: typedef int posint > 0; Or: typedef int > 0 posint; Thoughts? Sean "Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3ED53A84.513DDBDB deming-os.org...-- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]It just occurred to me that in & out contracts on function pointers would be nice: int (*foo)(int a,int b) in { assert(a>0); assert(b>0); } out(retval) { assert(retval <= a+b); }; The idea, of course, is that when you use the function pointer to call the function, it runs the in an out tests in addition to any in and out contracts specified in the funciton implementation. This would allow you to specify some common requirements on how the functions are called and what they do. Right now, I don't know what to do with assignments. That is, if you have a function pointer with in & out contracts, and you attempt to assign that pointer to another with the same type but different contracts, should that be legal and what should it mean? My thought, at first pass, is that it should be legal and the only binding contracts should be the ones where the function is actually used. Comments, anyone? -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Jun 02 2003