June 16, 2010
I think about it roughly this way (in reverse priority):

Contracts/assertions concern problems in the program(ming) domain.

Exceptions concern problems in the system domain.

Problems in the actual problem domain should be modeled in the design and have their own abstractions.

These interact a little bit, so I have an excuse to bend my rules whenever I want :)  For instance, if the system is part of your problem domain (e.g. embedded code), then exceptions are probably not the right approach.  That's why I indicate a false idea of priority.

Jason
June 16, 2010
On 2010-06-16 14:10:17 -0400, Jonathan M Davis <jmdavisProg@gmail.com> said:

> I would point out that pretty much nothing in std.contracts actually relates
> to contracts. Rather, it relates to error handling. So, it would probably be
> a good idea to simply rename the module - perhaps to std.error.

I concur: the module is misnamed. The only things not related to error handling are assumeUnique and assumeSorted, and I fail to see the link with design by contract for either one.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

June 16, 2010
On 2010-06-16 14:44:29 -0400, Michel Fortin <michel.fortin@michelf.com> said:

> On 2010-06-16 14:10:17 -0400, Jonathan M Davis <jmdavisProg@gmail.com> said:
> 
>> I would point out that pretty much nothing in std.contracts actually relates
>> to contracts. Rather, it relates to error handling. So, it would probably be
>> a good idea to simply rename the module - perhaps to std.error.
> 
> I concur: the module is misnamed. The only things not related to error handling are assumeUnique and assumeSorted, and I fail to see the link with design by contract for either one.

Oh, forgot about "pointsTo" too. What's the link with contracts, or error handling?

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

June 16, 2010
Michel Fortin wrote:
> On 2010-06-16 14:44:29 -0400, Michel Fortin <michel.fortin@michelf.com> said:
> 
>> On 2010-06-16 14:10:17 -0400, Jonathan M Davis <jmdavisProg@gmail.com> said:
>>
>>> I would point out that pretty much nothing in std.contracts actually relates
>>> to contracts. Rather, it relates to error handling. So, it would probably be
>>> a good idea to simply rename the module - perhaps to std.error.
>>
>> I concur: the module is misnamed. The only things not related to error handling are assumeUnique and assumeSorted, and I fail to see the link with design by contract for either one.
> 
> Oh, forgot about "pointsTo" too. What's the link with contracts, or error handling?

Certain functions (notably swap) must make sure that there's no mutual aliasing between two objects.

Andrei
June 16, 2010
Jonathan M Davis wrote:

> Assertions assert that something is _always_ true and that if it isn't, the
> program is wrong, while exceptions are for exceptional circumstances

Makes sense.

> You use [enforce] when you want an exception thrown rather than when you want to
> kill your program due to an error.

To further confuse the issue, assert throws too:

import std.stdio;
import std.algorithm;

void main()
{
    try {
        assert(false);
    } catch (Throwable) {
        writeln("an assertion failed");
    }
}

The difference is just the exception that is thrown. Throwable seems to be most general.

From what I've read so far, I take enforce as a replacement to what it exactly is:

if (condition) {
    throw /* ... */;
}

Since I never use assert for that purpose, I take enforce as a shortcut for the above.

Ali
June 16, 2010
Ali Çehreli <acehreli@yahoo.com> wrote:

> To further confuse the issue, assert throws too:
>
> import std.stdio;
> import std.algorithm;
>
> void main()
> {
>      try {
>          assert(false);
>      } catch (Throwable) {
>          writeln("an assertion failed");
>      }
> }
>
> The difference is just the exception that is thrown. Throwable seems to be most general.

Seeing as how Error is supposed to be unrecoverable, and Exception might
be recoverable, and both inherit from Throwable, one should only very very
rarely catch Exception, and by extension, Throwable. One might in fact
argue that Error and Exception should have no common ancestor but Object.


>  From what I've read so far, I take enforce as a replacement to what it exactly is:
>
> if (condition) {
>      throw /* ... */;
> }

That is indeed basically what it is.


-- 
Simen
June 16, 2010
Don wrote:
> import std.dunno;
> Works for me.

cut & print.
June 16, 2010
Don wrote:

> import std.dunno;
> Works for me.

Or std.poisson... :p

Ali
June 16, 2010
Le 16/06/10 22:36, Ali Çehreli a écrit :
> Don wrote:
>
>> import std.dunno;
>> Works for me.
>
> Or std.poisson... :p

Better name it std.fishy, because std.poisson could be mistaken for a statistical distribution module!

June 16, 2010
Ali Çehreli wrote:

> Jonathan M Davis wrote:
> 
>  > Assertions assert that something is _always_ true and that if it
> isn't, the
>  > program is wrong, while exceptions are for exceptional circumstances
> 
> Makes sense.
> 
>  > You use [enforce] when you want an exception thrown rather than when
> you want to
>  > kill your program due to an error.
> 
> To further confuse the issue, assert throws too:
> 
> import std.stdio;
> import std.algorithm;
> 
> void main()
> {
>      try {
>          assert(false);
>      } catch (Throwable) {
>          writeln("an assertion failed");
>      }
> }
> 
> The difference is just the exception that is thrown. Throwable seems to be most general.
> 
>  From what I've read so far, I take enforce as a replacement to what it
> exactly is:
> 
> if (condition) {
>      throw /* ... */;
> }
> 
> Since I never use assert for that purpose, I take enforce as a shortcut for the above.
> 
> Ali

Well, in a sense, the fact that assertions throw is an implementation detail since that's not the case in all languages. The concepts of assertions and exceptions are distinctly different.

However, while assertions do throw in D, they throw AssertErrors which are Errors and not exceptions, albeit both are Throwable. So, they're still different. You _can_ catch Errors, but you probably shouldn't. I believe that they're intended for pretty much unrecoverable errors. The fact that they're thrown likely makes it easier to exit the program semi-gracefully - or at least makes it easier for the generated program to properly indicate an error rather than simply dying - but they're still distinctly separate from exceptions and shouldn't generally be caught. I suppose that it's kind of like the difference between checked and unchecked exceptions in Java. You generally only worry about the checked ones.

You are right though in that the fact that Errors are Throwable does muddle things somewhat.

- Jonathan M Davis