October 16, 2014
On Thursday, 16 October 2014 at 07:44:37 UTC, Walter Bright wrote:
> On 10/15/2014 6:54 PM, Sean Kelly wrote:
>> I hate to say it, but I'm inclined to treat nothrow the same as in C++, which is
>> to basically pretend it's not a part of the language. The efficiency is nice,
>> but not if it means that throwing an Error will cause the program to be
>> invalid.  Please tell me there's no plan to change the unwinding behavior when
>> Error is thrown in standard (ie not nothrow) code.
>
> Don't throw Errors when you need to unwind. Throw Exceptions. I.e. use enforce() instead of assert().

I'm more concerned about Phobos. If it uses nothrow and asserts in preconditions then the decision has been made for me.
October 16, 2014
Walter Bright <newshound2@digitalmars.com> writes:

> On 10/15/2014 7:35 AM, Dan Olson wrote:
>> That is what I am looking for, just being able to continue from a failed assert in a unittest.
>
> Just use enforce() or something similar instead of assert(). Nothing
> says you have to use assert() in a unittest.

Makes sense.  However it is druntime and phobos unittests that already use assert.  I have convinced myself that catching Throwable is just fine in my case because at worst, unittests that follow an Error might be tainted, but only a perfect score of passing all tests really counts.
-- 
dano
October 16, 2014
"Ola Fosheim "Grøstad\"" <ola.fosheim.grostad+dlang@gmail.com> writes:

> On Wednesday, 15 October 2014 at 14:25:43 UTC, Dicebot wrote:
>> How can one continue without recovering? This will result in any kind of environment not being cleaned and false failures of other tests that share it.
>
> fork()?

Forking each unittest sounds like a good solution.
-- 
dano
October 16, 2014
On 10/16/2014 6:46 AM, Sean Kelly wrote:
> On Thursday, 16 October 2014 at 07:44:37 UTC, Walter Bright wrote:
>> Don't throw Errors when you need to unwind. Throw Exceptions. I.e. use
>> enforce() instead of assert().
>
> I'm more concerned about Phobos. If it uses nothrow and asserts in preconditions
> then the decision has been made for me.

Which function(s) in particular?
October 16, 2014
On 10/16/2014 8:36 AM, Dan Olson wrote:
> Walter Bright <newshound2@digitalmars.com> writes:
>
>> On 10/15/2014 7:35 AM, Dan Olson wrote:
>>> That is what I am looking for, just being able to continue from a failed
>>> assert in a unittest.
>>
>> Just use enforce() or something similar instead of assert(). Nothing says
>> you have to use assert() in a unittest.
>
> Makes sense.  However it is druntime and phobos unittests that already use
> assert.  I have convinced myself that catching Throwable is just fine in my
> case because at worst, unittests that follow an Error might be tainted, but
> only a perfect score of passing all tests really counts.

I don't understand why unittests in druntime/phobos are an issue for users. We don't release a DMD unless they all pass - it should be moot for users.

October 16, 2014
Hi all!
I've read the topic and I am really surprised so many engeneers
arguing for so long and not having systematic approach to the
problem.

As I see it, Walter states that there are eenvironmental errors
and program bugs, which are non-recoverable. So use exceptions
(enforce) for first ones and asserts for the latter.

Other folks argue, that you might want to recover from a program
bug or not recover from invalid input. Also,  exception might be
itself a program bug. This is a valid point too.

So if both are true, that clearly means that the right solution
would be to introduce four categories: a cross product of the
obove:

- bugs, that are recoverable
- bugs, that are unrecoverable
- input errors, that are recoverable
- input errors, that are not

Given that, makes sence to use exceptions for recoverable errors,
doesn't matter whether they are bugs or environmental errors, and
use asserts, if you can't recover.

So, the programmer decides, if his program can recover and puts
an assert or an enforce call in his code.

The problem is, as always, with libraries. The library writer
cannot possibly decide, is some unexpected condition recoverable
or not, so he just can't put both assert and enforce into his
library function and the caller must check the arguments before
calling the function. Yes, this is annoying, but it it the only
correct way.

But what if he didn't? This brings us to error codes. Yes, they
are the best for library error handling, imo, of course, in a
form of Maby and Error monads. They are as clear as asking the
ccaller to decide, what to do with the error. But I realize, that
you, guys, are all against error codes of any kind, so...

I would say, that since the caller didn't check the arguments
himself the bug becomes unrecoverable by default and there should
be an assert, which gives stack trace, so the programmer would
insert appropriate enforces before the function call.

Finally, this brings me to the conclusion: you don't need a stack
trace in the exception, it is never a bug.






October 16, 2014
On Thursday, 16 October 2014 at 18:49:13 UTC, Walter Bright wrote:
> On 10/16/2014 6:46 AM, Sean Kelly wrote:
>> On Thursday, 16 October 2014 at 07:44:37 UTC, Walter Bright wrote:
>>> Don't throw Errors when you need to unwind. Throw Exceptions. I.e. use enforce() instead of assert().
>>
>> I'm more concerned about Phobos. If it uses nothrow and asserts in preconditions then the decision has been made for me.
>
> Which function(s) in particular?

Nothing specifically... which is kind of the problem.  If I call
an impure nothrow function, it's possible the function accesses
shared state that will not be properly cleaned up in the event of
a thrown Error--say it contains a synchronized block, for
example.  So even if I can be sure that the problem that resulted
in an Error being thrown did not corrupt program state, I can't
be sure that the failure to unwind did not as well.

That said, I'm inclined to say that this is only a problem
because of how many things are classified as Errors at this
point.  If contracts used some checking mechanism other than
assert, perhaps this would be enough.  Again I'll refer to my "on
errors" post that gets into this a bit.  Using two broad
categories: exceptions and errors, is unduly limiting.
October 16, 2014
On Thursday, 16 October 2014 at 18:53:22 UTC, monnoroch wrote:
>
> So if both are true, that clearly means that the right solution
> would be to introduce four categories: a cross product of the
> obove:
>
> - bugs, that are recoverable
> - bugs, that are unrecoverable
> - input errors, that are recoverable
> - input errors, that are not

Yes, I've already started a thread for this:

http://forum.dlang.org/thread/zwnycclpgvfsfaactcyl@forum.dlang.org

but almost no one replied.
October 16, 2014
On Thursday, 16 October 2014 at 06:11:46 UTC, Jacob Carlborg wrote:
> On 2014-10-15 16:25, Dicebot wrote:
>
>> How can one continue without recovering? This will result in any kind of
>> environment not being cleaned and false failures of other tests that
>> share it.
>
> I will probably use something else than "assert" in my unit tests. Something like assertEq, assertNotEq and so on. It's more flexible, can give better error message and I can have it throw an exception instead of an error. But there's still the problem with asserts in contracts and other parts of the code.

This is what we are using right now:

public void test ( char[] op, T1, T2 ) ( T1 a, T2 b, char[] file = __FILE__, size_t line = __LINE__ )
{
    enforce!(op, TestException)(a, b, file, line);
}

but it won't work well with 3d-party libraries that use assertions.
October 16, 2014
On 10/16/2014 12:08 PM, Sean Kelly wrote:
> On Thursday, 16 October 2014 at 18:49:13 UTC, Walter Bright wrote:
>> On 10/16/2014 6:46 AM, Sean Kelly wrote:
>>> On Thursday, 16 October 2014 at 07:44:37 UTC, Walter Bright wrote:
>>>> Don't throw Errors when you need to unwind. Throw Exceptions. I.e. use
>>>> enforce() instead of assert().
>>>
>>> I'm more concerned about Phobos. If it uses nothrow and asserts in
>>> preconditions then the decision has been made for me.
>>
>> Which function(s) in particular?
>
> Nothing specifically... which is kind of the problem.  If I call
> an impure nothrow function, it's possible the function accesses
> shared state that will not be properly cleaned up in the event of
> a thrown Error--say it contains a synchronized block, for
> example.  So even if I can be sure that the problem that resulted
> in an Error being thrown did not corrupt program state, I can't
> be sure that the failure to unwind did not as well.

Contract errors in Phobos/Druntime should be limited to having passed it invalid arguments, which should be documented, or simply that the function has a bug in it, or that it ran out of memory (which is generally not recoverable anyway).

I.e. I'm not seeing where this is a practical problem.


> That said, I'm inclined to say that this is only a problem
> because of how many things are classified as Errors at this
> point.  If contracts used some checking mechanism other than
> assert, perhaps this would be enough.  Again I'll refer to my "on
> errors" post that gets into this a bit.  Using two broad
> categories: exceptions and errors, is unduly limiting.

My initial impression is that there's so much confusion about what should be an Error and what should be an Exception, that adding a third category will not improve things.