The other answers you’ve gotten are right, and this is mostly just expanding on their points. But speaking for a me, this is how I view the value proposition:
With Effect (and ideas like it), you can treat error conditions as normal expressions, without special control flow. You can reason about the error conditions the same way you reason about the successful data flow. You can treat your own Error subclasses just like any other value type, with the same kind of conditional logic in the same flow. And you can do that without looking deeper into the call stack to understand where errors come from, because errors flow exactly where values flow.
Because errors and values are in the same flow, you can compose things in ways you couldn’t (or at least wouldn’t typically) with separate error control flow. You can build complex logic by composing simpler fundamentals, in a way that’s more declarative and self-documenting. Your error instanceof checks can be combined with map/filter/whatever else just like you might use with success values, and they can be mixed so that recoverable error conditions are expressed even more like success conditions.
If you’re into types, all of the same benefits apply at the type system level. You don’t have to care about types to enjoy these benefits. If you don’t care now but embrace types in the future, you’ll just get more of the same benefits in that hypothetical future.
With Effect (and ideas like it), you can treat error conditions as normal expressions, without special control flow. You can reason about the error conditions the same way you reason about the successful data flow. You can treat your own Error subclasses just like any other value type, with the same kind of conditional logic in the same flow. And you can do that without looking deeper into the call stack to understand where errors come from, because errors flow exactly where values flow.
Because errors and values are in the same flow, you can compose things in ways you couldn’t (or at least wouldn’t typically) with separate error control flow. You can build complex logic by composing simpler fundamentals, in a way that’s more declarative and self-documenting. Your error instanceof checks can be combined with map/filter/whatever else just like you might use with success values, and they can be mixed so that recoverable error conditions are expressed even more like success conditions.
If you’re into types, all of the same benefits apply at the type system level. You don’t have to care about types to enjoy these benefits. If you don’t care now but embrace types in the future, you’ll just get more of the same benefits in that hypothetical future.