Asked on Reddit: Which of Rust, D, Go, Nim, and Crystal is the strongest and why?
Idan Arye via Digitalmars-d
digitalmars-d at puremagic.com
Wed Jun 10 15:33:25 PDT 2015
On Wednesday, 10 June 2015 at 19:56:00 UTC, Dave wrote:
>> I usually agree that the more restrictive option should be the
>> default, but exceptions is... well... the exception. The whole
>> point of the exceptions system is to limit the number of
>> points where you need to worry about something going wrong to
>> the place where it happens and the places where you want to do
>> something special with it.
>
> The point of exceptions is to communicate errors and where they
> originate. As long as this is respected, then I am not following
> your complaint.
>
>> you have to care about the exception at every single point in
>> between.
>
> That's the point. If you don't annotate the function (with a
> throw keyword for instance), then you are forced to catch and
> handle the exception. If you annotate it (saying this function
> will throw), no catch is needed, but at least you are
> communicating to the next layer that
> this code *does* have errors that should be accounted for.
>
>> nothrow by default means you can't do that
>
> Actually no guarantees by default means you can't do what I
> explained above.
The promise of exceptions isn't to not have to specifically
handle errors in every layer - it's to not care about exceptions
in every layer. I don't want to pass the annotation in each and
every intermediate layer - I want only the throwing layer and the
catching layer to acknowledge the exception's existence. The
middle layers should be written like there is no exception, and
when there is one, they will simply fail and let RAII to
automatically do the cleanup.
I've programmed enough Java to know how harmful
nothrow-by-default is. It doesn't really guarantee the functions
not annotated as throwing won't crash - only that if they do
crash there is nothing you can do about it. This mechanism is so
easy to bypass in harmful ways(catch and rethrow something that
doesn't need annotation(like Error), or terminate the process
with a special exit function), and annotating the layers all the
way up is so cumbersome(and sometimes impossible - when you
override functions, or pass delegates) that this mechanism tends
to encourage to bypass it, which harms the debugging.
Of course, nothrow as the optional annotation is a different
syntax for the same semantics, so it suffers from the same
drawbacks but it has the benefit of seldom being use therefore
seldom getting in your way. Which leads me to the final
conclusion - there shouldn't be nothrow, not by default and not
as special annotation!
(I'm not talking about D here - this isn't worth the code
breakage - but generally on programming languages)
If it's an error that the caller needs to know about - make it
part of the return type. If it doesn't need to know about it -
throw an exception and let someone up the line handle it. Rust
got it right - though they made it a bit cumbersome to catch
`panic`s. Why would I need to catch panic? To display them nicely
to the user(don't just dump to stderr - pop up a window that
apologizes and prompts the user to email the exception data to
the developers) or to rollback the changes(yes, there was an
irrecoverable error in the program. That doesn't give me the
right to corrupt user data when I can avoid it). But the point is
- you can either handle it or ignore it. The "sign here and we'll
pass it on" bureaucracy is not benefiting anyone.
More information about the Digitalmars-d
mailing list