4 ms·
>Exceptions are 2-3 orders of magnitude slower if exceptions are thrown And free if they aren't thrown. It doesn't really matter if it's slow in the error path
by mrout 9y ago
>Exceptions are 2-3 orders of magnitude slower if exceptions are thrown
And free if they aren't thrown. It doesn't really matter if it's slow in the error path, as the error path is.. well.. the error path. You aren't doing useful work on the error path anyway.
>Exceptions are not part of the type-system
False. 'noexcept' is absolutely part of the type system.
>auto unsafe = [] { // a function that throws, sometimes we can't avoid it...
Please don't write code like this, this is unidiomatic C++.
>Either<std::exception, int> e = Try<std::exception>(unsafe); // let's lift the exception into the typesystem
This is really bad style in Haskell, where you got this idea from, let alone in C++. Either is a symmetric type, it's like std::pair<a, b> (in fact it's the dual of std::pair). std::either should be to std::variant as std::pair is to std::tuple.
(Minor note: Idiomatic C++ is for types to be lowercase, see the std::exception and int.)
>e.left()
.map([](auto const& e) {
These 'functional maps' are unidiomatic in C++, especially for things that aren't ranges or containers.
> return std::cerr << e.what() << std::endl;
I don't really understand why you would want to return std::cerr. Why map?
>int result = e
.leftMap([](auto) { return 42; }) // do nothing with exception and map to 42
.rightMap([](auto x) { return x * 2; }) // do further computation if value available
.join() // join both sides of either
A different sense of join compared to Haskell as well? Wow that's designed to confuse.
Instead of doing this, you could just have a couple of `if` statements. There's nothing wrong with using `if` statements in C++, honestly. C++ isn't Haskell.
- cjhanks 9y agoI concur with all of these and I will admit to on more than one occasion implementing a `Maybe<...>` type. No matter how many silly blogs I see screaming "exceptions are evil", I have never understood the logic. Some times you're several methods deep in a recursion of abstract types and `throw GetMeTheHellOutOfHere` is really as great as it gets. Also - injecting a whole bunch of branch statements in what is otherwise a vectorizable function is almost never a good thing. This is effectively what your `.map` function is doing.
- entelechy 9y ago> 'noexcept' is absolutely part of the typesystem unfortunately it is not integrated well enough: int test() noexcept { throw 1; return 1; } compiles fine but calls std::terminate at runtime. This is not very helpful at compile time