Benefits of Functional decomposition and currying - java

I have a function, calculate(String A,int B) in legacy code
Double calculate(String A,int B) {
if(A.equals("something")){ return B*1.02; }
if(B.equals("some")) return B*1.0;
else return B;
}
The calculation applied on B depends on the value of A.
In functional style I can break this into:
Function<String, Function<Integer,Double>> strategyA = (a)-> {
if(A.equals("something")) return b -> b*1.02;
if(B.equals("some")) return b -> return b -> b*1.0;
else return b -> b;
}
Then instead of calling calculate(a,b) I would call
strategyA.apply(a).apply(b)
Is the second style better than first one. As per my understanding this involves Strategy pattern and Functional Decomposition and Currying.
If the second approach is indeed better, how would you convince someone?

In Java, the preferred way of delivering a named piece of code is and stays the method. There is no reason to express a method as function, just to have “more functional style”. The reason, why function support was added to Java, is, that you sometimes want to pass a reference to the code to another method or function. In this case, the receiving method defines the required function signature, not the code you’re going to encapsulate.
So your calculate method may be referred to as an ObjIntConsumer<String>, if the receiving method only wants to pass pairs of String and int to it without being interested in the result. Otherwise, it may use a custom functional interface expressing the (String,int) → Double signature. Or when you accept boxing, BiFunction<String,Integer,Double> will do.
Currying allows you to reuse existing interfaces like Function to express functions with multiple arguments, when no builtin interface exists, but given the resulting generic signature, which will appear at least at one place in Java code using such a curried function, the readability suffers a lot, so in most cases, defining a new functional interface will be preferred over currying in most cases…
For other programming languages, having a different syntax and type inference for functional types (or having real function types in the first place, rather than settling on functional interfaces), this will be quite different.

I agree with Holger that in most cases, it does not make sense to write code using functions just for the sake of using functional programming. Functions are just an additional tool that lets you write code such as collection processing in a nicer way.
There is one interesting thing about your example though, which is that you take the String parameter a, then perform some computation and then return another function. This can be sometimes useful if the first operation takes a long time:
Function<String, Function<Integer,Double>> f = (a) -> {
if (some-long-computation(a)) return b -> b*1.02;
if (some-other-long-computation(a)) return b -> return b -> b*1.0;
else return b -> b;
}
When you then invoke f with the String argument, the function will run some-long-computation and some-other-long-computation and return the desired function:
Function<Integer,Double> fast = f.apply("Some input"); // Slow
Double d1 = fast.apply(123); // Fast!
Double d1 = fast.apply(456); // Fast!
If f was an ordinary method, then calling it twice as f("Some input", 123) and
f("Some input", 456) would be slower, because you'd run the expensive computations twice. Of course, this is something you can handle without functional programming too, but it is one place where returning a function actually fits quite nicely.

Related

Correct syntax for making a functional interface instance automatically call its method

I've been watching Douglas Schmidt classes on Parallel Java. He introduces Lambda x method referencing syntax discussion, highlighting how the last one is preferable, as it makes clearer what the code is actually doing, not what the programmer is trying to do with the code, even more than forEach approach.
String[] names = {"first", "Second", "third"};
Arrays.sort(names, (n1,n2) -> n1.compareToIgnoreCase(n2));
Arrays.sort(names, String::compareToIgnoreCase); //preferable
For example, that approach mitigates the chances of programmer making mistakes inside lambda function: passing the wrong argument, inverting arguments order, adding collateral effects, etc.
Then he introduces Functional interfaces, an interface that contains only an abstract method, implementing its own interface runTest with an abstract method factorial():
private static <T> void runTest(Function<T,T> factorial, T n) {
System.out.println(n+ " factorial = " + factorial.apply(n));
}
private static class ParallelStreamFactorial{
static BigInteger factorial(BigInteger n) {
return LongStream
.rangeClosed(1, n.longValue())
.parallel()
.mapToObj(BigInteger::valueOf)
.reduce(BigInteger.ONE, BigInteger::multiply);
}
}
Calling it with the following syntax:
import java.math.BigInteger;
import java.util.function.Function;
import java.util.stream.LongStream;
public static void main(String[] args) {
BigInteger n = BigInteger.valueOf(3);
runTest(ParallelStreamFactorial::factorial, n);
}
The code works and prints
3 factorial = 6
As I'm studying lambdas, I tried to interchange method reference syntax for lambda syntax, and managed to using:
public static void main(String[] args) {
BigInteger n = BigInteger.valueOf(3);
runTest((number)->ParallelStreamFactorial.factorial(number), n);
}
Which also worked.
Then he proceeds to explain built-in interfaces, such as Predicate<T>{boolean test(T t);}, and that's where I got stuck.
I managed to implement a Predicate<Integer> that tests if the integer is bigger than 0 using the three syntaxes:
Instantiating an object myPredicate from a class that implements Predicate<Integer>
Instantiating an object lambdaPredicate from a lambda
Instantiating an object methodReferencePredicatefrom a method reference:
import java.util.function.Function;
import java.util.function.Predicate;
public class MyPredicates {
public static void main(String[] args) {
Predicate<Integer> constructorPredicate = new myPredicate();
System.out.println(constructorPredicate.test(4));
Predicate<Integer> lambdaPredicate = (number)-> number > 0;
System.out.println(lambdaPredicate.test(4));
Predicate<Integer> methodReferencePredicate = myMethodReference::myTest;
System.out.println(methodReferencePredicate.test(4));
}
private static class myPredicate implements Predicate<Integer>{
public boolean test(Integer t) {
return t>0;
}
}
private static class myMethodReference{
public static boolean myTest(Integer t) {
return t>0;
}
}
}
And then calling their .test() methods. They're all three working and printing true.
However I would like to "instantiate and call" everything in a single line, as he did in his example. It seems like his code is inferring the type of the argument passed (I may be wrong) but it's definitely running automatically.
I tried different things:
Predicate<Integer>(myMethodReference::myTest, 4);
Predicate(myMethodReference::myTest, 4);
Predicate<Integer>((number) -> myMethodReference.myTest(number), 4);
Predicate((number) -> myMethodReference.myTest(number), 4);
But none of them work.
They throw:
Syntax error, insert ";" to complete LocalVariableDeclarationStatement
and
The method Predicate(myMethodReference::myTest, int) is undefined for the type MyPredicates
Errors. I also don't even know the name of what he's doing in that single line to properly search better on internet for references.
What's the correct syntax for that, whether by method reference or lambdas?
You've made things far too complicated.
There is no point in lambdas if you want to 'execute them immediately'.
Here is how you run your my test code 'immediately':
System.out.println(number > 4);
Why mess with lambdas? They just make matters confusing here.
The very point of a lambda is two-fold:
A way to transmit code itself to other contexts.
Control flow abstraction.
In java in particular, option 2 is an evil - it makes code ugly, harder to reason about, introduces pointless distractions, and in general should be avoided... unless you're employing it to avoid an even greater evil. That happens plenty - for example, a reasonable 'stream chain' is generally better even though its control flow abstraction. I'd say this:
int total = list.stream()
.filter(x -> x.length() < 5)
.mapToInt(Integer::valueOf)
.sum();
is the lesser evil compared to:
int total = 0;
for (var x : list) {
if (x.length() < 5) continue;
total += Integer.parseInt(x);
}
but it is a pretty close call.
Why is it 'evil'? Because lambdas in java are non transparent in 3 important ways, and this non-transparency is a good thing in the first case, but a bad thing in the second. Specifically, lambdas are not transparent in these ways:
Lambdas cannot change or even read local variables from outer scope unless they are (effectively) final.
Lambdas cannot throw checked exceptions even if the outer scope would handle them (because they catch them or the method you're in declared throws ThatException).
Lambdas cannot do control flow. You can't break, continue, or return from within a lambda to outside of it.
These 3 things are all useful and important things to be doing when you're dealing with basic control flow. Therefore, lambdas should be avoided as you create a bunch of problems and inflexibility by using them... unless you've avoided more complexity and inflexibility of course. It's programming: Nothing is ever easy.
The notion of bundling up code is therefore much more useful, because those non-transparencies turn into upside:
If you take the lambda code and export it to someplace that runs that code much later and in another thread, what does it even mean to modify a local variable at that point? The local variable is long gone (local vars are ordinarily declared on stack and disappear when the method that made them ends. That method has ended; your lambda survived this, and is now running in another context). Do we now start marking local vars as volatile to avoid thead issues? Oof.
The fact that the outer code deals with a checked exception is irrelevant: The lexical scope that was available when you declared the lambda is no longer there, we've long ago moved past it.
Control flow - breaking out of or restarting a loop, or returning from a method. What loop? What method? They have already ended. The code makes no sense.
See? Lambda lack of transparency is in all ways great (because they make no sense), if your lambda is 'travelling'. Hence, lambdas are best used for this, they have no downsides at that point.
Thus, let's talk about travelling lambdas: The very notion is to take code and not execute it. Instead, you hand it off to other code that does whatever it wants. It may run it 2 days from now when someone connects to your web server, using path /foobar. It may run every time someone adds a new entry to a TreeSet in order to figure out where in the tree the item should be placed (that's precisely the fate of the lambda you pass to new TreeSet<X>((a, b) -> compare-a-and-b-here).
Even in control flow situations (which are to be avoided if possible), your lambda still travels, it just travels to place that does immediately ends up using it, but the point of the lambda remains control flow abstraction: You don't run the code in it, you hand your lambda off to something else which will then immediately run that 0 to many times. That's exactly what is happening here:
list.forEach(System.out::println);
I'm taking the code notion of System.out.println(someString), and I don't run it - no, I bundle up that idea in a lambda and then pass this notion to list's forEach method which will then invoke it for me, on every item in the list. As mentioned, this is bad code, because it needlessly uses lambdas in control flow abstraction mdoe which is inferior to just for (var item : list) System.out.println(item);, but it gets the point across.
It just doesn't make sense to want to write a lambda and immediately execute it. Why not just... execute it?
In your example from the book, you don't actually execute the lambda as you make it. You just.. make it, and hand it off to the runTest method, and it runs it. The clue is, runTest is a method (vs your attempts - Predicate is not a method), it's not magical or weird, just.. a method, that so happens to take a Function<A, B> as argument, and the lambda you write so happens to 'fit' - it can be interpreted as an implementation of Function<A, B>, and thus that code compiles and does what it does.
You'd have to do the same thing.
But, if that code is a single-use helper method, then there's no point to the lambda in the first place.

Why use lambda over normal methods?

So suppose my application does lots of repetitive work, for example let's say my application checks lots of various Lists if they're empty or not. There are two methods by which I can accomplish this functionality - (there maybe other methods but since my goal is to understand the difference of the two methods and not the functionality itself here we go)
Method 1 - Tradition Method
public boolean isEmptyOrNull(List list)
{
return list != null && !list.isEmpty();
}
Method 2 - Lambda Way
Assuming we have created a functional interface with class name Demo and boolean isEmptyOrNull as the function.
Demo var = list -> list != null && !list.isEmpty();
So each time I wish to check a list I can either use Method 1 or 2 by using isEmptyOrNull(myList) or var.isEmptyOrNull(myList) respectively.
My question is why should I use Method 1 and not Method 2 and vice versa. Is there some performance aspect or some other aspect as to why I should prefer one method over the other !?
Oof, where to start.
Your idea of what null is, is broken.
isEmptyOrNull is a code smell. You shouldn't have this method.
null is a stand-in value that necessarily can mean 'not initialised', because that's built into java itself: Any field that you don't explicitly set will be null. However, it is very common in APIs, even in java.* APIs, that null can also mean 'not found' (such as when you call map.get(someKeyNotInTheMap)), and sometimes also 'irrelevant in this context', such as asking a bootstrapped class for its ClassLoader.
It does not, as a rule, mean 'empty'. That's because there is a perfectly fine non-null value that does a perfect job representing empty. For strings, "" is the empty string, so use that, don't arbitrarily return null instead. For lists, an empty list (as easy to make as List.of()) is what you should be using for empty lists.
Assuming that null semantically means the exact same thing as List.of() is either unneccessary (the source of that list wouldn't be returning null in the first place, thus making that null check unneccessary) or worse, will hide errors: You erroneously interpret 'uninitialized' as 'empty', which is a fine way to have a bug and to have that result your app doing nothing, making it very hard to find the bug. It's much better if a bug loudly announces its presence and does so by pointing exactly at the place in your code where the bug exists, which is why you want an exception instead of a 'do nothing, silently, when that is incorrect' style bug.
Your lambda code does not compile
Unless Demo is a functional interface that has the method boolean isEmptyOrNull(List list);, that is.
The difference
The crucial difference is that a lambda represents a method that you can reference. You can pass the lambda itself around as a parameter.
For example, java.util.TreeSet is an implementation of set that stores all elements you put inside in sorted order by using a tree. It's like building a phonebook: To put "Ms. Bernstein" into the phonebook, you open the book to the middle, check the name there, and if it's 'above' 'Bernstein', look at the middle of the first half. Keep going until you find the place where Bernstein should be inserted; even in a phonebook of a million numbers, this only takes about 20 steps, which is why TreeSet is fast even if you put tons of stuff in there.
The one thing TreeSet needs to do its job is a comparison function: "Given the name 'Maidstone' and 'Bernstein', which one should be listed later in the phone book"? That's all. If you have that function then TreeSet can do its job regardless of the kind of object you store in it.
So let's say you want to make a phone book that first sorts on the length of names, and only then alphabetically.
This requires that you pass the function that decrees which of two names is 'after' the other. Lambdas make this easy:
Comparator<String> decider = (a, b) -> {
if (a.length() < b.length()) return -1;
if (a.length() > b.length()) return +1;
return a.compareTo(b);
};
SortedSet<String> phonebook = new TreeSet<>(decider);
Now try to write this without using lambdas. You won't be able to, as you can't use method names like this. This doesn't work:
public void decider(String a, String b) {
if (a.length() < b.length()) return -1;
if (a.length() > b.length()) return +1;
return a.compareTo(b);
}
public SortedSet<String> makeLengthBook() {
return new TreeSet<String>(decider);
}
There are many reasons that doesn't work, but from a language design point of view: Because in java you can have a method named decider, and also a local variable named decider. You can write this::decider which would work - that's just syntax sugar for (a, b) -> this.decider(a, b); and you should by all means use that where possible.
There is no advantage in your example. Lamdas are often used in Object Streams, e.g for mapping or filtering by defining "adhoc functions" (that's what lambdas are).
Example: You have a list of strings named allStrings that you want to filter
List<String> longStrings = allStrings.stream()
.filter(s -> s.length() > 5) // only keep strings longer than 5
.collect(Collectors.toList()); // collect stream in a new list
Lambdas were added to introduce functional programming in java. It could be used as a shorthand for implementing single method interfaces (Functional interfaces). In the above example you provided, there is no much advantage. But lambdas could be useful in the below scenario:
Before lambdas
public Interface Calc{
int doCalc(int a, int b);
}
public class MyClass{
public void main(String[] args){
Calc x = new Calc() {
#Override
public int doCalc(int a, int b) {
return a + b;
}
};
System.out.println(x.doCalc(2, 3));
}
}
But with lambdas this could be simplified to
public class MyClass{
public void main(String[] args){
BiFunction<Integer, Integer, Integer> doCalc= (a, b) -> a + b;
System.out.println(doCalc.apply(2, 3));
}
}
This is especially helpful for implementing event listeners (in Android), in which case there are a lot of interfaces provided as part of the API with methods like onClick etc. In such cases lambdas could be useful to reduce the code.
Also with Java 8, streams were introduced and lambdas could be passed to filter/map the stream elements. Stream allow more readable code than traditional for loop / if-else in most cases.

Null-safe method chaining with Optional

Guava's Optional pattern is great, as it helps remove the ambiguity with null. The transform method is very helpful for creating null-safe method chains when the first part of the chain may be absent, but isn't useful when other parts of the chain are absent.
This question is related to Guava Optional type, when transformation returns another Optional, which asks essentially the same question but for a different use case which I think may not be the intended use of Optional (handling errors).
Consider a method Optional<Book> findBook(String id). findBook(id).transform(Book.getName) works as expected. If there is no book found we get an Absent<String>, if there is a book found we get Present<String>.
In the common case where intermediate methods may return null/absent(), there does not seem to be an elegant way to chain the calls. For example, assume that Book has a method Optional<Publisher> getPublisher(), and we would like to get all the books published by the publisher of a book. The natural syntax would seem to be findBook(id).transform(Book.getPublisher).transform(Publisher.getPublishedBooks), however this will fail because the transform(Publisher.getPublishedBooks) call will actually return an Optional<Optional<Publisher>>.
It seems fairly reasonable to have a transform()-like method on Optional that would accept a function which returns an Optional. It would act exactly like the current implementation except that it simply would not wrap the result of the function in an Optional. The implementation (for Present) might read:
public abstract <V> Optional<V> optionalTransform(Function<? super T, Optional<V>> function) {
return function.apply(reference);
}
The implementation for Absent is unchanged from transform:
public abstract <V> Optional<V> optionalTransform(Function<? super T, Optional<V>> function) {
checkNotNull(function);
return Optional.absent();
}
It would also be nice if there were a way to handle methods that return null as opposed to Optional for working with legacy objects. Such a method would be like transform but simply call Optional.fromNullable on the result of the function.
I'm curious if anyone else has run into this annoyance and found nice workarounds (which don't involve writing your own Optional class). I'd also love to hear from the Guava team or be pointed to discussions related to the issue (I didn't find any in my searching).
You are looking for some Monad, but Guava's Optional (as opposite to for example Scala's Option) is just a Functor.
What the hell is a Functor?!
Functor and Monad are a kind of box, a context that wraps some value.
Functor containing some value of type A knows how to apply function A => B and put the result back into Functor. For example: get something out of Optional, transform, and wrap back into Optional.
In functional programming languages such method is often named 'map'.
Mona.. what?
Monad is almost the same thing as Functor, except that it consumes function returning value wrapped in Monad (A => Monad, for example Int => Optional).
This magic Monad's method is often called 'flatMap'.
Here you can find really awesome explanations for fundamental FP terms: http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
Functors & Monads are coming!
Optional from Java 8 can be classified as both Functor (http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#map-java.util.function.Function-) and Monad (http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#flatMap-java.util.function.Function-).
Nice mon(ad)olog, Marcin, but how can I solve my particular problem?
I'm currently working on a project that uses Java 6 and yesterday I write some helper class, called 'Optionals', which saved me a lot of time.
It provides some helper method, that allows me to turn Optional into Monads (flatMap).
Here is the code: https://gist.github.com/mkubala/046ae20946411f80ac52
Because my project's codebase still uses nulls as a return value, I introduced Optionals.lift(Function), which can be used to wrapping results into the Optional.
Why lifting result into Optional?
To avoid situation when function passed into transform might return null and whole expression would return "present of null" (which by the way is not possible with Guava's Optional, because of this postcondition -> see line #71 of https://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/base/Present.java?r=0823847e96b1d082e94f06327cf218e418fe2228#71).
Couple of examples
Let's assume that findEntity() returns an Optional and Entity.getDecimalField(..) may return BigDecimal or null:
Optional<BigDecimal> maybeDecimalValue = Optionals.flatMap(
findEntity(),
new Function<Entity, Optional<BigDecimal>> () {
#Override
public Optional<BigDecimal> apply(Entity input) {
return Optional.fromNullable(input.getDecimalField(..));
}
}
);
Yet another example, assuming that I already have some Function, which extracts decimal values from Entities, and may return nulls:
Function<Entity, Decimal> extractDecimal = .. // extracts decimal value or null
Optional<BigDecimal> maybeDecimalValue = Optionals.flatMap(
findEntity(),
Optionals.lift(extractDecimal)
);
And last, but not least - your use case as an example:
Optional<Publisher> maybePublisher = Optionals.flatMap(findBook(id), Optionals.lift(Book.getPublisher));
// Assuming that getPublishedBooks may return null..
Optional<List<Book>> maybePublishedBooks = Optionals.flatMap(maybePublisher, Optionals.lift(Publisher.getPublishedBooks));
// ..or simpler, in case when getPublishedBooks never returns null
Optional<List<Book>> maybePublishedBooks2 = maybePublisher.transform(Publisher.getPublishedBooks);
// as a one-liner:
Optionals.flatMap(maybePublisher, Optionals.lift(Publisher.getPublishedBooks)).transform(Publisher.getPublishedBooks);
You probably figured that out, but you could add .or(Optional.absent) after every transformation that returns Optional (in your case after .transform(Book.getPublisher) reducing Optional<Optional<T>> to Optional<T>:
Optional<List<Book>> publishedBooks = findBook(id).transform(Book.getPublisher).
or(Optional.absent()).transform(Publisher.getPublishedBooks);
Unfortunately, the type of Optional.absent cannot be inferred here, so the code actually becomes:
Optional<List<Book>> publishedBooks = book.transform(Book.getPublisher).
or(Optional.<Publisher> absent()).transform(Publisher.getPublishedBoooks);
Not too convenient but there doesn't seem to be any other way.

Java: "implements operator?"

I have some functions containing much calculation stuff. All calculations are done using operators [], *, /, + and -. Eyerything else is loops and tests. So those same functions "could" be used on any type that implements those operators, eg. double, float, int, long etc. For performance reasons, i just use basic types. Is there any way to do this generic?
Also – for perfomace reasons, i dont want to cast floats and ints to double and calc in double. i want to calc in int on int, in float on floats and in double on doubles. I just dont want to write 3 times the same code that just differs in the type used.
For example, guess you have
public double doSomething(double a, double b)
{
return a * b + 1;
}
of course, actual fn do much more than this.
I think a trick would be something like
public T doSomething(T a, T b)
{
return staticAdd(staticMul(a,b),1);
}
…and define basic operations as static fn for all used types. But as those are not inlined, this would add another fn-call.
Is there a way in java to do some thing like
<T implements +, implements -> …?
The suggestion you give for defining methods like staticAdd isn't as bad as you might think at first. One of the things HotSpot will do for you (when it's in the mood) is inline code. If you define such functions for the types you're concerned with, you may well get decent performance.
That said, you're still going to be dealing with autoboxing, since you can't genericize methods on primitives. If the performance is truly that critical, you may be stuck writing multiple method signatures.
Consider, though, that it's rumored that primitives may go away entirely in future versions of Java/the JVM. Of course the penalty for dealing with the wrapped types isn't nil, but it's approaching negligible in many applications.
The only operator overloading Java supports is + as stringify and concatenate. If you want this, you want one of the non-Java JVM languages.
But, recall the old joke: “If you want LISP, you know where to find it.”
Simply put, it is not possible. Java being statically typed, operations cannot be abstracted from the underlying type.
For example, you cannot have arithmetic operations defined on Number so as to abstract away the underlying type (Short, Integer, etc..).
Short answer NO, there isn't a way to do this. The type system isn't strong enough to express this sort of thing in Java.
Also since primitive data types are not supported in Generics you may have to use the wrapper classes like Integers, Float etc., Hackiest way to accomplish using Wrapper class would be as below,
public class Calculator<T extends Number> {
T add(T a, T b) {
if (a instanceof Double) {
return (T) Double.valueOf((a.doubleValue() + b.doubleValue()));
} else if (a instanceof Float) {
return (T) Float.valueOf(((a.floatValue() + b.floatValue())));
} else if (a instanceof Integer) {
return (T) Integer.valueOf(((a.intValue() + b.intValue())));
}
throw new IllegalArgumentException();
}
}
You can call the same as below.
Calculator<Double> c1 = new Calculator<Double>();
mc.add(1.0, 1.1);
Calculator<Integer> c1 = new Calculator<Integer>();
mc.add(1, 2);

Monads with Java 8

In the interests of helping to understand what a monad is, can someone provide an example using java ? Are they possible ?
Lambda expressions are possible using java if you download the pre-release lambda compatible JDK8 from here http://jdk8.java.net/lambda/
An example of a lambda using this JDK is shown below, can someone provide a comparably simple monad ?
public interface TransformService {
int[] transform(List<Integer> inputs);
}
public static void main(String ars[]) {
TransformService transformService = (inputs) -> {
int[] ints = new int[inputs.size()];
int i = 0;
for (Integer element : inputs) {
ints[i] = element;
}
return ints;
};
List<Integer> inputs = new ArrayList<Integer>(5) {{
add(10);
add(10);
}};
int[] results = transformService.transform(inputs);
}
Just FYI:
The proposed JDK8 Optional class does satisfy the three Monad laws. Here's a gist demonstrating that.
All it takes be a Monad is to provide two functions which conform to three laws.
The two functions:
Place a value into monadic context
Haskell's Maybe: return / Just
Scala's Option: Some
Functional Java's Option: Option.some
JDK8's Optional: Optional.of
Apply a function in monadic context
Haskell's Maybe: >>= (aka bind)
Scala's Option: flatMap
Functional Java's Option: flatMap
JDK8's Optional: flatMap
Please see the above gist for a java demonstration of the three laws.
NOTE: One of the key things to understand is the signature of the function to apply in monadic context: it takes the raw value type, and returns the monadic type.
In other words, if you have an instance of Optional<Integer>, the functions you can pass to its flatMap method will have the signature (Integer) -> Optional<U>, where U is a value type which does not have to be Integer, for example String:
Optional<Integer> maybeInteger = Optional.of(1);
// Function that takes Integer and returns Optional<Integer>
Optional<Integer> maybePlusOne = maybeInteger.flatMap(n -> Optional.of(n + 1));
// Function that takes Integer and returns Optional<String>
Optional<String> maybeString = maybePlusOne.flatMap(n -> Optional.of(n.toString));
You don't need any sort of Monad Interface to code this way, or to think this way. In Scala, you don't code to a Monad Interface (unless you are using Scalaz library...). It appears that JDK8 will empower Java folks to use this style of chained monadic computations as well.
Hope this is helpful!
Update: Blogged about this here.
Java 8 will have lambdas; monads are a whole different story. They are hard enough to explain in functional programming (as evidenced by the large number of tutorials on the subject in Haskell and Scala).
Monads are a typical feature of statically typed functional languages. To describe them in OO-speak, you could imagine a Monad interface. Classes that implement Monad would then be called 'monadic', provided that in implementing Monad the implementation obeys what are known as the 'monad laws'. The language then provides some syntactic sugar that makes working with instances of the Monad class interesting.
Now Iterable in Java has nothing to do with monads, but as a example of a type that the Java compiler treats specially (the foreach syntax that came with Java 5), consider this:
Iterable<Something> things = getThings(..);
for (Something s: things) { /* do something with s */ }
So while we could have used Iterable's Iterator methods (hasNext and company) in an old-style for loop, Java grants us this syntactic sugar as a special case.
So just as classes that implement Iterable and Iterator must obey the Iterator laws (Example: hasNext must return false if there is no next element) to be useful in foreach syntax - there would exist several monadic classes that would be useful with a corresponding do notation (as it is called in Haskell) or Scala's for notation.
So -
What are good examples of monadic classes?
What would syntactic sugar for dealing with them look like?
In Java 8, I don't know - I am aware of the lambda notation but I am not aware of other special syntactic sugar, so I'll have to give you an example in another language.
Monads often serve as container classes (Lists are an example). Java already has java.util.List which is obviously not monadic, but here is Scala's:
val nums = List(1, 2, 3, 4)
val strs = List("hello", "hola")
val result = for { // Iterate both lists, return a resulting list that contains
// pairs of (Int, String) s.t the string size is same as the num.
n <- nums
s <- strs if n == s.length
} yield (n, s)
// result will be List((4, "hola"))
// A list of exactly one element, the pair (4, "hola")
Which is (roughly) syntactic sugar for:
val nums = List(1, 2, 3, 4)
val strs = List("hello", "hola")
val results =
nums.flatMap( n =>
strs.filter(s => s.size == n). // same as the 'if'
map(s => (n, s)) // Same as the 'yield'
)
// flatMap takes a lambda as an argument, as do filter and map
//
This shows a feature of Scala where monads are exploited to provide list comprehensions.
So a List in Scala is a monad, because it obeys Scala's monad laws, which stipulate that all monad implementations must have conforming flatMap, map and filter methods (if you are interested in the laws, the "Monads are Elephants" blog entry has the best description I've found so far). And, as you can see, lambdas (and HoF) are absolutely necessary but not sufficient to make this kind of thing useful in a practical way.
There's a bunch of useful monads besides the container-ish ones as well. They have all kinds of applications. My favorite must be the Option monad in Scala (the Maybe monad in Haskell), which is a wrapper type which brings about null safety: the Scala API page for the Option monad has a very simple example usage: http://www.scala-lang.org/api/current/scala/Option.html
In Haskell, monads are useful in representing IO, as a way of working around the fact that non-monadic Haskell code has indeterminate order of execution.
Having lambdas is a first small step into the functional programming world; monads
require both the monad convention and a large enough set of usable monadic types, as well as syntactic sugar to make working with them fun and useful.
Since Scala is arguably the language closest to Java that also allows (monadic) Functional Programming, do look at this Monad tutorial for Scala if you are (still) interested:
http://james-iry.blogspot.jp/2007/09/monads-are-elephants-part-1.html
A cursory googling shows that there is at least one attempt to do this in Java: https://github.com/RichardWarburton/Monads-in-Java -
Sadly, explaining monads in Java (even with lambdas) is as hard as explaining full-blown Object oriented programming in ANSI C (instead of C++ or Java).
Even though monads can be implemented in Java, any computation involving them is doomed to become a messy mix of generics and curly braces.
I'd say that Java is definitely not the language to use in order to illustrate their working or to study their meaning and essence. For this purpose it is far better to use JavaScript or to pay some extra price and learn Haskell.
Anyway, I am signaling you that I just implemented a state monad using the new Java 8 lambdas. It's definitely a pet project, but it works on a non-trivial test case.
You may find it presented at my blog, but I'll give you some details here.
A state monad is basically a function from a state to a pair (state,content). You usually give the state a generic type S and the content a generic type A.
Because Java does not have pairs we have to model them using a specific class, let's call it Scp (state-content pair), which in this case will have generic type Scp<S,A> and a constructor new Scp<S,A>(S state,A content). After doing that we can say that the monadic function will have type
java.util.function.Function<S,Scp<S,A>>
which is a #FunctionalInterface. That's to say that its one and only implementation method can be invoked without naming it, passing a lambda expression with the right type.
The class StateMonad<S,A> is mainly a wrapper around the function. Its constructor may be invoked e.g. with
new StateMonad<Integer, String>(n -> new Scp<Integer, String>(n + 1, "value"));
The state monad stores the function as an instance variable. It is then necessary to provide a public method to access it and feed it the state. I decided to call it s2scp ("state to state-content pair").
To complete the definition of the monad you have to provide a unit (aka return) and a bind (aka flatMap) method. Personally I prefer to specify unit as static, whereas bind is an instance member.
In the case of the state monad, unit gotta be the following:
public static <S, A> StateMonad<S, A> unit(A a) {
return new StateMonad<S, A>((S s) -> new Scp<S, A>(s, a));
}
while bind (as instance member) is:
public <B> StateMonad<S, B> bind(final Function<A, StateMonad<S, B>> famb) {
return new StateMonad<S, B>((S s) -> {
Scp<S, A> currentPair = this.s2scp(s);
return famb(currentPair.content).s2scp(currentPair.state);
});
}
You notice that bind must introduce a generic type B, because it is the mechanism that allows the chaining of heterogeneous state monads and gives this and any other monad the remarkable capability to move the computation from type to type.
I'd stop here with the Java code. The complex stuff is in the GitHub project. Compared to previous Java versions, lambdas remove a lot of curly braces, but the syntax is still pretty convoluted.
Just as an aside, I'm showing how similar state monad code may be written in other mainstream languages. In the case of Scala, bind (which in that case must be called flatMap) reads like
def flatMap[A, B](famb: A => State[S, B]) = new State[S, B]((s: S) => {
val (ss: S, aa: A) = this.s2scp(s)
famb(aa).s2scp(ss)
})
whereas the bind in JavaScript is my favorite; 100% functional, lean and mean but -of course- typeless:
var bind = function(famb){
return state(function(s) {
var a = this(s);
return famb(a.value)(a.state);
});
};
<shameless>
I am cutting a few corners here, but if you are interested in the details you will find them on my WP blog.</shameless>
Here's the thing about monads which is hard to grasp: monads are a
pattern, not a specific type. Monads are a shape, they are an abstract
interface (not in the Java sense) more than they are a concrete data
structure. As a result, any example-driven tutorial is doomed to
incompleteness and failure.
[...]
The only way to understand monads is to see them for what they are: a mathematical construct.
Monads are not metaphors by Daniel Spiewak
Monads in Java SE 8
List monad
interface Person {
List<Person> parents();
default List<Person> greatGrandParents1() {
List<Person> list = new ArrayList<>();
for (Person p : parents()) {
for (Person gp : p.parents()) {
for (Person ggp : p.parents()) {
list.add(ggp);
}
}
}
return list;
}
// <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
default List<Person> greatGrandParents2() {
return Stream.of(parents())
.flatMap(p -> Stream.of(p.parents()))
.flatMap(gp -> Stream.of(gp.parents()))
.collect(toList());
}
}
Maybe monad
interface Person {
String firstName();
String middleName();
String lastName();
default String fullName1() {
String fName = firstName();
if (fName != null) {
String mName = middleName();
if (mName != null) {
String lName = lastName();
if (lName != null) {
return fName + " " + mName + " " + lName;
}
}
}
return null;
}
// <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
default Optional<String> fullName2() {
return Optional.ofNullable(firstName())
.flatMap(fName -> Optional.ofNullable(middleName())
.flatMap(mName -> Optional.ofNullable(lastName())
.flatMap(lName -> Optional.of(fName + " " + mName + " " + lName))));
}
}
Monad is a generic pattern for nested control flow encapsulation.
I.e. a way to create reusable components from nested imperative idioms.
Important to understand that a monad is not just a generic wrapper class with a flat map operation.
For example, ArrayList with a flatMap method won't be a monad.
Because monad laws prohibit side effects.
Monad is a formalism. It describes the structure, regardless of content or meaning.
People struggle with relating to meaningless (abstract) things.
So they come up with metaphors which are not monads.
See also:
conversation between Erik Meijer and Gilad Bracha.
the only way to understand monads is by writing a bunch of combinator libraries, noticing the resulting duplication, and then discovering for yourself that monads let you factor out this duplication. In discovering this, everyone builds some intuition for what a monad is… but this intuition isn’t the sort of thing that you can communicate to someone else directly – it seems everyone has to go through the same experience of generalizing to monads from some concrete examples of combinator libraries. however
here i found some materials to learn Mondas.
hope to be useful for you too.
codecommit
james-iry.blogspot
debasishg.blogspot
This blog post gives a step-by-step example of how you might implement a Monad type (interface) in Java and then use it to define the Maybe monad, as a practical application.
This post explains that there is one monad built into the Java language, emphasising the point that monads are more common than many programmers may think and that coders often inadvertently reinvent them.
Despite all controversy about Optional satisfying, or not, the Monad laws, I usually like to look at Stream, Optional and CompletableFuture in the same way. In truth, all them provide a flatMap() and that is all I care and let me embrace the "the tasteful composition of side effects" (cited by Erik Meijer). So we may have corresponding Stream, Optional and CompletableFuture in the following way:
Regarding Monads, I usually simplify it only thinking on flatMap()(from "Principles of Reactive Programming" course by Erik Meijer):
A diagram for the "Optional" Monad in Java.
Your task: Perform operations on the "Actuals" (left side) transforming elements of type T union null to type U union null using the function in the light blue box (the light blue box function). Just one box is shown here, but there may be a chain of the light blue boxes (thus proceeding from type U union null to type V _union null to type W union null etc.)
Practically, this will cause you to worry about null values appearing in the function application chain. Ugly!
Solution: Wrap your T into an Optional<T> using the light green box functions, moving to the "Optionals" (right side). Here, transform elements of type Optional<T> to type Optional<U> using the red box function. Mirroring the application of functions to the "Actuals", there may be several red box functions to be be chained (thus proceeding from type Optional<U> to Optional<V> then to Optional<W> etc.). In the end, move back from the "Optionals" to the "Actuals" through one of the dark green box functions.
No worrying about null values anymore. Implementationwise, there will always be an Optional<U>, which may or may not be empty. You can chain the calls to to the red box functions without null checks.
The key point: The red box functions are not implemented individually and directly. Instead, they are obtained from the blue box functions (whichever have been implemented and are available, generally the light blue ones) by using either the map or the flatMap higher-order functions.
The grey boxes provide additional support functionality.
Simples.
I like to think of monads in slighlty more mathematical (but still informal) fashion. After that I will explain the relationship to one of Java 8's monads CompletableFuture.
First of all, a monad M is a functor. That is, it transforms a type into another type: If X is a type (e.g. String) then we have another type M<X> (e.g. List<String>). Moreover, if we have a transformation/function X -> Y of types, we should get a function M<X> -> M<Y>.
But there is more data to such a monad. We have a so-called unit which is a function X -> M<X> for each type X. In other words, each object of X can be wrapped in a natural way into the monad.
The most characteristic data of a monad, however, is it's product: a function M<M<X>> -> M<X> for each type X.
All of these data should satisfy some axioms like functoriality, associativity, unit laws, but I won't go into detail here and it also doesn't matter for practical usage.
We can now deduce another operation for monads, which is often used as an equivalent definition for monads, the binding operation: A value/object in M<X> can be bound with a function X -> M<Y> to yield another value in M<Y>. How do we achieve this? Well, first we apply functoriality to the function to obtain a function M<X> -> M<M<Y>>. Next we apply the monadic product to the target to obtain a function M<X> -> M<Y>. Now we can plug in the value of M<X> to obtain a value in M<Y> as desired. This binding operation is used to chain several monadic operations together.
Now lets come to the CompletableFuture example, i.e. CompletableFuture = M. Think of an object of CompletableFuture<MyData> as some computation that's performed asynchronously and which yields an object of MyData as a result some time in the future. What are the monadic operations here?
functoriality is realized with the method thenApply: first the computation is performed and as soon as the result is available, the function which is given to thenApply is applied to transform the result into another type
the monadic unit is realized with the method completedFuture: as the documentation tells, the resulting computation is already finished and yields the given value at once
the monadic product is not realized by a function, but the binding operation below is equivalent to it (together with functoriality) and its semantic meaning is simply the following: given a computation of type CompletableFuture<CompletableFuture<MyData>> that computation asynchronously yields another computation in CompletableFuture<MyData> which in turn yields some value in MyData later on, so performing both computations on after the other yields one computation in total
the resulting binding operation is realized by the method thenCompose
As you see, computations can now be wrapped up in a special context, namely asynchronicity. The general monadic structures enable us to chain such computations in the given context. CompletableFuture is for example used in the Lagom framework to easily construct highly asynchronous request handlers which are transparently backed up by efficient thread pools (instead of handling each request by a dedicated thread).
Haskell monads is an interface which specify rules to convert “datatype that is wrapped in another datatype” to another “datatype that is wrapped in another or same datatype”; the conversion steps is specified by a function you define with a format.
The function format takes a datatype and return “datatype that is wrapped in another datatype”. You can specify operations/ calculations during conversion e.g. multiply or lookup something.
It is so difficult to understand because of the nested abstraction. It is so abstracted so that you can reuse the rules to convert datatype in a datatype without custom programming to unwrap the first “ datatype that is wrapped in another datatype” before putting the data to your specified function; Optional with some datatype is an example of “datatype in a datatype”.
The specified function is any lambda confirming the format.
You don’t need to fully understand it; you will write your own reusable interface to solve similar problem. Monad is just exist because some mathematicians already hit and resolve that problem, and create monad for you to reuse. But due to its abstraction, it is difficult to learn and reuse in the first place.
In other words, e.g. Optional is a wrapper class, but some data is wrapped , some not, some function take wrapped data type but some don’t, return type can be of type wrapped or not. To chain calling mixture of function which may wrap or not in parameter/return types, you either do your own custom wrap/unwrap or reuse pattern of functor / applicative / monad to deal with all those wrapped/unwrapped combinations of chained function call. Every time u try to put optional to a method that only accept plain value and return optional, the steps are what monad does.

Categories