

Exceptions are monadic - timf
http://blogs.atlassian.com/developer/2011/06/exceptions_are_monadic.html

======
_delirium
This is kind of interesting for collapsing two solutions to the error-
signaling problem that are usually seen as alternatives. Or at least, I think
of them as alternatives, and they're often presented that way.

The classic error-signaling approach is in-band signaling through 'error'
return values, but that has the problem of any in-band-signaling solution,
clash between the control and data values. Two possible solutions are: 1) in-
band signaling with a more complex (data,control) encoding scheme, in this
case every function returning (value,error-code); or 2) out-of-band signaling.
The simplest example of #2 is C's _errno_ facility, with one global out-of-
band error status system; exceptions can be taken as a more sophisticated
improvement that implements local context, along with infrastructure to make
it easy to specify error-handling policies.

But it's interesting to think of exceptions as syntactic sugar on an in-band-
signaling solution, rather than out-of-band signaling at all (at least
conceptually), with Monads wrapping the code to check/propagate the error
signal.

------
virmundi
How does this work for constructors? I have the habit of guarding against poor
input. If a value is null, I'll throw a null pointer exception or an illegal
argument exception. While I recognize that both of these unchecked exceptions,
I could just as easily throw a ModelArgumentException that extends from
Exception.

The reason I throw such exceptions is that I don't want my object to be
constructed with invalid state (this is especially true when my object is
immutable, but has actions). Since I cannot return an Either, I believe that I
must either A) throw an exception or B) allow invalid state. I don't like
either solution.

~~~
T-R
Perhaps you could return an Either from the constructor, and then either have
a special construct to handle Left:

    
    
        myObj = new Object() :{ cleanup() }
    

or require dummy objects in case of failure:

    
    
        myObj = new Object() ?? new DummyObject()
    

Admittedly less than optimal. The more I think about it, the more I think it's
a bad idea... The first still means that you need a separate catch block for
each statement. The second is essentially swallowing the exception.

Aside from that, using Either in the return kills your ability to do method
chaining, unless you build method chaining into an operator and have it
propagate the Either (similar to bind).

~~~
riffraff
I think I am missing something: is there any commonly used statically typed OO
language that allows you to return a different type from the constructor?

AFAIR even in scala you either use a factory method in a companion object or
use "real" constructors.

~~~
0x0
If Objective-C fits your definition of statically typed OO language, then I
believe you can return whatever you want in the -(id)init constructor.

The common idiom for implementing constructors in subclasses is to do "self =
[super init]; if (self) { ... subclass constructor impl ... }; return self".

Setting self to nil is a common use-case.

~~~
ryanpetrich
Objective-C isn't a statically typed language, it is a dynamically typed one
with static type annotations to make the compiler check common errors for you.

------
T-R
If you were to implement this in a procedural language with side effects, what
would you do about "finally"?

~~~
rix0r
It would be a little more cumbersome to write, but the same effect can be
achieved easily:

    
    
      A a = new A();
      try {
          B(a);
          return C(a);
      } finally {
          a.cleanup();
      }
     

Transforms into:

    
    
      Either<Exception, Result> ret;
      
      A a = new A();
    
      ret = B(a);
      if (ret.isRight()) ret = C(a);
      
      a.cleanup();
      return ret;
    

Maybe someone can rewrite this even more cleanly. I can think of an easy-to-
generate improvement containing a GOTO.

~~~
T-R
Forgive my ignorance, but what about this method saves us from having to use
continuations to unwind/rewind the stack, as Exceptions do?

~~~
batterseapower
You can implement "finally" as a higher order function in Haskell:

    
    
      finally :: Either err a -> IO () -> (a -> IO (Either err b)) -> IO (Either err b)
      finally (Left err) cleanup  _k = cleanup >> return (Left err)
      finally (Right x)  _cleanup k  = k x
    

You avoid having to unwind the stack because the user of finally has to
manually convert into CPS in order to supply the higher order argument of type
"a -> IO (Either err b)"

------
pufuwozu
Author here: thanks for submitting this!

------
rian
the simple use of "Either" does not instantly qualify something as "monadic"

you know what else is monadic? NULL pointers. oh wait, you know what else is
monadic? unix pipes. you know what else is monadic? CPP. really old shit.

just because the word monad isn't everyday english doesn't make it a cool or
even an interesting concept. it's just an awkward abstraction for something
everyone already intuitively understands. monads were invented for the sole
purpose of giving haskell a programmable model for IO, that's _it_. it's just
a concept that's only useful for haskell programming, everything else
_already_ has an intuitive programming model for IO.

it's like building up integers to be this crazy complicated concept and then
saying Exceptions are integers. awesome, good job, you've just found an
equivalence, here's a pat on the back (psst
<http://en.wikipedia.org/wiki/Church_encoding>). i guess i should expect these
kinds of vacuous observations given all the BufferedManagerFactorySingleton
crap code java slaves write.

you know what else is monadic? state machines. you know what else is monadic?
imperative programming. wait wait wait! you know what else is monadic? JAVA
ITSELF _head explodes_

~~~
Peaker
I'm sorry but almost every sentence in your comment is wrong:

> the simple use of "Either" does not instantly qualify something as "monadic"

The composition of calls to functions that return Either as to implement
exceptions is exactly Monadic.

> you know what else is monadic? NULL pointers. oh wait, you know what else is
> monadic? unix pipes. you know what else is monadic? CPP. really old shit.

Only if very loosely interpreted. NULL pointers are not monadic. Maybe types
are monadic (and also considered an "Exception monad").

Unix pipes are not monadic in a meaningful way (they don't support the monadic
operations), but approximations/implementations of them can be.

In what sense is the C preprocessor monadic?

> just because the word monad isn't everyday english doesn't make it a cool or
> even an interesting concept. it's just an awkward abstraction for something
> everyone already intuitively understands.

Cool and interesting are subjective concepts. I find them pretty cool, in the
sense of capturing one of the most general patterns in code I've ever seen
captured.

In what sense are monads an "awkward" abstraction?

> monads were invented for the sole purpose of giving haskell a programmable
> model for IO, that's it. it's just a concept that's only useful for haskell
> programming, everything else already has an intuitive programming model for
> IO.

That's completely false. Monads don't have anything to do with IO, it's just a
particular instance of them. I can make a list of Bananas, does a list have
anything to do with bananas?

Monads are immensely useful for many things. When using Haskell, I can use a
very large set of combinators that work with any monad, to compose Parsers,
functions, Maybe values, and various other types.

This means I can re-use a lot more code and vocabulary. When I learn an API, I
don't have to read the documentation and types of 30 specific combinators.
Instead, the library just says: "This type has a monad instance" -- and I can
use my existing knowledge to work with it.

> it's like building up integers to be this crazy complicated concept and then
> saying Exceptions are integers. awesome, good job, you've just found an
> equivalence, here's a pat on the back

No -- the semantics of statement composition in the face of exceptions is the
only valid instance of Monad for Either values that encode them. It's not like
you have to go very far to find this equivalence. Integers are not usefully
equivalent to exceptions.

> i guess i should expect these kinds of vacuous observations given all the
> BufferedManagerFactorySingleton crap code java slaves write.

This observation is actually one of the first uses of monads in the Haskell
crowd, not in the Java crowd.

> you know what else is monadic? state machines. you know what else is
> monadic? imperative programming. wait wait wait! you know what else is
> monadic? JAVA ITSELF head explodes

I think you've completely missed the point of Monads.

Take a look at:

[http://haskell.org/ghc/docs/latest/html/libraries/base/Contr...](http://haskell.org/ghc/docs/latest/html/libraries/base/Control-
Monad.html)

I can use any of the combinators in there with any monad instance. The fact I
can use them with Either values makes Either value composition behave exactly
like exceptions.

This is not a "neat observation" -- it is something people routinely use,
plentifully.

~~~
rian
look dude, you're right. monads are freaking awesome. it's because a lot of
things in CS can be shown to "be monads", it's called turing completeness.
<http://en.wikipedia.org/wiki/Turing_completeness>

unix pipes as monads: <http://okmij.org/ftp/Computation/monadic-shell.html>

cpp as a monad: [http://conal.net/blog/posts/the-c-language-is-purely-
functio...](http://conal.net/blog/posts/the-c-language-is-purely-functional/)

monads invented for IO / functional impurity:
[http://homepages.inf.ed.ac.uk/wadler/papers/monads/monads.ps...](http://homepages.inf.ed.ac.uk/wadler/papers/monads/monads.ps.gz)

"This is not a "neat observation" -- it is something people routinely use,
plentifully." ...in haskell

and who are you to say that integers are not usefully equivalent to
exceptions??? have you ever heard of _errno_? i don't have exceptions _or_
monads in bf, just pointers. i need an equivalence so that i can feel smarter
when i code bf. and if you dare say that bf isn't a useful programming
language then you better stop coding in java...

~~~
Peaker
Monads and Turing Completeness have very little to do with each other.

Unix pipes as monads is trying to create an analogy (an imprecise one) between
unix pipe operations and monadic operations. The monadic laws do not hold with
unix pipes, so the analogy is pretty weak.

You might want to re-read Conal's "the c language is purely functional"
because it makes no claim about cpp being a monad, at all.

Let's look at the monad instances/examples listed by the Wadler paper, in
order:

* The identity monad

* The strictness monad

* The state monad

* Filters (MonadZero)

* Monad Morphisms

Under "More Monads":

* Parsers

* Exceptions

* __Input and Output __

Are you trying to use this paper to establish that monads were invented
exclusively for I/O and now perverted to describe exceptions? Note how
exceptions are listed as an example use of monads _before_ I/O.

> and who are you to say that integers are not usefully equivalent to
> exceptions??? have you ever heard of errno?

errno is not an exception mechanism. You have to indicate, in-band, that
there's an error result, then check for that result, and then use errno as
well, to implement exceptions.

Whereas the Either monad itself implements both the in-band encoding of
errors, and the caller's error-check and propagation.

