The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

Please post errors in the published version of Functional Programming in Java here. If necessary, we'll publish a comprehensive list for everyone's convenience. Thank you!

The listing 2.2 on page 52 appears to have a few issues with it.

1. The definition of "compose" appears to be that the current/this/first function is to be applied to the second function. And the corollary: "andThen" appears to be defined such that the second function is to be applied to the current/this/first function.
The following methods adhere to this understanding:

The following methods are reversed from this understanding:

- compose()
- andThen()

2. If the body of compose() and andThen() are expanded (that is, change y.compose(x) into y.apply(x.apply(z))), it seems that there really isn't a difference between the compose()/andThen() set and the higherCompose()/higherAndThen() set [other than issue #1 above]. Both sets return the same values. Am I missing something?

447791 wrote:The listing 2.2 on page 52 appears to have a few issues with it.

1. The definition of "compose" appears to be that the current/this/first function is to be applied to the second function. And the corollary: "andThen" appears to be defined such that the second function is to be applied to the current/this/first function.
The following methods adhere to this understanding:

The following methods are reversed from this understanding:

- compose()
- andThen()

2. If the body of compose() and andThen() are expanded (that is, change y.compose(x) into y.apply(x.apply(z))), it seems that there really isn't a difference between the compose()/andThen() set and the higherCompose()/higherAndThen() set [other than issue #1 above]. Both sets return the same values. Am I missing something?

First of all, I am very sorry for not having answered in time. In fact I never received the notification, and I just saw your message more than four months later!

You are right about compose() and andThen() having their argument inverted compared to the corresponding methods or the higherCompose and higherAndThen functions. This is only a question of convention. The convention is that the composition of f and g is g(f(x)), so compose() and andThen() are indeed correct, and the others are wrong. Using defferent types would show this:

public static void main(String... args) {
Function<Integer, Double> f = x -> x * 3.0;
Function<Double, Long> g = x -> (long) (x + 3.0);
//System.out.println(f.compose(g).apply(6)); // does not compile
System.out.println(g.compose(f).apply(6));
System.out.println(Function.<Integer, Double, Long>compose().apply(f).apply(g).apply(6));
//System.out.println(Function.<Double, ???, ???>compose().apply(g).apply(f).apply(6)); // does not compile
System.out.println(Function.<Integer, Double, Long>higherCompose().apply(g).apply(f).apply(6));
System.out.println(Function.<Integer, Double, Long>higherAndThen().apply(f).apply(g).apply(6));
System.out.println(g.apply(f.apply(6)));
}

Regarding the second point, you're not missing anything. higherCompose and higherAndThen are just a mean to define composition while not using the compose and andThen methods defined in the interface. They are in fact the only higher order functions that are necessary.

Both of your implementations may be considered ok since they give the correct result. However, none is the solution of exercise 3.8 since they are not recursive, but iterative. A recursive function is a function calling itself as part of a further computation. A corecursive function is a function calling itself as the last operation it does (hence not as part of a further computation). The solution of exercise 3.8 is:

public static <T, U> U foldRight(List<T> ts, U identity, Function<T, Function<U, U>> f) {
return ts.isEmpty()
? identity
: f.apply(head(ts)).apply(foldRight(tail(ts), identity, f));
}

Here, you see that the function calls itself and then calls the result of applying f to head(ts), which is a function, to the result of the recursive call.

A corecursive function example could be:

public static <T, U> U foldLeft(List<T> ts, U identity, Function<U, Function<T, U>> f) {
return ts.isEmpty()
? identity
: foldLeft(tail(ts), f.apply(identity).apply(head(ts)), f);
}

Here, the "recursive" call to foldLeft is the last thing the method does. The result is not part of a further computation. So it is a corecursive function (also called "tail recursive", which is not very well chosen.)

foldright may be implemented through iteration (as you did), or through corecursion (applying foldLeft after having reversed the list), but this is not equivalent to a recursive implementation. These are different implementations giving the same result (at least for short lists!).