request switch statement with common block

luminousone rd.hunt at gmail.com
Mon Aug 5 15:53:44 PDT 2013


On Monday, 5 August 2013 at 21:48:46 UTC, Andre Artus wrote:
> On Monday, 5 August 2013 at 19:58:21 UTC, ron wrote:
>> On Monday, 5 August 2013 at 08:46:54 UTC, Andre Artus wrote:
>>> On Monday, 5 August 2013 at 06:28:12 UTC, luminousone wrote:
>>>> perhaps a more generic solution should be looked at, extend 
>>>> contracts to work with all scope blocks.
>>>>
>>>> switch(somenumber)
>>>> in {
>>>>  ... before stuff ...
>>>> }
>>>> out {
>>>>  .... after stuff ...
>>>> }
>>>> body {
>>>>  case 1:
>>>>  in {
>>>>     ... etc ....
>>>>  }
>>>>  out {
>>>>     ... more etc ...
>>>>  }
>>>>  body {
>>>>     ...
>>>>  }
>>>>  case 2:
>>>>    // and so on
>>>> }
>>>>
>>>> or perhaps
>>>>
>>>> for( int i = 0 ; i < 10 ; i ++ )
>>>> in {
>>>>  assert( i == 0 );
>>>> }
>>>> out {
>>>>  assert( i == 9 );
>>>> }
>>>> body {
>>>> ... stuff ...
>>>> }
>>>>
>>>> if it is desired for a particular contract block to be 
>>>> called in release builds perhaps a attribute label to mark 
>>>> it as a runtime block or something similar.
>>>>
>>>> foreach( i, k ; somerange )
>>>> @runtime in {
>>>> ...
>>>> }
>>>> body {
>>>> }
>>>
>>> Please do not take offense, but I do not see this as a good 
>>> idea. Contracts have a very different function; not just in 
>>> D, but every language that uses them. The idea is to support 
>>> design-by-contract programming. Overloading the constructs 
>>> for the purposes proposed here would, in my opinion, cause 
>>> confusion and/or weaken the proper use of contract 
>>> programming.
>>>
>>>
>>> The code in the contract conditions should never do anything 
>>> more than what is necessary to specify the contract. It 
>>> should not do explicit IO (other than implied by assert()), 
>>> mutate state, or anything like that.
>>>
>>> At the bottom of this page you can find a reading list for 
>>> more info.
>>> http://www.digitalmars.com/d/dbc.html
>>>
>>> Or for a general overview:
>>> http://en.wikipedia.org/wiki/Design_by_contract
>>>
>>> Walter, does the D compiler or any of it's companion tools do 
>>> any static analysis on the contracts? Such as a void 
>>> safety/null reference check?
>>
>> None taken, =-p.
>>
>> I don't see how this is different from current contract usage, 
>> right now they apply to function scopes only. currently I 
>> believe you could get a similar effect via using an inner 
>> function.
>>
>> void a() {
>>   int i = 0;
>>   void b()
>>   in {
>>      assert( i == 0 );
>>   }
>>   out {
>>      assert( i == 10 );
>>   }
>>   body {
>>      for( ; i < 10 ; i ++ ) {
>>         ... do something ...
>>      }
>>   }
>>   b();
>> }
>
> I could be missing something, if so please clarify.
>
> The construct I have issue with is this one,
>
>>>> switch(somenumber)
>>>> in {
>>>>  ... before stuff ...
>>>> }
>>>> out {
>>>>  .... after stuff ...
>>>> }
>
> I would contend that code within in/out/invariant blocks should 
> be 'pure' (no state changes, no IO [other than assert 
> throwing]), it's only there to validate that a class and it's 
> methods do not violate certain conditions. They should be able 
> to be stripped out of the release build without altering the 
> execution of the application in any way.
>
> A classic example is the null dereference check, which some 
> compilers and most (all?) static analysers can detect.
>
>
>
> string whoIsAMonkey(Person p)
>   in
>   {
>     assert(p !is null, "Person can not be null");
>     assert(!isNullOrEmpty(p.Name), "Person name can not be null 
> or empty");
>   }
>   body
>   {
>     return p.Name ~ " is a monkey!";
>   }
>
>
> void main() {
>     Person p = null;
>     // Compiler / analyser should complain with
>     // "Person can not be null"
>     writeln(whoIsAMonkey(p));
>     //                   ^ here
> }
>
> void main() {
>     Person p = new Person();
>     // Compiler / analyser should complain with
>     // "Person name can not be null or empty"
>     writeln(whoIsAMonkey(p));
> }
>
> etc.
>
> Contracts are meant to define the public (*) interface of a 
> class.
>
> * By public I mean here anything not 'private', e.g. 
> 'protected' for inheritance.
>
> As Andrei points out in his book ("The D Programming Language") 
> contracts are not used to validate/scrub user (or any external) 
> input as they can be compiled out of the executable.
>
> Contracts are there to check sanity at compile time, or at the 
> very least during testing.
>
> The contract is (or should be) part of the documentation.

You are correct. I will have to check out his book.


More information about the Digitalmars-d mailing list