On 24 March 2011 15:03, Reinier Zwitserloot <[email protected]> wrote:
> error-via-return-value is far inferior to anything else as a complete > solution to what checked/unchecked exceptions are trying to do. Here are the > problems with it: > > (A) For any method that would ordinarily return void, this boils down to > C-style "return error codes". I pray I don't have to explain why this is far > far worse compared to exceptions (of either checked or unchecked variety). > C-style error codes are perfectly natural where the closest you have to pattern-matching on alternate possibilities is a switch statement that only handles integers. Exceptions often seem to be a better fit, not because there's any benefit to returning data via a side channel, but because exception *handlers* offer richer pattern-matching semantics. The issue here isn't return statements, but what language constructs are available for structure and flow control in the language. Don't point to nested if/else statements as showing the inadequacy of return values when you should be pointing to exception handlers as showing the inadequacy of nested if/else statements. (B) Where you can get away with returning maybes/options, you're making it > much harder for code to decide to defer the handling of this error condition > to something up the chain. It's also infectious - if as part of doing your > thing you could run into errors, then you have to turn whatever you return > into an Option/Maybe guard as well. At some point virtually every method > returns option/maybe. > Which is exactly what you want, sometimes, and is *exactly* what checked exceptions do. The following two definitions are directly equivalent: String someMethod(String input) throws FileNotFoundException Either<FileNotFoundException, String> someMethod(String input) The differences being: - Java has specialised construct to ease the task of exception handling, but lacks constructs to simplify working with data inside the right-hand side of an "Either" - "throws" is returning data via a sideband channel, and isn't part of the core method signature - Either could just as easily return some error type, not just exceptions (it could be a string for display to the end user) - Uses exceptions always forces an expensive stack trace to be built, if if not needed - When using "Either", it's the method that decides if it must be explicitly handled, not the type hierarchy of the exception type This last point is significant, imagine I had two methods: void logImportantTransactionDetailsForLegalCompliance void saveActiveDocument In both cases, the file may not be found, so a FileNotFoundException seems appropriate. For the first method, I'd want to enforce that that exception is caught asap, in the second, I want it to propogate back to the UI through several layers of stack. by having a return type of Option<Exception> in the first case, and an unchecked exception in the second case, I can do this. But with the checked variety, it's all or nothing, as the Exception type determines if it must be checked, not the thrower. > (C) You don't solve the problem of "where do we draw the line?" - when does > an exception become sufficiently unlikely that you're better off making it a > checked exception? The same question applies to: When do we return Option > and when do we not? You're not solving any problems here. > Exactly the same as for checked exceptions, you either handle it or pass up the stack. This is a domain design issue though, not something that can be correctly answered at the language level. Option is typically used wherever a null would be expected in java to indicate "no value", such as looking up the value for an undefined key in a map. (question, how best would you disambiguate the case where it does hold a value, but that value is null?) The problem being solved is how to compose a sequence of operations that may or may not have a return value/error. The missing piece of the puzzle is closures, allowing you to do stuff like: val x: Option[Int] = Some(7) val y = x map (2 * _) //returns Some(14) if x was None, this would return None. No errors, no NullPointerExceptions, it just works. You can do the same thing to map-over the right-hand-side of an Either, while leaving intact any Error held by the left hand side. Likewise, you can map over the left hand side to convert (for example) an exception to a message string. -- Kevin Wright gtalk / msn : [email protected] <[email protected]>mail: [email protected] vibe / skype: kev.lee.wright quora: http://www.quora.com/Kevin-Wright twitter: @thecoda "My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra -- You received this message because you are subscribed to the Google Groups "The Java Posse" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.
