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