Why is it awkward? It keeps the API streamlined: You call fileOpen, and you get a FileHandle. When things do not proceed along the "essential path", you get an exception. Which is documented.
Checked exceptions aren't any less useful just because "some people" decide to call it a "shadow type system" and interpret this to mean "shadow" is somehow "bad". On Sep 23, 1:02 pm, Kevin Wright <[email protected]> wrote: > Surely "having to care about it" is the whole point here! > isn't that the entire justification of *checked* exceptions... that they > force you to "care about it"? > > Either is an alternative way to insist upon such caring, and it has the > advantages of being composable and not perverting your type signatures. > > Think about this for a second: what's the signature of our fileOpen > function? > With checked exceptions it's: String => FileHandle (or maybe > FileNotFoundException) > With either it's: String => Either<FileHandle, Error> > > That bit in the parenthesis is awkward. It's certainly a valid return from > the function, but if you use reflection to examine the return type then > you'll only see `FileHandle`. It's like a wart on the side of the > signature, a return type that isn't a return type - this is why checked > exceptions are sometimes termed a "shadow type system". This kind of > problem will definitely become more apparent once lambda support arrives in > Java. > > Then again... once lambda support arrives, we can use better solutions based > on the composability of functions. > > On 23 September 2010 11:11, Reinier Zwitserloot <[email protected]> wrote: > > > > > ... but you keep having to work around an "Either". This seems like a > > very bad idea, because now code I write has to care about it. After > > all, if I make a method that takes a String, I can't then call this > > method if I have an Either[String, Exception]. > > > On Sep 23, 1:44 am, Josh Suereth <[email protected]> wrote: > > > You've completely neglected the composability of Either, which fail > > highly, > > > IMHO. > > > > Either[A,B] has a really really interesting use case if you can convert > > it > > > into a failure monad. This allows you to chain operations as desired. > > > > // Assume every file operation returns an Either[Exception, T] > > > file.open.right.flatMap(doSomethingWithFile) > > > > This will return to us a Either[Exception, T] where T is the result type > > of > > > do something with File. However I can continue to compose functions > > > together: > > > file.open.right.flatMap(doSomethingWithFile).right.flatMap(doSomethingElseW > > ithLastResult) > > > > This will also return a Either[Exception,T] where T is the result type of > > > doSomethingElseWithLastResult. > > > > The key here is that if an exception occurs after the first expression, > > the > > > rest of the function is not executed (similarly to exception handling). > > > However, I can pass the result of this code somewhere else, *without > > > handling the exception* and allow whoever is taking the > > Either[Exception,T] > > > to handle the exception as desired. This means one piece of code can > > > create the Either and another that is *not necessarily in the same stack* > > > can handle it. I could even pass the Either to another thread. > > > > Of course, this method of capture exceptions should not be used on > > actually > > > critical exceptions, like OOM or such, but it does give you a lot of > > > options. > > > > Also, the person who finally handles the exception has something which > > looks > > > like pattern matching. > > > > theResult match { > > > case Right(value) => "Success!" > > > case Left( t : FileNotFoundException) => "O NOES!!!" > > > case Left( t : IOException) => "Something random happened in I/O, good > > > luck debugging it" > > > > } > > > > I think it's fair to say that this is more expressive than Java > > exceptions, > > > however they should *not* be used with actually critical exceptions. In > > > any case, the Lift framework uses this concept to handle parameters and > > > parsing to great effect. See Lift's Box > > > monad< > >http://blog.getintheloop.eu/2010/4/16/understanding-lift-s-box-t-monad>for > > > a good example of how this is useful. > > > > On Wed, Sep 22, 2010 at 6:20 PM, Reinier Zwitserloot <[email protected] > > >wrote: > > > > > .... but the either is noise when "file found" and "file not found" > > > > are NOT equally likely. There's no way to know as an API designer. The > > > > one thing you can tell is that "file found" is pretty much always > > > > going to be a reasonable option. No one is going to call fileOpen when > > > > they know for sure it'll fail, there wouldn't be any point. Your > > > > further comment that the "catch" will start drifting away makes no > > > > sense to me. Let's look at the either example again: > > > > > You're *calling a different method* to handle the actual result > > > > ("doSomethingWithFile"). If that's how we're going to handle it, we > > > > should be fair and let the try/catch example also use that. But, then > > > > the 'catch' for the fileOpen failure is NEVER going to drift away too > > > > far. If you're _not_ going to be calling a different method, the > > > > pattern matching version is going to make the case Right drift away > > > > just as far. This is yet another case where you see (and say, as if > > > > you're some sort of authority) that some way that java can't do is > > > > better, where its actually just personal preference. > > > > > Then there's "Left" and "Right" which are just ugly, and which also > > > > suggest there's only 1 type of exception that fileOpen can throw. try/ > > > > catch does not suffer from any of these problems. > > > > > I don't understand why this thread has drifted into "try/catch itself" > > > > is bad. It started with "forcing onto a programmer the need to check > > > > certain exceptions based on method signatures is not a good idea" > > > > which most seem to agree with. That's entirely different from the idea > > > > that try/catch itself is bad. > > > > > On Sep 22, 2:34 pm, Kevin Wright <[email protected]> wrote: > > > > > Lets compare... > > > > > > Apologies for using Scala, my intent here is to demonstrate the > > > > differences > > > > > in the techniques using a language that supports both styles, not > > > > > specifically to advocate Scala. > > > > > > val fileName = """c:\autoexec.bat""" > > > > > > // using either > > > > > fileOpen(fileName) match { > > > > > case Left(handle) => doSomethingWithFile(handle) > > > > > case Right(error) => logError(error) > > > > > } > > > > > > //using try/catch > > > > > try { > > > > > val handle = fileOpen(fileName) > > > > > doSomethingWithFile(handle) > > > > > } catch { > > > > > case Exception(e) => logError(e) > > > > > } > > > > > > The try/catch example has a couple of extra lines, but that's hardly > > > > > significant. More importantly, as the amount of code grows between > > the > > > > try > > > > > and the catch, possible points of divergence for control flow become > > > > > increasingly unclear. This is high-risk for > > > > > causing maintenance difficulties in the future. using Either, on the > > > > other > > > > > hand, suggests that "file found" and "file not found" are equally > > valid > > > > > non-exceptional outcomes, and places them on a level footing as > > regards > > > > the > > > > > flow of control. > > > > > > On 22 September 2010 13:19, Ricky Clarkson <[email protected] > > > > > wrote: > > > > > > > The point is that it's your choice what to do. Using Either does > > not > > > > mean > > > > > > you have to write lots of if statements, though you can if you > > like. > > > > > > > On Wed, Sep 22, 2010 at 12:22 PM, Miroslav Pokorny < > > > > > > [email protected]> wrote: > > > > > > >> How is either any better than letting catching an exception or > > letting > > > > the > > > > > >> code continue in the original spot. One gets a split off into a > > > > everythings > > > > > >> ok here a file, or jump to there and process the problem ? Using > > > > Either ends > > > > > >> up being "more" code because we get the branch for free with > > > > > >> exceptions...And given FileCreation failed is an exception the > > flow > > > > will be > > > > > >> most likely at least a bit different. Continuing on and checking > > later > > > > does > > > > > >> not seem to make much sense most of the time. > > > > > > >> -- > > > > > >> 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]<javaposse%2bunsubscr...@googlegroups > > > > > >> .com> > > <javaposse%2bunsubscr...@googlegroups .com> > > > > <javaposse%2bunsubscr...@googlegroups .com> > > > > > >> . > > > > > >> For more options, visit this group at > > > > > >>http://groups.google.com/group/javaposse?hl=en. > > > > > > > -- > > > > > > 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]<javaposse%2bunsubscr...@googlegroups > > > > > > .com> > > <javaposse%2bunsubscr...@googlegroups .com> > > > > <javaposse%2bunsubscr...@googlegroups .com> > > > > > > . > > > > > > For more options, visit this group at > > > > > >http://groups.google.com/group/javaposse?hl=en. > > > > > > -- > > > > > Kevin Wright > > > > > > mail / gtalk / msn : [email protected] > > > > > pulse / skype: kev.lee.wright > > > > > twitter: @thecoda > > > > > -- > > > > 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]<javaposse%2bunsubscr...@googlegroups > > > > .com> > > <javaposse%2bunsubscr...@googlegroups .com> > > > > . > > > > For more options, visit this group at > > > >http://groups.google.com/group/javaposse?hl=en. > > > -- > > 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 > > ... > > read more » -- 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.
