
C++14 either monad and why you shouldn't use exceptions - entelechy
https://github.com/LoopPerfect/neither
======
daemin
This won't work well with types that need alignment. It might be better not to
have the internal buffer of characters but instead have an anonymous union of
both left and right types.

Also Expected is not quite the same thing as this. This Maybe and Either is
like Expected but with the ability to call .then() on it to do further
processing.

~~~
entelechy
interesting, why wouldn't it work well with those types?

how would an union help?

~~~
daemin
So one of the reasons is that it's following a bool variable, which size is
not fixed, but are usually 1 byte. So even if the class itself was aligned the
buffer within would be unaligned. The other is that the alignment of a char
buffer is 1 by default.

This can actually lead to crashes in the processor when it is using aligned
functions (like SSE) but the data is unaligned.

If a union is used instead it should be aligned to the biggest alignment of
its members. Then if it's put at the start of the class as the first variable,
it should make the class aligned to the same value and not waste space on
padding.

------
entelechy
alternatives:
[https://github.com/ptal/expected](https://github.com/ptal/expected)
[https://github.com/beark/ftl](https://github.com/beark/ftl)

------
tempodox
Still looks very clunky and nowhere near the elegance and efficiency of true
FP.

------
mrout
>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
I 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.

