Not a fan. Code branches and this is Good Thing(TM). Result violates the single responsibility principle and tries to make what are distinct paths into a single thing. If your language has exceptions and returned values as distinct constructs then obfuscating them with Result means you end up fighting the language which becomes apparent fairly quickly. It's also a frustrating experience to want to interact with returned values directly and constantly have to deal with a polymorphic wrapper.

I don't see how try-catch promotes single responsibility principle. I feel like this principle is just arbitrary.

If I have Result<Error, Value> and I change the Error, I have to change all places that are using the Error type and tweak the error handling in mapLeft or flatMapLeft.

If I instead raise Error and change it, I have to look at all the places where this error explodes and deal with it, not to mention, most languages won't even give me a compile time warning if I still keep the previous error type.

I agree that if language does not have do-notation, that it's a bit ugly to sprinkle map and flatMap everywhere. Good example of ugliness is https://github.com/repeale/fp-go

I think only an effect system, or a big environment object, places everything at 1 place, and when types change you have 1 place to edit the code. But starting immediately with an effect system (to abstract away control flow) or big env (to lift all ifs up) is premature.

Your complaint wrt sprinkling flatmap is the motivation behind scala for comprehensions

    Result violates the single responsibility principle and tries to make what are distinct paths into a single thing.
You're trying to equate code paths (outcome handling) with values (outcomes), and that seems a more unfortunate category error.

> Result violates the single responsibility principle and tries to make what are distinct paths into a single thing.

Only in languages that struggle to represent multiple shapes of values with a single type. I don't think I ever want to use a language with exceptions again.

What language do you use which does not have exceptions?

C, Rust, Go. With a little effort, Scala can be used this way quite naturally, simply by allowing exceptions to crash the process.

How do you handle situations where crashing the process is inappropriate. I may not care that a library doesn't like its log file or network socket disappearing, but I very much care if its exception about that event kills the entire process.

There are cases when you need to store the result of a function regardless of if it succeeded or threw. Like if you need to tell the user that an error occurred. In those situations, a `Result` can make a lot of sense.

Arguably, `Result` can also help when it is important that error are dealt with and not just allowed to bubble up.

I'm also not a fan. Due to your point regarding code branches, but also because I just don't find the code very readable.

I think Result<T> has its use, but I don't think this is a particular great example.

[dead]