That was my first thought too. I thought it was a new web framework at first, then an ETL pipeline library. It took me about 5 pages of reading before I found an actual description, and I only knew what it was trying to accomplish from the code example because I've done functional programming before
In plain (ES6) JavaScript I can extend the class Error with my own error-classes and then extend those further. So I can create a different error-class for ever conceivable error. I can also use "instanceof" to infer whether an error is an instance of any (recursive) subclass of the error-class I'm testing for.
Just reading the docs, but it looks like it forces these errors into compile-time checks instead of runtime checks. It makes you a lot more confident that code that compiles with run correctly and without error.
Seems like it's mostly trying do similar things to what Haskell or StandardML does, but in Typescript.
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.
I see, I think. I sometimes write JavaScript functions which instead of throwing an error return an error-instance. If the caller knows what kind of result may be returned it can check if it is "instanceof Error" or of some subclass of Error and handle it somehow.
(Sum-)Types would of course be helpful in making it clear that the function can sometimes return an instance of some specific Error-subclasses of course.
Now I assume I could do something like that in plain TypeScript also, return error-instances of different error-subclasses and declare them to be possible return-types, and then handle them in the caller or its callers somehow.
Anybody getting the error-result could not pass it or return it to anybody else whose type does not expect an error-instance.
It's often said that checked exceptions are the worst mistake in Java and I believe that.
To be specific consider the case of a class that implements FetchSomeData which fetches some data (could just as well be a function with parameters encoded inside it as a closure) which could come from many sources such as
* hard coded in the class
* read from a file
* fetched via http
* fetched from Postgresql or CouchDB or ...
the one thing these have in common is they can fail in very different ways. If you want to take encapsulation seriously here the right way to do it is to expose certain semantics of the error such as
* Could the user avoid this problem by changing their inputs?
* What do we tell the end user? What do we tell the sysadmin?
* Is it likely that this problem will clear up if we retry the request in five minutes?
* Is attempting to use this object likely to cause worsening data corruption
and such. In Java we get the very week beer of people creating a large number of exceptions like FailureinSubsystemSeventeenException and sprinking thousands of methods with throws clauses and doing a lot of error-prone catching and rethrowing to please the compiler but if you really are serious about error handling you know you could get a RuntimeException because something wrote a[15] on an array that has only 12 elements and you still need to catch those anyway.
So far systems that use something like Either[Result|Exception] aren't based on an ontology of failure but my experience is that code written like that tends to have the same problems you have with checked exceptions: harried by the compiler people often omit error handling code to the maximum extent that they can. From working with both kinds of code bases I'd say that code bases worked on exceptions have the glass half full and handle errors properly more than they do improperly, these monad-based systems are the other way around.
Errors/Exceptions are just way too contextual without some sort of operator to say “hey trust me I know this can’t happen”. I’d like to see Java adopt something like Kotlins !! operator rather than coloring the stack with throws clauses.
Otherwise your code is just littered with try/catch/throw new RuntimeException(ex).
!! is poison but what is priceless in the JVM is attaching an exception handler to each thread so exceptions don’t fall off ignored, mostly you don’t want to catch exceptions if you can but instead use finally as much as possible to get the state right on both happy and sad paths, if you must rethrow use a rethrower function that handles InterruptedExeptions!
Maximum Type Safety and Error Handling doesn't tell the interesting bit that it uses the type system to track errors. (And I really don't know what Maximum Type Safety is supposed to mean in the first place)
I guess to me it looks like yet another monads for JS library. I get its a marketing page but marketing to whom? Maybe there's a better document to share on HN that shows how Effect improves those features?
This website should probably start with this. Instead it’s a bunch of like, modern synergy-ese.