28
Poor man’s FP How to change your java code in a way you never thought about

Poor man's functional programming

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: Poor man's functional programming

Poor man’s FP

How to change your java code in a way you never thought

about

Page 2: Poor man's functional programming

Dmitry Lebedev

Page 3: Poor man's functional programming

Agile Latvia & LDN

Page 4: Poor man's functional programming

Agile Latvia & LDN

Page 5: Poor man's functional programming

Functional Programming

• Higher order functions• Pure functions• Recursion• Non-strict evaluation• Currying

Page 6: Poor man's functional programming

Higher order functions

foo = Proc.new { |prompt| prompt.echo = false }new_pass = ask("Enter your new password: ", &foo)

Page 7: Poor man's functional programming

Pure Functions

foo = Proc.new { |x| x*x+(x+20) }

Page 8: Poor man's functional programming

Recursion

def fib(n) return n if (0..1).include? n fib(n-1) + fib(n-2) if n > 1end

Page 9: Poor man's functional programming

Non-strict evaluation

print length([2+1, 3*2, 1/0, 5-4])

Page 10: Poor man's functional programming

Currying

plus = lambda {|a,b| a + b} plus.(3,5) #=> 8 plus_one = plus.curry.(1) plus_one.(5) #=> 6plus_one.(11) #=> 12

Page 11: Poor man's functional programming

Java 8?import java.awt.Button;import java.awt.event.ActionEvent;import java.awt.event.ActionListener; public class Java8 { public static void main(String[] args) { Button myButton = new Button(); myButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { System.out.println(ae.getSource()); } }); }}

Page 12: Poor man's functional programming

Java 8?

import java.awt.Button;import java.awt.event.ActionEvent; public class Java8 { public static void main(String[] args) {

Button myButton = new Button(); myButton.addActionListener((ActionEvent ae) -

> { System.out.println(ae.getSource()); }); }}

Page 13: Poor man's functional programming

Java 8?

import java.awt.Button; public class Java8 { public static void main(String[] args) { Button myButton = new Button(); myButton.addActionListener(ae -> {System.out.println(ae.getSource());} ); }}

Page 14: Poor man's functional programming

Still living under Java 6?

Languages• Scala• Clojure

Libraries• Guava• LambdaJ• Functional Java

Page 15: Poor man's functional programming

Guava

• Function<A, B>, which has the single method B apply(A input). Instances of Function are generally expected to be referentially transparent -- no side effects -- and to be consistent with equals, that is, a.equals(b) implies that function.apply(a).equals(function.apply(b)).

• Predicate<T>, which has the single method boolean apply(T input). Instances of Predicate are generally expected to be side-effect-free and consistent with equals.

Page 16: Poor man's functional programming

Guava

List converted = ImmutableList.copyOf( Iterables.transform( userDTOs, new Function(){ public User apply( UserDTO input ){ return new User( input.name, input.id ); }}));

Page 17: Poor man's functional programming

LambdaJ

Person me = new Person("Mario", "Fusco", 35);Person luca = new Person("Luca", "Marrocco", 29);Person biagio = new Person("Biagio", "Beatrice", 39);Person celestino = new Person("Celestino", "Bellone", 29);List<Person> meAndMyFriends = asList(me, luca, biagio, celestino);List<Person> oldFriends = filter(having(on(Person.class).getAge(), greaterThan(30)), meAndMyFriends);

Page 18: Poor man's functional programming

FunctionalJavaimport fj.data.Array;import static fj.data.Array.array;import static fj.Show.arrayShow;import static fj.Show.intShow;import static fj.function.Integers.even;

public final class Array_filter { public static void main(final String[] args) { final Array<Integer> a = array(97, 44, 67, 3, 22, 90, 1, 77, 98, 1078, 6, 64, 6, 79, 42); final Array<Integer> b = a.filter(even); arrayShow(intShow).println(b); // {44,22,90,98,1078,6,64,6,42} }}

Page 19: Poor man's functional programming

Invention of Own Bicycle

Page 20: Poor man's functional programming

First Attempt

public static <T> void forEach(Collection<T> list, Procedure<T> proc) {

for (T object : list) {proc.invoke(object);

}}

Page 21: Poor man's functional programming

Another try

public static <T, E> Collection<E> each(Collection<T> list, Function<T, E> function) {

ArrayList<E> result = new ArrayList<E>();for (T object : list) {

result.add(function.apply(object));}return result;

}

Page 22: Poor man's functional programming

Use Caseresult.addAll(

each(imageList, new Function<S3ObjectSummary, String>({

@Override

public String apply(@NullableS3ObjectSummary input)

{return siteURL +

input.getKey();}

}));

Page 23: Poor man's functional programming

Let’s complicate!

public interface MapFunction<T, K, V> { Pair<K,V> proceed(T key);}

Page 24: Poor man's functional programming

Let’s complicate!public static <T, K, V> Map<K, V> map(Collection<T> list,

MapFunction<T, K, V> function) {

Map<K, V> result = new HashMap<K, V>();for (T object : list) {

Pair<K, V> pair = function.proceed(object);result.put(pair.getKey(),

pair.getValue());}return result;

}

Page 25: Poor man's functional programming

Let’s complicate!...List<Future> fs = new ArrayList<Future>(list.size());for (final T object : list) {

fs.add(exec.submit(new Callable() {@Overridepublic Object call() throws Exception {

return function.proceed(object);}

}));}...

Page 26: Poor man's functional programming

Let’s complicate!

...for (Future ft : fs) {

Pair<K, V> pair = (Pair<K, V>) ft.get();result.put(pair.getKey(), pair.getValue());

}...

Page 27: Poor man's functional programming

Question?

Page 28: Poor man's functional programming

The End