les concepts de la programmation fonctionnelle illustrés avec java 8
DESCRIPTION
Ma présentation à Devoxx France 2014: Ce Quickie est basé sur le talk de Bodil Stokke: What Every Hipster Should Know About Functional Programming. C'est un petit exercice basé sur la question suivante: peut-on transposer tous les exemples JS de son talk en Java 8 avec des lambdas? Au programme donc: First Class Function, Functor, High Order Function, Reduction, Combinator, Composition.TRANSCRIPT
1
Les concepts de la
programmation fonctionnelle
illustrés avec Java 8 by Yannick Chartois
@ychartois
2
Bodil Stokke
What Every Hipster Should Know About Functional
Programming
Vimeo / Parleys
Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
3
Question
Maintenant que nous avons les lambdas, peut-on faire la
même chose avec Java 8?
Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
4
First Class Function
Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
Définition
“Les fonctions sont traitées par le langage comme des valeurs de
première classe.”
5 Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
Code
Résultat
Function<String, String> hello = (String s) -> "hello " + s;
hello ;
// BaseConcepts$$Lambda$1@a09ee92
// != BaseConcepts@30f39991
hello.apply("Erouan") ;
// hello Erouan
6
Higher order function
Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
Définition
“C'est une fonction qui prend une ou plusieurs fonctions comme
entrée et/ou qui renvoie une fonction”
7 Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
Code
Résultat
List<String> filter( Predicate<String> f, List<String> values ) {
List<String> toReturn = new ArrayList<>();
for( String current : values ) {
if ( f.test(current) )
toReturn.add( current );
}
return toReturn; }
List<String> confs = Arrays.asList("jug", "devoxx", "javaone");
filter(s -> s.contains("j"), confs) ;
// [jug, javaone]
Filter
Java 8
confs.stream().filter( s -> s.contains("j") ).collect(Collectors.toList())
8
Functor
Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
Définition
“C'est une collection d'éléments X qui peut s'appliquer une fonction
f: X -> Y pour créer une collection Y”
9 Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
Code
Résultat
List<String> map( Function<String, String> f , List<String> values ) {
List<String> toReturn = new ArrayList<>();
for( String current : values ) {
toReturn.add( f.apply(current) );
}
return toReturn; }
List<String> confs = Arrays.asList( "jug", "devoxx", "javaone" );
map( s -> s.toUpperCase(), confs );
// [JUG, DEVOXX, JAVAONE]
Map
Java 8
confs.stream().map( s -> s.toUpperCase() ).collect( Collectors.toList() )
10
Reduction / Aggregation
Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
Définition
Higher order function dont le but est de produire une valeur qui est
le résultat de l’application d’un opérateur sur tous les éléments
d’une structure de donnée
11 Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
Code
Résultat
String reduce( BinaryOperator<String> op , List<String> values ) {
String toReturn = "";
for( String current : values ) {
toReturn = toReturn.isEmpty() ? current : op.apply(toReturn, current)
}
return toReturn; }
List<String> confs = Arrays.asList( "jug", "devoxx", "javaone" );
reduce( (s1, s2) -> s1 + ", " + S2, confs );
// jug, devoxx, javaone
Reduce / fold
Java 8
confs.stream().reduce((s1, s2) -> s1 + ", " + s2 ).get() )
12
Combinator
Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
Définition
“C'est une fonction qui définie une nouvelle fonction à partir de ses
arguments ou d'autre combinators”
13 Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
Problème
Solution
List< String > confs2 = Arrays.asList( "jug", "devoxx", "javaone", null );
map( s -> s.toUpperCase(), confs2);
// Exception in thread "main" java.lang.NullPointerException
Function< String, String > nullCheck( Function< String, String > f ) {
return (String s) -> s == null ? "null" : f.apply(s);
}
Null Combinator
Résultat
map( nullCheck(s -> s.toUpperCase()), confs2)
// [JUG, DEVOXX, JAVAONE, null]
14
Composition
Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
Définition
“Combine plusieurs fonctions pour créer une nouvelle fonction”
15 Twitter: @ychartois – Github: https://github.com/ychartois/ProgFoncJava8
Code
Résultat
Function<String, String> compose (
Function<String, String> f1, Function<String, String> f2 ){
return (String s) -> f1.apply( f2.apply(s) );
}
Function<String, String> up = (String s) -> s.toUpperCase();
Function<String, String> hello = (String s) -> "hello " + s;
up.apply( hello.apply("Erouan") );
compose( up, hello).apply("Erouan") ;
// HELLO EROUAN
Java 8
hello.andThen(up).apply("Erouan")
16
Twitter: @ychartois
Github: https://github.com/ychartois/ProgFoncJava8