News for hackers. Stuff that matters.
Re:Where Everything Went Wrong: Error Handling and Error Mes... by tus89 on Friday February 19, 2021 @01:08PM (#26195985)
> Any error system that relies upon developer discipline will fail because errors will be missed.

Haven't there been some languages that force functions to return some kind of tuple like:

result,error

And forces the programmer to at least do:

if(error) { }

It does not force any kind of correct handling, but simply oversights should be caught. I might be imagining things though.

Re:Where Everything Went Wrong: Error Handling and Error Mes... by masklinn on Friday February 19, 2021 @02:02PM (#26196643)
What you're describing is Go, except its requirements are much weaker than that.

Rust, meanwhile, is way stricter than that, and has gone way further on the "not relying on developer discipline" path: a failing Rust function will return a `Result<Value, Error>`. You can't even access the value without explicitly checking whether it's a value or an error one way or the other, which you can very much do so in e.g. Go. Rust also has an attribute called `must_use`, which can be set on types and functions. That attribute causes the compiler to emit a warning if the marked object is not used at all (either the type or the function's result), so while go will not say anything if you write

    Foo()
and that returns an error (or an error and a result you happened not to care for), Rust will absolutely complain by default in the same case, you will need to write at the very least

    let _ = Foo();
Go has a second issue, which is that in

    result, error := Foo()
that you "have to" handle the error is a consequence of the unused variable check (can't define a variable and never read from it). However because it's that instead of something dedicated, this:

    id, error := Foo()
    result, error := Bar(id)
    if error != nil {}
will work fine, with no complaint. Despite possibly passing complete nonsense to Bar if Foo is in error. Also works with

    id, error := Foo()
    if error != nil {}
    result, error := Bar(id)
Funnily enough Rust will also warn in both those cases, because it tries to track individual writes.
Re:Where Everything Went Wrong: Error Handling and Error Mes... by simias on Friday February 19, 2021 @01:12PM (#26196028)
That's Go. IMO Rust's approach is vastly saner, since a Result<> type has to be explicitly handled one way or an other. You simply can't access the returned value without unwrapping it.

Of course that leaves function that can fail but don't return any value, but since Result is tagged "must_use" you get a compiler warning if you don't explicitly discard the result with something like `let _ = foo()`.

Re:Where Everything Went Wrong: Error Handling and Error Mes... by kelnos on Friday February 19, 2021 @05:00PM (#26198588)
There's no "forcing" there. You can simply ignore the error part of the tuple, or even just forget to check it.

If the function returns a (non-error) value that is directly accessible from the function call, the programmer is not forced to do anything with the error.

This is exactly the same problem with null: forget a null check, and you're hosed. Forget an error check, and you're hosed.

If you make errors a part of the actual single return type (as Rust does), then you have to explicitly deal with the possibility of an error before you are even allowed to touch the successful case.

Re:Where Everything Went Wrong: Error Handling and Error Mes... by TacticalCoder on Friday February 19, 2021 @01:48PM (#26196460)
GP mentionned "maybes". In Haskell (and others) you have for example both maybe and either. When you've got an either you can have either (ah!) the left to indicate an error (and which error) or the right to hold the correct value. And the type system forces you to at deal with both cases (like a maybe forces you to deal with the case where it's "maybe not").