DMD 1.027 and 2.011 releases

eao197 eao197 at intervale.ru
Fri Feb 29 08:35:15 PST 2008


On Fri, 29 Feb 2008 18:42:05 +0300, Russell Lewis  
<webmaster at villagersonline.com> wrote:

> I believe that assert()s are ways to programmatically document things  
> that the program must enforce.  An in() contract on a function is a  
> statement that says "any code which calls me, but violates this  
> contract, is buggy."  Exceptions are the way to programmatically handle  
> unusual conditions in well-ordered ways.

Contract may be considered another way: a function with precodition says  
"I guarantee correct behaviour only when you keeps my precondition".

> So, in your example below, since pack7bitMessage asserts that the  
> message must be no more than 160 characters, then any code which called  
> it must enforce that contract.  Any code which didn't enforce the  
> contract has a bug.

Yes it is. But a bug in code is not always should lead to abortion of  
entire application.

> IMHO, if what you want is to have a function which will take input of  
> any length, but refuse to encode things which are longer than 160  
> characters, then it should be coded as follows:
>
>    byte[] pack7bitMessage( byte[] message )
>    {
>      if(message.length > 160)
>        throw InputTooLongException;
>
>      ... encode ...
>    }

Yes that function could be rewritten in such way. But there could be  
condition when DbC is preferable than defensive programming:
- contracts are part of function prototype, so conract help understanding  
function behaviour. For example, try look at EiffelBase reference manual  
(http://docs.eiffel.com) -- sometimes bodies of 'require' and 'ensure'  
give more information that description of a methods;
- contracts could be turned off in release mode when you sure that there  
isn't critical bugs. So, function with contracts:

byte[] pack7bitMessage( byte[] message )
   in {
    assert( message );
    assert( message.length <= 160 );
    assert( !is8bitCharFound( message ) );
   }
   body { ... }

will be much faster in speed-critical applications then the function which  
is written in defensive-programming style.

> Finally, let me ask you a question:
>
> If an failed assert() doesn't represent an unrecoverable logic error,  
> then what does???

As in the case with ordinal exception -- it depends. When you try to add a  
member into associative array you and get NoMemory exception you don't  
know is that exception would be unrecoverable or recoverable. If you write  
yet another WordCounter example such exception will be fatal for your  
application. But if you write, for example, some image-transformation  
program for http://picasa.google.com/ you could simple throw away current  
problematic image, clear all resouces which was allocated for that image,  
and go to next image in queue.

> eao197 wrote:
>> On Thu, 28 Feb 2008 19:34:45 +0300, Russell Lewis  
>> <webmaster at villagersonline.com> wrote:
>>
>>>>  It is not necessary to catch AssertError. Sometimes it is necessary  
>>>> to catch any error. For example, in a HTTP-server you could start  
>>>> processing of a new request and catch different kinds of errors to  
>>>> make appropriate response:
>>>
>>> I agree that a web server needs to post an appropriate response.  But  
>>> if an assert() has failed, you don't know if the failure is in your  
>>> main program, in a library, or maybe even in your network code.  In  
>>> that case, you can't really rely on your program to keep working  
>>> correctly, and the only sane solution would be to restart it.
>>  Violation of contract is not a sign of unrecoverable failure of the  
>> program, expecially for preconditions. Quite the contrary contracts  
>> help detect unappropriate conditions at earlier stages.
>>  For example, SMS body in 140 bytes long. 7-bit message could be up to  
>> 160 symbols, packed into 140 bytes SMS body. You could have 7-bit  
>> message packing functions with precondition:
>>  byte[] pack7bitMessage( byte[] message )
>>   in { assert( message.length <= 160 ); }
>>   body { ... }
>>  When pack7bitMessage receives message which is longer than 160 symbols  
>> there isn't any sign of unrecoverable error. For example, the too long  
>> body of message may be received from SMPP PDU submit_sm from a ESME who  
>> simply had made an error in their PDU. It may be a sign of presence of  
>> error in your code for submit_sm parsing (length of SMS body not  
>> checked) but there nothing fatal for whole application.
>>  And that is a situation where application abort and restart don't  
>> solve a problem -- ESME simply repeat the problem submit_sm after  
>> server restart and server go down again and so on.
>>
>>> My argument, then, is that you need a metaprogram or "watchdog" (such  
>>> as the init process in *NIX, or maybe just a "web server launcher")  
>>> which manages the server programs and restarts them when they crash.
>>  A rather complex application is build from a several layers. A failure  
>> on some layer should abort all current processing on that layer, but  
>> parent layer could restart the problem layer. So that model with  
>> metaprogram/watchdogs or supervisor processes (from Erlang) could be  
>> implemented inside a single application with use of safe languages like  
>> D, Java or C#.
>>  --Regards,
>> Yauheni Akhotnikau



-- 
Regards,
Yauheni Akhotnikau


More information about the Digitalmars-d-announce mailing list