Asked on Reddit: Which of Rust, D, Go, Nim, and Crystal is the strongest and why?

Dave via Digitalmars-d digitalmars-d at puremagic.com
Thu Jun 11 11:17:01 PDT 2015


> Exceptions are for when something went wrong. Returned errors 
> are for when the function can't do what you asked it to do, but 
> that doesn't mean that something went wrong.

You seem to be implying this as a fact, when traditionally this
is not how things are done.

> For example, if you try to write to a file and fail that's an 
> exception, because something went wrong(e.g. - not enough disk

Agreed. Traditionally handled with an exception.

> But if you have a function that parses a string to a number and 
> you call it with a non-numeric string - that doesn't 
> necessarily mean that something went wrong. Maybe I don't 
> expect all strings to be convertible to numbers, and instead of 
> parsing each string twice(once for validation and once for the 
> actual conversion) I prefer to just convert and rely on the 
> conversion function to tell me if it's not a number?

Disagree. Traditionally also handled by throwing exceptions. C#
throws a Format exception if a parse fails. Java throws...a
ParseException. Just for some real-world examples.

> Note that doesn't mean that every time a function returns an 
> error it's not a problem - they can indicate problems, the 
> point is that it's not up to the callee to decide, it's up to 
> the caller. The conversion function doesn't know if I'm parsing 
> a YAML file and if field value is not a number that just means 
> it's a string, or if I'm parsing my own custom file format and 
> if something specific is not a number that means the file is 
> corrupted.

In a lot of C/C++ code a lot of functions just inform you that it
failed. Sometimes they push it onto an error queue you can check.
Sometimes they throw exceptions. Sometimes the return is an error
code itself. But you very rarely see them return an error code
AND throw an exception or push on an error queue. If they do they
are being redundant.

> In the latter case, I can convert the returned error to 
> exception(the returned error's type should have a method that 
> returns the underlying result if it's OK and if there was an 
> error raises an exception), but it's the caller's decision, not 
> the callee.

The implementer makes the decision on how errors are
communicated.The caller has no control over the mechanism minus
editing their code.

>>> Exceptions are not "hard fails".
>>
>> They can be if they go unaccounted for (depending on the
>> language/environment). Java has the infamous,
>> NullPointerException that plagues Java applications. C# has the
>> NullReferenceException.
>
> Even if they go unaccounted for, you still get a nice stack 
> trace that helps you debug them.

You still would. This is not being debated. However, programmers
seem to forget their code is often for customers. They care more
that their program just crashed. Very rarely are the exceptions
in forms where they can go "you know what would fix this?". No.
They write a defect up and send it to the company that made the
product.

> Maybe we have different definitions for "hard fail"...

A crash? Or abrupt termination of an entire execution stack?
Often unnecessarily?

> Even with no throw you can't guarantee a function won't cause 
> problems with unhandled errors - unless you use a very strict 
> definition of handling errors, that include discarding them or 
> crashing the program.

A very strict definition of handling errors is EXACTLY what I am
advocating for. You should be able to do what you want. But when
you do something naughty or potentially disruptive, you should
inform others.

> nothrow can only guarantee the function won't expose any 
> problems

That's a solid guarantee. I'd advocate that so much I might even
go as far as suggesting it as a default ;)

> If you insist on forcing developers to handle exceptions close 
> to the source, or to explicitly pass them on, I guess it can be 
> useful let them know what it is that they are require to 
> handle/pass on.

Exactly.

> Still, I don't think it's a good idea to needlessly burden 
> people just so > you could provide them with the tool to better 
> handle that burden.

I am not sure any *real* burden is here. People should be doing
this in the form of documentation anyhow. However, if it's part
of the definition, the work on documenting a function or type
becomes easier. Because functionally they have an idea of what is
needed by the language's definition and the header of the
function or type.

> It has panics, which are different from exceptions in that you 
> can't catch them(unless it's from another thread), but close in 
> their usage to what I have in mind when referring to exceptions 
> - they don't allow you to go on with what you where trying to 
> do, but allow you to debug the problem and/or back down from it 
> gracefully.

I know very little about Rust. I only recently encountered a
discussion about RAII where one of the developers said Rust has
RAII but no exceptions. That is the only reason why I commented
about anything regarding Rust with any certainty.

> It's not a matter of preferences, just like choosing between 
> int and float is not a matter of preferences. Each type of 
> error has it's own purpose, and a library can use them both.

It seems to be a matter of preference to others. Most library
writers literally choose one error handling scheme. It's not
common that you see too much of a mix.

> Returned errors provide a faster error path, and when you have 
> to decide if an error should be returned or thrown, the ones 
> that should be thrown are usually the ones where you don't care 
> as much about speed.

Not arguing the merits of returning error codes. The benefit of
returning errors it that it doesn't have the potential to disrupt
a process directly. Now ignoring the error is bad practice, as it
could indirectly cause problems with something down the line
(which is why I said checking errors in all cases is good
practice). Unchecked exceptions have the potential to directly
disrupt a process. 99.999% of the time unexpectedly.

>>> Writing code that acknowledges that this code can fail due to 
>>> an exception somewhere else does not count as ignoring it.
>>
>> You could not handle it all the way up the chain (at the cost 
>> of
>> adding something to a definition, not much trade-off there).
>
> Assuming you have control over the definition, which is not 
> always the case. In Java, for example, when you implement an 
> interface you have no control over the signature of it's 
> methods. The library that have provided that interface doesn't 
> know what the implementers are going to do, so it has to either 
> mark the methods as all-throwing(kind of defeats the purpose of 
> the `throws` annotation),

It does not defeat the purpose of 'throws' completely. Because
now people know you need to 'catch' at some point due to
something in this method. Most languages allow for a wildcard
catch statement to match wildcard throws.

> Returned errors are a faster mechanism that forces to deal with 
> the error at the source, or explicitly transfer it to the upper 
> level at the cost of changing the function's signature.

Yes what is your point? Some people go this direction. Others say
it doesn't provide enough information at times. Which is why many
turn to exceptions.

> Exceptions are a slower mechanism that allows to deal with the 
> errors far from the source without requiring special function 
> signatures in the middle levels(when they do require it's a 
> syntactic salt, not a requirement of the mechanism).

Again what's your point. I agree exceptions are slow. I disagree
on your usage.

> nothrow by default is combining the slowness of exceptions with 
> the limitness of returned errors. Why would anyone want to do 
> that?

How would something that is guaranteeing that exceptions won't be
used, combining anything with the idea they are forbidding? You
literally are getting a guarantee that any slow down is not due
to exceptions. So this last statement is non-sense (I am sorry to
be blunt, but it is).


More information about the Digitalmars-d mailing list