3 ms·
It is not only cleaner, it is also safer. In Python you have to add checks explicitly, or your program may try to execute a method on None. When using the Maybe
by danieldk 15y ago
It is not only cleaner, it is also safer. In Python you have to add checks explicitly, or your program may try to execute a method on None. When using the Maybe or Either monad in Haskell, failure is always handled. Say that you have a sequence of three functions that return a Maybe value:
do
b <- f a
c <- g b
h c
Now, suppose that in a particular case f a returns Nothing, then the whole do-expression will evaluate to Nothing and g Nothing is never evaluated.
Failure monads do not only add cleanliness, but also safety.
- icebraining 15y agoOne could say the problem is using None for indicating errors. Python does have exceptions, which also prevent further statements from being executed. try: b = f(a) c = g(b) return h(c) If f(a) raises an exception, g and h don't get executed. None should be returned when it's a valid value (say, in search() if it doesn't find anything), and in those cases it makes sense to have explicit handling.
- danieldk 15y agoThat's a fair point. On some level a try block resembles a monad that encapsulates success/failure. However, it is not general, e.g. it does not provide a solution if you want to chain computations where returning None/Nothing is valid (e.g. a Map lookup in Haskell). The nice thing about monads is that it provides an abstraction on sequences of computations, involving failure, error, state, effects, etc. Though, it can get ugly at times when you want to use multiple monads simultaneously (via monad transformers).
- icebraining 15y agoHowever, it is not general, e.g. it does not provide a solution if you want to chain computations where returning None/Nothing is valid (e.g. a Map lookup in Haskell). But I think that's a feature, not a bug. Conflating errors and valid values leads to ambiguity. As PEP 20 says, "Explicit it better than implicit". If you actually want certain function return values to act as a failure, I think you should wrap it in a new function that adds those semantics.