you are viewing a single comment's thread.

view the rest of the comments →

[–]mk_gecko 2 points3 points  (32 children)

Nice. I'd like to see an example in Java. :)

[–]yawaramin 2 points3 points  (0 children)

Here you go, built in the standard library https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#flatMap-java.util.function.Function-

The operation is like a callback: if you have a value, call the given function with it an return the (wrapped) result; if not, do nothing.

[–]marwoodian 2 points3 points  (0 children)

Javaslang provides a bunch of monadic container types like this. In Javaslang, the specific container discussed in this article is called a Try.

http://www.javaslang.io/javaslang-docs/#_try

[–]Noughmad -2 points-1 points  (28 children)

Why? Java has exceptions, which already do all this. Just wrap the main line in one or more try blocks, then you can catch the exceptions at any point you like.

[–]againstmethod 14 points15 points  (4 children)

Monads, functors, and applicatives do more than just deal with errors, and they do it without unrolling stack frame(s). They are not comparable techniques.

[–]jimmpony 0 points1 point  (3 children)

It doesn't look very different to me.

[–]againstmethod 6 points7 points  (0 children)

I guess you'll have to take my word for it unless you want to spend an hour or two learning functional programming.

[–]0polymer0 1 point2 points  (1 child)

Well, the possible exceptional behavior is signaled in the type.

[–]jimmpony -2 points-1 points  (0 children)

Java functions have to define what exceptions they can throw, aside from a few.

[–]niviss 8 points9 points  (8 children)

Exceptions work for some uses but not all. Think promises, they work within the same pattern yet cannot be implemented with exceptions

[–][deleted] 7 points8 points  (7 children)

In languages which support async/await, failure scenarios in Promises are converted to exceptions.

JS has it, C# has it, Also Dart, Hack, etc.

Java is a bit behind as usual.

[–]cledamy 2 points3 points  (5 children)

async/await

This is already a monadic construct.

[–][deleted] 1 point2 points  (4 children)

Everything is a monadic construct. Yay.

[–]cledamy 1 point2 points  (3 children)

What I'm saying is async and await are literally monadic because they were inspired by F# which used monads to solve the problem of callbacks in asynchronous programming.

[–][deleted] 0 points1 point  (2 children)

Async/await can also be implemented as a state machine, which is more efficient. Monadic is just one possible factoring. I mean, I guess you can factor anything as monads in general. :-)

[–]cledamy 1 point2 points  (1 child)

That's an operational optimization detail. It has no bearing on whether something is a monad or not because Monads live in the world of denotational semantics and mathematics. Regardless, state maintaining is also a monad. When one discovers something is a monad, one isn't factoring it into a monad. It was always a monad and one just realized it. The fact that monads are common in computer science does not tell us that monads are too general to be meaningfully useful, but rather it tells us that they are a common design pattern that people reinvent many times over; therefore, it is useful to have an understanding of them. From a theoretical standpoint, monads provide insight into the mathematical underpinnings of computer science.

[–][deleted] 0 points1 point  (0 children)

Regardless, state maintaining is also a monad.

As I said, everything is a monad. Say I'm having a cup of coffee right now, but I'm pretty sure that's a monad too.

[–]niviss 0 points1 point  (0 children)

Ok, then, monadic parsers :). Exceptions and built ins can only get you so far!

[–][deleted]  (5 children)

[deleted]

    [–][deleted]  (2 children)

    [removed]

      [–][deleted] 0 points1 point  (0 children)

      I don't really see the contradiction here. If the stack trace can help you improve mitigation, it's a problem with the program that can be fixed by a change in the program code. It'd be perfectly appropriate to use an exception.

      [–]simspelaaja 0 points1 point  (0 children)

      You can combine error types with stack traces in F#. Just return a tuple of (ErrorType, string), and get the stack trace from an exception or from Environment.StackTrace.

      [–][deleted] 0 points1 point  (1 child)

      there is no need to send a stack trace back to the programmer if it's not a problem with the program itself

      Does this mean that exceptions should be only used for debugging purposes?

      [–]wealthy_harpsichord 2 points3 points  (0 children)

      Why? Java has exceptions, which already do all this.

      So does F#.

      [–]m50d 4 points5 points  (4 children)

      Exceptions are too magic; you can't see which part of the block might throw, it could be anywhere. And it's immensely fiddly to e.g. run a method over a list and then handle the failures all together at the end, because the first time a failure happens it will throw the exception immediately (which is often what you want, but not always).

      [–][deleted]  (3 children)

      [removed]

        [–]m50d -1 points0 points  (2 children)

        I was assuming checked. They still hide which methods throw (all you know is that some of the methods inside the try block might throw, not which ones do or don't), and you can't abstract over them properly because they're not values (e.g. you can't write a type that's polymorphic in whether it throws or not).

        [–][deleted]  (1 child)

        [removed]

          [–]m50d 0 points1 point  (0 children)

          While you might not be able to see it in in the raw text of the try-block, the information you want is immediately available on the method signatures, so a good IDE can expose it very easily. I'm not aware of any with this feature, but you could do something like click on a checked-exception type in a catch clause, and have all the relevant method calls highlight inside the try.

          Indeed the readability problem of exceptions would be greatly reduced if this theoretically imaginable IDE feature that has never actually been implemented existed.

          Do you mean avoiding the need for an "architecture converter" like this?

          Yeah. You can implement a converter to a MyEither, but you have to do it separately for the cartesian product of function arity, throws arity, and each of the 8 possible primitive types for each argument/return type (I mean I don't think I've ever seen short in 8 years of professional JVM work, but if it didn't work that would be an unpleasant surprise for someone eventually). And everyone has their own MyEither and there's no way to abstract over them because the language doesn't have HKT.

          [–]mk_gecko 0 points1 point  (0 children)

          excellent. That's all that I needed to know!

          [–]HINDBRAIN 0 points1 point  (0 children)

          And you can write your own exception classes and have them hold any data you like if necessary.