News for hackers. Stuff that matters.
Re:Functional exceptionless error-handling with optional and... by steveklabnik on Sunday December 03, 2017 @01:59PM (#15838895)
Translated to today's Rust, this code looks like:

  fn get_cute_cat(img: image_view) -> Option<image_view> {
      let cropped = find_cat(img)?;

      let with_tie = add_bow_tie(cropped)?;

      let with_sparkles = make_eyes_sparkle(with_tie)?;

      add_rainbow(make_smaller(with_sparkles))
  }
Basically, with the same amount of boilerplate as your exception-based solution, just three ?s. If you prefer, you could also do

  fn get_cute_cat(img: image_view) -> Option<image_view> {
      find_cat(img).and_then(|cropped| 
          add_bow_tie(cropped).and_then(|with_tie|
              make_eyes_sparkle(with_tie).and_then(|with_sparkles)|
                  add_rainbow(make_smaller(with_sparkles))
              )
          )
      )
  }
... but that has rightward drift issues. I _think_ you could do

  fn get_cute_cat(img: image_view) -> Option<image_view> {
      find_cat(img)
          .and_then(add_bow_tie)
          .and_then(make_eyes_sparkle)
          .and_then(|with_sparkles|
              add_rainbow(make_smaller(with_sparkles))
          )
      )
  }
but I'm not 100% sure without a comparable example.

I bring this up because I don't believe the thing you're seeing is inherent to this style of error-handling, but instead to the language's support for these kinds of monadic patterns. Haskell would look even more succinct than the Rust!

Re:Functional exceptionless error-handling with optional and... by kindfellow92 on Sunday December 03, 2017 @02:49PM (#15839153)
I agree with your final point. Sadly Rust’s model for errors is tied to a specific implementation. That is, you must issue check instructions after every function call. In C++, errors are truly zero-cost: Exceptions only cause overheard when they happen. (Also in C++, different exception handling implementations are supported)

Rust could do something like this but it would need syntactic support for something like “throw.” In this hypothetical world, on throw the compiler could generate code that does the unwinding and all that. When a normal value is returned, it would just return as normal. The function call ABI would be one such that functions that returned Result<T> and returned normally would be assumed to have succeeded. Actually Result<T> wouldn’t need to be a real type, just decoration at the syntax level.

Re:Functional exceptionless error-handling with optional and... by Rusky on Sunday December 03, 2017 @03:11PM (#15839280)
> Exceptions only cause overheard when they happen.

They only execute instructions when they happen... but they still inhibit the optimizer when they don't. Calls that may throw act like branches in the control flow graph. They also introduce more code bloat for their landing pads.

> Rust’s model for errors is tied to a specific implementation.

The Rust ABI is unspecified for a reason. We're currently seeing a lot of optimization around struct and enum layout; I'm not sure why this couldn't be applied to the calling convention without any extra syntax for "throw."

Re:Functional exceptionless error-handling with optional and... by kindfellow92 on Sunday December 03, 2017 @05:22PM (#15839992)
> They only execute instructions when they happen... but they still inhibit the optimizer when they don't. Calls that may throw act like branches in the control flow graph.

This is a fair point and elucidates the trade off being made. Perhaps this is the reason C++11 has the “nothrow” attribute.

Re:Functional exceptionless error-handling with optional and... by kindfellow92 on Sunday December 03, 2017 @05:18PM (#15839967)
It’s not exactly tied to that implementation but because error sum types are runtime values, it’s not clear whether a statement like “return foo” should return a normal value or do stack unwinding.
Re:Functional exceptionless error-handling with optional and... by smaddox on Sunday December 03, 2017 @07:30PM (#15840565)
How are exceptions in C++ any more zero-cost than Option or Result in Rust? There must still be a branch operation in the code that C++ generates, or it wouldn't be able to handle the exception.
Re:Functional exceptionless error-handling with optional and... by kindfellow92 on Sunday December 03, 2017 @07:43PM (#15840624)
In C++ there is at most only one compare (presumably at the spot where the exception was detected). In Rust there is a compare all the way up the stack after every function call site, and it is executed if an error happens or not.