An introduction to the JDK8 functional model for Groovy developers.
JDK 8 FunctionalProgramming…For Groovy Developers
View Slide
John Engelman• @johnrengelman• github.com/johnrengelman• ratpack.io• objectpartners.com/category/blog
Caveats• Scala• Clojure• Erlang• Haskell
…Big pile of Salt
Questions?
public static TransformablePublisher stream(Publisher publisher) {return Streams.transformable(subscriber -> require().streamSubscribe((handle) ->publisher.subscribe(new Subscriber() {@Overridepublic void onSubscribe(final Subscription subscription) {handle.event(() ->subscriber.onSubscribe(subscription));}@Overridepublic void onNext(final T element) {handle.event(() -> subscriber.onNext(element));}@Overridepublic void onComplete() {handle.complete(subscriber::onComplete);}@Overridepublic void onError(final Throwable cause) {handle.complete(() -> subscriber.onError(cause));}})));}
java.util.functionhttps://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
JDK8 Functional InterfacesConceptually, a functional interface has exactlyone abstract method.- https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html
public interface Supplier {T get();}
Supplier supply() {return (() -> {return new Foo();});}lambda expressionparameters listbody
Supplier supply() {return (() -> new Foo());}implicit returnwhere have we seenthat before?
Supplier supply() {return Foo::new}method handle
Supplier supply() {return {new Foo()}}Supplier supply() {//http://mrhaki.blogspot.com/2015/03/groovy-goodness-use-constructor-as.htmFoo.metaClass.&invokeConstructor}
public interface Consumer {void accept(T t);}
Consumer consume() {return (val -> System.out.println(val));}Consumer consumeMethod() {return System.out::println;}
Consumer consume() {return { val ->println val.name}}Consumer consumeMethod() {this.&println}
public interface Function {R appy(T t);}
Function convert() {return (foo -> {return new Bar(foo.name);});}Function convertMethod() {return Bar::new;}
Function convert() {return { foo ->new Bar(foo.name)}}Function convertMethod() {Bar.metaClass.&invokeConstructor}
public interface BiConsumer {void accept(T t, U u);}public interface BiFunction {R apply(T t, U u);}
Where is TriFunction?
• BiConsumer• BiFunction• BinaryOperator• BiPredicate• BooleanSupplier• Consumer• DoubleBinaryOperator• DoubleConsumer• DoubleFunction• DoublePredicate• DoubleSupplier• DoubleToIntFunction• DoubleToLongFunction• DoubleUnaryOperator• Function• IntBinaryOperator• IntConsumer• IntFunction• IntPredicate• IntSupplier• IntToDoubleFunction• IntToLongFunction• IntUnaryOperator• LongBinaryOperator• LongConsumer• LongFunction• LongPredicate• LongSupplier• LongToDoubleFunction• LongToIntFunction• LongUnaryOperator• ObjDoubleConsumer• ObjIntConsumer• ObjLongConsumer• Predicate• Supplier• ToDoubleBiFunction• ToDoubleFunction• ToIntBitFunction• ToIntFunction• ToLongBiFunction• ToLongFunction• UnaryOperatorJava• ClosureGroovy
java.util.streamhttps://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
List filter(List foos) {return foos.stream().filter(foo ->foo.name.equals(“bar")).collect(Collectors.toList());}List map(List foos) {return foos.stream().map(Bar::new).collect(Collectors.toList());}List distinct(List foos) {return foos.stream().distinct().collect(Collectors.toList());}
List filter(List foos) {foos.findAll { foo -> foo.name == 'bar' }}List map(List foos) {foos.collect { new Bar(foo) }}List distinct(List foos) {foos.unique()}
public static TransformablePublisher stream(Publisher publisher) {return Streams.transformable { subscriber ->require().streamSubscribe { handle ->publisher.subscribe(new Subscriber() {@Overridepublic void onSubscribe(final Subscription subscription) {handle.event {subscriber.onSubscribe(subscription)}}@Overridepublic void onNext(final T element) {handle.event { subscriber.onNext(element) }}@Overridepublic void onComplete() {handle.complete(subscriber.&onComplete)}@Overridepublic void onError(final Throwable cause) {handle.complete { subscriber.onError(cause) }}})}}}
Default Interface Methods• Game changerpublic interface Baz {String getName();default Bar bar() {return new Bar(this);}}Bar interfaceMethod(Baz baz) {return baz.bar();}Bar useInterface() {return interfaceMethod(() -> "John");}becomes a Supplierlambda implicitly coerced tointerface
Default Interface Methods• Not directly* supported in Groovy* Groovy 2.3 introduced Traits which are similar
References/More Info• https://github.com/danveloper/uberconf2014-from-groovy-to-java8/blob/master/from-groovy-to-java8.pdf• Anything w/ Venkat• https://www.youtube.com/watch?v=Ee5t_EGjv0A