assume, assert, enforce, @safe

Daniel Gibson via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 31 14:31:26 PDT 2014


Am 31.07.2014 23:21, schrieb Sean Kelly:
> On Thursday, 31 July 2014 at 06:57:15 UTC, Walter Bright wrote:
>> On 7/30/2014 3:39 PM, Joseph Rushton Wakeling via Digitalmars-d wrote:
>>> My take is that, for this reason, these should be asserts and not
>>> enforce() statements.  What are your thoughts on the matter?
>>
>> An excellent question.
>>
>> First, note that enforce() returns a recoverable exception, and
>> assert() a non-recoverable error.
>>
>> Logically, this means that enforce() is for scrubbing input, and
>> assert() is for detecting program bugs. I'm pretty brutal in asserting
>> (!) that program bugs are fatal, non-recoverable errors. I've been
>> fighting this battle for decades, i.e. repeated proposals by
>> well-meaning programmers who believe their programs can safely recover
>> from an unknown, invalid state.
>
> It may be worth drawing a distinction between serial programs
> (ie. a typical desktop app) and parallel programs (ie. server
> code).  For example, in a server program, a logic error caused by
> one particular type of request often doesn't invalidate the state
> of the entire process.  More often, it just prevents further
> processing of that one request.  Much like how an error in one
> thread of a multithreaded program with no shared data does not
> corrupt the state of the entire system.
>
> In short, what one terms a "process" is really somewhat fluid.
> What is the distinction between a multi-threaded application
> without sharing and multiple instances of the same process all
> running individually?  In Erlang, a "process" is really just a
> thread being run by the VM, and each process is effectively a
> class instance.  All errors are fatal, but they're only fatal for
> that one logical process.  It doesn't take down the whole VM.
>
> Now in a language like D that allows direct memory access, one
> could argue that any logic error may theoretically corrupt the
> entire program, and I presume this is where you stand.  But more
> often in my experience, some artifact of the input data or
> environmental factors end up pushing execution through a path
> that wasn't adequately tested, and results in a fully recoverable
> error (initiated by bad program logic) so long as the error is
> detected in a timely manner.  These are issues I want caught and
> signaled in the most visible manner possible so the logic error
> can be fixed, but I don't always want to immediately halt the
> entire process and terminate potentially thousands of entirely
> correct in-progress transactions.
>
> Perhaps these are all issues that should be marked by enforce
> throwing a ProgramLogicException rather than assert with an an
> AssertError, but at that point it's almost bikeshedding.
> Thoughts?

I agree.
Also: During development I'd be fine with this terminating the program 
(ideally dumping the core) so the error is immediately noticed, but in 
release mod I'm not, so a construct that halts in debug mode and throws 
an exception or maybe just returns false (or one construct for each of 
the cases) in release mode would be helpful.

Cheers,
Daniel


More information about the Digitalmars-d mailing list