8 ms·
This feels like a lot of words and fp "stuff" to describe a system where a function takes two inputs (anyval0, maybe<error>) and ouputs (anyval1, maybe<error>)
by meddlepal 8y ago
This feels like a lot of words and fp "stuff" to describe a system where a function takes two inputs (anyval0, maybe<error>) and ouputs (anyval1, maybe<error>) and you chain them together.
- deleted 8y ago[deleted]
- meowzero 8y agoNo, it's a system that takes 1 input (anyval0) and outputs either an error OR anyval1. If any of the functions errors, it rides the "error" track back up and returns the first error that it encounters. This is fail fast method using flatmap.
- woah 8y agoSounds like it’s a convoluted way to implement the same kind of thing that you’d get with a traditional error throwing paradigm
- hderms 8y agoWhat's convoluted about it? Exceptions jumping up multiple stacks and being rescued or reraised or what have you is convoluted. If you mean errors as return values then I agree, monads are more complicated than returning a simple error type.
- jecxjo 8y agoThe part you might be missing is that you're explicitly told "this function returns a value OR and error. You must handle error cases with this function". With the try/catch paradigm you never know from the function definition if that is the case. You also know what type the error will be. No need to derive a new class from `Error` and add custom functions to extract the data from your failure case, just pass the data along.
- steego 8y agoSome people don't understand what it means to chain functions returning maybe types together, so they need more words. Also, We're not taking about maybe types here. This article is demonstrating a specific library that composes a specific either type using F#'s computation expressions or custom operators. Lots of people don't know what computation expressions are, nor are they familiar with the bind operator. They don't know why they'd use an either type instead of try/catch. You can always reduce the number of words to say something, but you often sacrifice context and end up alienating people when you take too much for granted.
- lmm 8y agoThe essence of FP is that if you apply a bit of cleverness and engineering, you can replace things that look like they would need custom language features, like multiple return or async, with libraries that let you work do the same thing with plain old functions and values. (All that said, if you're thinking in terms of multiple inputs and outputs you're missing the point. The output isn't a pair, it's one or the other, and that's really important. You need to be able to make invalid states unrepresentable, so a disjoint union is not just a pair)
- mpweiher 8y agoSame for OOP, example from 1988: "Building a backtracking facility in smalltalk without kernel support"[1] Languages like Snobol, Prolog, and Icon were designed with backtracking facilities from the outset and these facilities are deeply intertwined with the implementation. Retrofitting a backtracking facility in a language that wasn't designed for it has never been achieved. We report on an experiment to retrofit Smalltalk with a backtracking facility. The facility is provided through a small number of primitives written in the language (no modifications to the kernel were made). The ability to do this is a direct result of the power provided by the objectification of contexts. There's tons of other examples, for example various distributed objects mechanisms, my own Higher Order Messaging [2] the way Gemstone creates queries from procedural selection code etc. [1] https://dl.acm.org/citation.cfm?doid=62084.62094 https://dl.acm.org/citation.cfm?doid=62084.62094 [2] https://en.wikipedia.org/wiki/Higher_order_message https://en.wikipedia.org/wiki/Higher_order_message
- corysama 8y agoYep. Java’s strawman implementation of OOP lead most of the world to never learn OOP’s potential. In Smalltalk, if was a virtual method of Boolean! Sounds horrible for performance, eh? Despite that, the Strongtalk spin off of Smalltalk was used as the internals of Java’s Hotspot JIT.
- mpweiher 8y agoFrom The Evolution of the Smalltalk Virtual Machine (Dan Ingalls, in Smalltalk-80, Bits of History, Words of Advice, Krasner): "Smalltalk-76 had to provide a mechanism for passing unevaluated code. [Blocks/Closures] Since the Smalltalk-76 design had no experience to draw from, it was weak in several areas.[..] One Problem which was discovered in the process of of supporting error recovery was that block contexts could not be restarted because they did not include their initial PC as part of their state. This was normally needed for looping , since all such code fragments ended with a branch back to the beginning. Happily, we were able to fix this by defining a new subclass." So they were able to fix a bug in the language implementation by writing code in the language itself!
- arwhatever 8y agoIt's worth noting also that the benefit of doing this is to avoid the difficult-to-reason-about, goto-like behavior that exception throwing and catching necessitates. I have yet to experience a team which handles that very well at all; it usually turns into a mess.
- nnutter 8y agoIn my experience (most) exceptions also cause people to forget about their own failure state, i.e. "always on the “happy path”", so they leave a mess behind when something they call throws an exception. Often they don't haven't handled failure state even when their own code throws an exception.
- xenomachina 8y agoAs much as people like to hate Java's checked exceptions, this is one thing I feel they really help with. They force you to think about the failure cases at least enough to either declare that you percolate them up, or handle them. I've been writing a lot of Kotlin recently, and Kotlin doesn't have checked exceptions. This has led me to start migrating away from exceptions entirely because without checked exceptions it gets too hard to track what can fail, and how. I've been switching to an approach like the author's of using an `Either` (actually `Validated` from arrow-kt -- a special purpose `Either`) to have failures in my return values. I just have to be careful when calling library code to immediately translate exceptions into return values, but the entire stack in my own code has no exceptions (aside from unrecoverable errors).
- jecxjo 8y agoI feel like this statement is often used and just as often wrong. It's not about avoiding the goto like behavior. It's about making you to know it exists and forcing you to handle it. Rathet than throwing 5 calls deep, doing nothing until you empty your call stack, you must explicitly say "I know I'm part of a system that may error" at each step along the way.
- KirinDave 8y agoCongratulations: monads are not that hard. That said, it's often preferred to use Either<Success,Error> because then you can try to explain what went wrong. A Maybe cascade failing can be pretty mysterious when you start to compose them, and you're deliberately creating something your optimizer will inline into an difficult-to-debug straight line of code.
- hderms 8y agoMaybe is perhaps suitable for things that can go wrong in only one specific way, but how many of those are there? Agreed that Either is preferable