4 ms·
First, who writes code like that? Let's try some more realistic formatting. fooResult = foo(x); if (fooResult == null) { return null; }
by jlarocco 14y ago
First, who writes code like that? Let's try some more realistic formatting.
fooResult = foo(x);
if (fooResult == null) {
return null;
}
barResult = bar(fooResult);
if (barResult == null) {
return null;
}
bazResult = baz(barResult);
if (bazResult == null) {
return null;
}
quuxResult = quux(bazResult);
if (quuxResult == null) {
return null;
}
return quuxResult;
Second, in most cases ignoring errors is not what you want. Knowing which function returned null, and why it returned null, is almost as important as the null itself.
Ideally functions would raise an exception instead of returning bad data (aka null) and the psuedo-code snippet above would more cleanly be written:
fooResult = foo(x);
barResult = bar(fooResult);
bazResult = baz(barResult);
return quux(bazResult);
Or to match your single line:
return quux(baz(bar(foo)));
The exception would be handled in the same place that handles the eventual Nothing value returned in Haskell.
- tmhedberg 14y agoI concede on the pseudocode formatting point. Upon rereading, that is uglier than necessary. The trouble with exceptions is that, unless you're referring to Java-style checked exceptions, there's nothing that forces you to handle them. You can still forget that the exception can occur, and then your code will blow up at runtime. And in one sense, exceptions are even worse than the repetitive if-then clauses: if statements at least handle the failure right there at the call site, whereas exceptions let you move your error handling code to some other place in the call stack, non-local to where the actual error might occur. There are advantages as well, for sure, but I see this as potentially very confusing. Haskell has exceptions but most people prefer to avoid them, favoring the use of MonadError instances (such as Maybe) instead, since they make the potential failure highly explicit and impossible to forget about or ignore. And while I don't think using Maybe is at all the same as ignoring errors, I suppose I see how it could be construed that way. That's why there's Either as well, which allows you to associate some piece of data with the failure. So you could use the Either String monad to pass back an error message on failure, or Either [String] to pass a list of them, or Either (IO ()) to specify an action to be taken in response to the failure, or whatever you want. I guess that ends up being a lot like exceptions, except for the fact that you can't ignore or forget them, so your code is still verifiably safe at runtime, and there is nice syntactic sugar from the Monad class (do notation, >>= chaining, etc.) to make them concise and elegant to use without cluttering your code.
- pka 14y agoSo, Java's HashMap.get() should throw a checked exception whenever the value is not found in the map? That would sure eliminate a lot of boilerplate code :) Aren't exceptions meant to be used for, well, exceptional cases only, i.e. when no matter what, execution really can't be continued? It makes sense for a lot of functions to return some sort of "Nothing" value instead of raising an exception, but the problem is that in many languages there is no explicit "Nothing" value, so people just abuse null. You can have Maybe in Java too, but getting out a value or a Nothing out of a Maybe value is just not enforced by the compiler due to the lack of algebraic data types and pattern matching; still, it is an improvement over null hell. On a side note, Maybe is called Option in Scala. By the way, exceptions are monads, they are just predefined in most languages in a way you can not change. If you want a lengthy Java centric read about that I would strongly recommend checking out [1]. Ant here's another if you're ok with reading Haskell [2]. Also for the record, in Haskell you can use the ErrorMonad in place of the Maybe monad if you want precise error reporting capabilities. [1] http://apocalisp.wordpress.com/2008/05/16/thrower-functor http://apocalisp.wordpress.com/2008/05/16/thrower-functor [2] http://www.haskell.org/haskellwiki/Exception http://www.haskell.org/haskellwiki/Exception
- Peaker 14y agoExceptions can be modeled by a type like "Maybe" that simply also has the error information in it. So instead of a "Nothing", you have "Left err" with the "err" information in it. The nice thing is that the same example using >>= above would work with Either's too, because it will just use the monad instance of Eithers, and you will get all the error information that way. Exceptions, when represented this way, become a way that the error is handled by the caller rather than a different way to return. That way, the result of the function is well-described by its type.
- dustingetz 14y agoyou can implement exceptions with error monad.