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(doSomethingElseWithLastResult)

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%[email protected]>
> <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%[email protected]>
> <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%[email protected]>
> .
> 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].
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en.

Reply via email to