Functional Programming in Java

Getting Started

Created by Mark Perry, @mprry, G+, Blog, LinkedIn, GitHub, maperry78@yahoo.com.au

Goals

  • Write programs by combining pure functions
  • Learn by immersion with examples
  • Higher order functions

Example

  • See GettingStarted.java
  • Effect pushed to outer shell
  • Program is RT, since main is not called from program
  • Note immutable values

Loops


// imperative factorial
static int factorial(int n) {
    int i = n;
    int result = 1;
    while (i > 1) {
        result = result * i;
        i = i - 1;
    }
    return result;
}
                    

Loops Without Mutation

  • Recursive calls implement loop
  • Recursive call in tail position
  • Tail call optimisation (TCO)

static int factorial(int n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}
// factorial(5) = 5 * factorial(4) = 5 * (4 * factorial(3)) = ...

// tail call version
static int fact(int n) {
    return fact(n, 1);
}
static int fact(int n, int acc) {
    return (n <= 1) ? acc : fact(n - 1, n * acc);
}
// fact(5, 1) = fact(4, 5 * 1) = fact(3, 4 * 5) = ...
					

Functions

  • Instantiate functions with lambda expression

public interface F<A, B> {
    B f(A a);
}

void func(F<Integer, Integer> f) {...}

// Java 8
func(x -> x + 1);

// Java 7
func(new F<Integer, Integer>(){
    public Integer f(Integer i) {
        return i + 1;
    }
});

Higher Order Functions


static int abs(int x) { ... }

static int factorial(int n) { ... }

static String formatResult(String name, int n, F<Integer, Integer> f) {
	String msg = "The %s of %d is %d.";
	return msg.format(name, n, f.f(n));
}

public static void main(String [] args) {
	out.println(formatResult("absolute value", -42, x -> abs(x)))
	out.println(formatResult("factorial", 7, ClassName::factorial))
}
					

Anonymous Functions


public static void main(String [] args) {
	out.println(formatResult("increment1", 7, (int x) -> x + 1));
	out.println(formatResult("increment2", 7, (x) -> x + 1));
	out.println(formatResult("increment3", 7, x -> x + 1);
	out.println(formatResult("increment4", 7, x -> {
	    int r = x + 1;
		    return r;
	}));
}
					

Polymorphic Functions

  • Previously monomorphic
  • Abstract over any type
  • Takes a list of type parameters/variables

static <A> boolean isSorted(List<A> as, F2<A, A, Boolean> f) {...}

static <A, B> B fold(List<A> as, F2<B, A, B> f, B b) {...}

static <A, B, C> F<B, C> partial1(A a, F2<A, B, C> f) {...}

static <A, B, C> F<A, F<B, C>> curry(F2<A, B, C> f) {...}

static <A, B, C> F<A, C> andThen(F<A, B> f, F<B, C> g) {...}
					

Summary

  • Learn basic FP concepts
  • Some simple Java
  • Recursion
  • Higher Order Functions
  • Polymorphism

Afterword

Functional Programming in Scala, Chiusano and Bjarnason, Chapter 2, Getting Started

Created by Mark Perry, @mprry, G+, Blog, LinkedIn, GitHub, maperry78@yahoo.com.au