SlideShare una empresa de Scribd logo
1 de 42
Descargar para leer sin conexión
Dans les traboules
des lambdas
Rémi Forax
UPEM
Mai 2012
2
Moi
MCF à l'Université Paris Est Marne-la-vallée
Joue avec Java depuis trop longtemp pour
l'avouer
Créateur de langages dynamiques ou pas
Expert pour les JSR 292 (invokedynamic) et
JSR 335 (lambda)
Contributeur OpenJDK, ASM, Tatoo, PHP.reboot, JDart,
etc...
3
Un exemple de lambda
enum Gastronomy {
rosette,
andouillette,
coq_au_vin,
tripe,
cardoon
}
private static List<Gastronomy> getGastronomyList() {
List<Gastronomy> list = Arrays.asList(Gastronomy.values());
Collections.sort(list, new Comparator<Gastronomy>() {
@Override
public int compare(Gastronomy g1, Gastronomy g2) {
return g1.name().compareTo(g2.name());
}
});
return list;
}
public static void main(String[] args) {
System.out.println(getGastronomyList());
}
4
Exemple un poil plus compliqué
private static ArrayList<Gastronomy> prefixList(String prefix, List<Gastronomy> list) {
ArrayList<Gastronomy> list2 = new ArrayList<>();
for(Gastronomy gastronomy: list) {
if (gastronomy.name().startsWith(prefix)) {
list2.add(gastronomy);
}
}
return list2;
}
private static List<Gastronomy> getGastronomyList(String prefix) {
List<Gastronomy> list = Arrays.asList(Gastronomy.values());
ArrayList<Gastronomy> list2 = prefixList(prefix, list);
Collections.sort(list2, new Comparator<Gastronomy>() {
@Override
public int compare(Gastronomy g1, Gastronomy g2) {
return g1.name().compareTo(g2.name());
}
});
return list2;
}
5
Parties codantes
private static ArrayList<Gastronomy> prefixList(String prefix, List<Gastronomy> list) {
ArrayList<Gastronomy> list2 = new ArrayList<>();
for(Gastronomy gastronomy: list) {
if (gastronomy.name().startsWith(prefix)) {
list2.add(gastronomy);
}
}
return list2;
}
private static List<Gastronomy> getGastronomyList(String prefix) {
List<Gastronomy> list = Arrays.asList(Gastronomy.values());
ArrayList<Gastronomy> list2 = prefixList(prefix, list);
Collections.sort(list2, new Comparator<Gastronomy>() {
@Override
public int compare(Gastronomy g1, Gastronomy g2) {
return g1.name().compareTo(g2.name());
}
});
return list2;
}
6
Closure ??
Expression que l'on veut voir comme une valeur
Les closures/lambda existent dans plein d'autres
langages
Lisp/Clojure, Ruby, Groovy, Scala, C#,
JavaScript/Python, et même C++/Objective C
récemment
En Java, on a des classes annonymes
Youpi !
Nan, je rigole :)
7
Problème des classes anonymes
Verbeux visuellement
rapport signal/bruit pas terrible
Sémantiquement bizarre
on veut envoyer une expression, créont une classe ...
Perf discutable (pour des closures)
création d'une instance à chaque appel
+ 1 classe sur le disque
+ 1 instance de java.lang.Class et
ses métadatas en mémoire
8
Exemple de lambdas
(sans lambdas)
private static List<Gastronomy> getGastronomyList(String prefix) {
List<Gastronomy> list = Arrays.asList(Gastronomy.values());
ArrayList<Gastronomy> list2 = prefixList(prefix, list);
Collections.sort(list2, new Comparator<Gastronomy>() {
@Override
public int compare(Gastronomy g1, Gastronomy g2) {
return g1.name().compareTo(g2.name());
}
});
return list2;
}
9
Exemple de lambdas
(avec lambdas)
private static List<Gastronomy> getGastronomyList(String prefix) {
List<Gastronomy> list = Arrays.asList(Gastronomy.values());
ArrayList<Gastronomy> list2 = prefixList(prefix, list);
Collections.sort(list2, (Gastronomy g1, Gastronomy g2) -> {
return g1.name().compareTo(g2.name());
});
return list2;
}
La syntaxe utilise -> (light arrow)
et pas => (fat arrow) comme en Scala ou en C#
10
Inférence de type !
Le compilateur peut calculer le type des paramétres d'une
lambda !
la méthode sort() prend une liste de Gastronomy
donc elle attends un Comparator<Gastronomy>
private static List<Gastronomy> getGastronomyList(String prefix) {
List<Gastronomy> list = Arrays.asList(Gastronomy.values());
ArrayList<Gastronomy> list2 = prefixList(prefix, list);
Collections.sort(list2, (Gastronomy g1, Gastronomy g2) -> {
return g1.name().compareTo(g2.name());
});
return list2;
}
Le compilo n'utilise pas l'expression de la lambda pour faire l'inférence !
11
Exemple de lambdas
(avec lambdas + inférence)
private static List<Gastronomy> getGastronomyList(String prefix) {
List<Gastronomy> list = Arrays.asList(Gastronomy.values());
ArrayList<Gastronomy> list2 = prefixList(prefix, list);
Collections.sort(list2,
(g1, g2) -> g1.name().compareTo(g2.name()) );
return list2;
}
12
Syntaxe: Lambda expression
sans paramètre
() -> System.out.println("Vive l'OL")
avec un paramètre (+ inférence)
employee -> employee.isManager()
avec plusieurs paramètres
en déclarant les types
(int x, int y) -> x == y
sans déclarer les types (+ inférence)
(x, y) -> x == y
13
Syntaxe: Lambda instruction
sans paramètre
() -> {
System.out.println("Vive l'OL");
}
avec un paramètre (+ inférence)
employee -> {
return employee.isManager();
}
avec plusieurs paramètres (+ inférence)
(index1, index2) -> {
list.set(index1, list.get(index2));
}
14
Sémantique
Typé par une functional interface (ex SAM)
Runnable, Callable, Filter, Function, ...
Une lambda n'est pas un objet
“this” représente la classe courante pas la lambda
Une lambda est convertissable en un objet
qui implante une functional interface
Runnable r = () -> System.out.println("LOL?")
objet pas objet
15
Et les collections ?
Ici on filtre une liste, donc au lieu de
private static ArrayList<Gastronomy> prefixList(
String prefix, List<Gastronomy> list) {
ArrayList<Gastronomy> list2 = new ArrayList<>();
for(Gastronomy gastronomy: list) {
if (gastronomy.name().startsWith(prefix)) {
list2.add(gastronomy);
}
}
return list2;
}
16
Et les collections ?
On aimerait bien écrire
private static List<Gastronomy> prefixList(
String prefix, List<Gastronomy> list) {
return list.filter(g -> g.name().startsWith(prefix))
.toList()
}
Operation lazy
Operation pas lazy
Heu, toList() sur une liste, vraiment ??
17
Programmation déclarative
list.filter(...)
.map(...)
.reduce(...)
on veut éviter les structures de données
intermédiaire
lambdas
list filter map reduce
list filter map
reduce
Création (pipeline)
exécution
18
Programmation déclarative
Permet la programmation parallèle
On split les données en amont en on envoie le calcul sur
différentes threads
● Disponible pour Java 8
Permet d'utiliser les GPUs
On émet le code PTX/HSAIL correspondant
● Projet Sumatra (prototype avec Graal)
With great power there must also come — great
responsibility!
L'utilisateur ne doit pas faire d'effet de bord dans
les lambdas !!
19
Interface java.util.Stream
Sequentielle ou parallele
list.stream() ou list.parallelStream()
Deux types de methode
intermédiaire
filter, map, sorted, distinct, flatMap ...
terminales
forEach, reduce, collect, findFirst ...
L'implantation n'utilise pas de structures
intermédaires mais un pipeline !
Un effet de bord, t'es mort !
20
Sans l'API des streams
private static ArrayList<Gastronomy> prefixList(
String prefix, List<Gastronomy> list) {
ArrayList<Gastronomy> list2 = new ArrayList<>();
for(Gastronomy gastronomy: list) {
if (gastronomy.name().startsWith(prefix)) {
list2.add(gastronomy);
}
}
return list2;
}
21
Avec l'API des streams
private static ArrayList<Gastronomy> prefixList(
String prefix, List<Gastronomy> list) {
return list.stream()
.filter(g -> g.name().startsWith(prefix))
.collect(Collectors.toList());
}
Bonus! pas besoin de déclarer la variable locale final !
22
Le coté sombre
>= JDK8< JDK 8
Où sont passées mes belles interfaces ?
23
Traits
Pour ajouter le support des lambdas au
collections
Les méthodes stream() et parallelStream()
Il faut pouvoir ajouter des méthodes à une
interface
Il faut mettre du code dans les interfaces
Don't panic
Cela s'appelle des traits
(trivia: les traits de Scala ne sont pas des traits)
24
Default methods
Une méthode qui a du code dans une interface doit
être taggée default
Une méthode par défaut est utilisée par une classe si il
n'y a pas de méthode définie ou fournie par une sous
classe
public interface Iterator<T> {
public abstract boolean hasNext();
public abstract T next();
public default void remove() {
throw new UnsupportedOperationException();
}
}
25
Et le problème du diamand
Une interface accepte du code
mais pas de champs
Pas de problème de redéfinition de champ donc
Problème si on implante deux interfaces qui ont
chacune une méthode ayant du code
– Si une interface hérite de l'autre, on prend la méthode de la
sous-interface
– Sinon, le compilo plante
interface I { default void m() { } }
interface J { default void m() { } }
class A implements I, J {
// compile pas
}
26
Super sur des interfaces
La syntaxe, I.super.m() permet d'appeler la
méthode m de l'interface I.
donc pour résoudre le conflit
interface I { default void m() { } }
interface J { default void m() { } }
class A implements I, J {
public void m() {
I.super.m();
}
}
27
Retrofit
Avec Java 8, l'interface java.util.List possède enfin une
méthode sort (par défaut)
qui appele Collections.sort :)
private static List<Gastronomy> getGastronomyList(String prefix) {
List<Gastronomy> list = Arrays.asList(Gastronomy.values());
ArrayList<Gastronomy> list2 = prefixList(prefix, list);
list2.sort((g1, g2) -> g1.name().compareTo(g2.name()));
return list2;
}
28
Avoir une méthode intermédiaire n'est plus nécessaire, on peut
tout écrire dans une seule méthode
Et en utilisant Comparators.comparing()
private static List<Gastronomy> getGastronomyList(String prefix) {
return Arrays.stream(Gastronomy.values())
.filter(g -> g.name().startsWith(prefix))
.sorted(Comparators.comparing(g -> g.name()))
.collect(Collectors.toList());
}
public static void main(String[] args) {
System.out.println(getGastronomyList("c"));
}
Exemple (suite)
29
Method Reference
Il existe une syntaxe spécifique pour les
lambdas qui appel juste une méthode
g -> g.name() peut s'écrire Gastronomy::name
On ne spécifie pas le type des paramètres,
le compilateur utilise la fonctional interface pour
les trouver
Il est aussi possible de capturer une valeur
Callable<String> c = "foo"::toUpperCase()
System.out.println(c.call()); // prints FOO
30
Avec des Method References
Et tout dans le main.
public static void main(String[] args) {
Arrays.stream(Gastronomy.values())
.filter(g -> g.name().startsWith("c"))
.sorted(
Comparators.comparing(Gastronomy::name))
.forEach(System.out::println);
}
31
Hunder the hoodHunder the hood
32
Compilation - Création
Une référence sur une méthode est crée en
utilisant invokedynamic
BiFunction<String, Integer, Character> fun
= String::charAt;
est transformé par le compilateur en
code:
0: invokedynamic lambda() #0
()Ljava/util/function/BiFunction;
5: astore_1
33
Compilation - Création
constants:
#0: #15 invokestatic java/lang/invoke/LambdaMetafactory.metaFactory:
(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invok
e/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHan
dle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments:
#16 invokeinterface java/util/function/BiFunction.apply
:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
#17 invokevirtual java/lang/String.charAt:(I)C
#18 (Ljava/lang/String;Ljava/lang/Integer;)Ljava/lang/Character;
code:
0: invokedynamic lambda() #0
()Ljava/util/function/BiFunction;
5: astore_1
Functional interface
Methode
de l'interface
Methode
référencée
Signature générique réifiée
34
Intérêt d'utiliser invokedynamic
La création de l'objet implantant la functional
interface n'est pas écrite dans le code généré
Peux changer en fonction des versions du JDK,
des optimisations implantées dans la VM
Si l'objet est constant, il peut être ré-utilisé
Pour le jdk8, utilise ASM pour générer une
classe proxy dynamiquement
et sans vérification du bytecode
35
Compilation - Appel
L'appel se fait en utilisant la méthode de l'interface
BiFunction<String, Integer, Character> fun = ...
char c = fun.apply("foo", 0);
et en bytecode
7: ldc #3 // String “foo”
9: iconst_0
10: invokestatic #4 // Integer.valueOf:(I)Ljava/lang/Integer;
13: invokeinterface #5, 3 // BiFunction.apply
(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
18: checkcast #6 // class Character
21: invokevirtual #7 // Character.charValue:()C
24: istore_2
36
Et les perfs ? / un nano-test
public class HoodPerf {
private static int COUNTER;
private static void test() {
BiFunction<String, Integer, Character> fun = String::charAt;
char c = fun.apply("foobar", 5);
COUNTER += c; // side effect
}
public static void main(String[] args) {
for(int i=0; i<10_000; i++) {
test();
}
System.out.println(COUNTER);
System.out.println(end – start);
}
}
Ce code ne marche
pas pour faire un
benchmark mais ...
37
pour voir de l'assembleur ...
{0x00007fd655851530} 'test' '()V' in 'HoodPerf'
...d64d074300: mov %eax,-0x14000(%rsp)
...d64d074307: push %rbp
...fd64d074308: sub $0x20,%rsp
...d64d07430c: mov $0xef010e68,%r10 ; {oop(a 'HoodPerf$$Lambda$1')}
...d64d074316: mov 0x8(%r10),%r8d ; getClass
...d64d07431a: mov $0xeeedaf80,%r11 ; {oop(a 'java/lang/Integer'[256] )}
...d64d074324: mov 0x210(%r11),%r11d ;*aaload
; - java.lang.Integer::valueOf@21 (line 809)
...d64d07432b: cmp $0xc6860240,%r8d ; {metadata('HoodPerf$$Lambda$1')}
...d64d074332: jne ...d64d0743e9 ;*invokeinterface apply
; - HoodPerf::test@13 (line 10)
...d64d074338: mov 0xc(%r11),%ebp ;*getfield value
; - java.lang.Integer::intValue@1 (line 871)
; implicit exception: dispatches to 0x00007fd64d074486
...d64d07433c: test %ebp,%ebp
...d64d07433e: jl ...d64d074401 ;*iflt
; - java.lang.String::charAt@1 (line 650)
...d64d074344: cmp $0x3,%ebp
...d64d074347: jge ...d64d074401 ;*if_icmplt
; - java.lang.String::charAt@10 (line 650)
...d64d07434d: cmp $0x3,%ebp
...d64d074350: jae ...d64d0743b7
ahah
charAt
38
Pour info, le code de String.charAt
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIOOBException(index);
}
return value[index];
}
...070d06a53c: test %edx,%edx
...070d06a53e: jl ...070d06a575 ;*iflt
; - java.lang.String::charAt@1 (line 650)
...070d06a540: mov 0xc(%rsi),%ebp ;*getfield value
; - java.lang.String::charAt@6 (line 650)
...070d06a543: mov 0xc(%rbp),%r10d ;*arraylength
; - java.lang.String::charAt@9 (line 650)
; implicit exception: dispatches to ...070d06a589
...070d06a547: cmp %r10d,%edx
...070d06a54a: jge ...070d06a575 ;*if_icmplt
; - java.lang.String::charAt@10 (line 650)
...070d06a54c: cmp %r10d,%edx
...070d06a54f: jae ...070d06a562
...070d06a551: movzwl 0x10(%rbp,%rdx,2),%eax
39
et encore de l'assembleur ...
...d64d074352: mov $0xef015e10,%r10 ; {oop([C)}
...d64d07435c: movzwl 0x10(%r10,%rbp,2),%ebp ;*caload
; - java.lang.String::charAt@27 (line 653)
...d64d074362: cmp $0x7f,%ebp
...d64d074365: jg ...d64d074411 ;*if_icmpgt
; - java.lang.Character::valueOf@3 (line 4570)
...d64d07436b: cmp $0x80,%ebp
...d64d074371: jae 0x00007fd64d0743c9
...d64d074373: mov $0xeef0e828,%r10 ; {oop(a 'java/lang/Character'[128] )}
...d64d07437d: mov 0x10(%r10,%rbp,4),%r10d ;*aaload
; - java.lang.Character::valueOf@10 (line 4571)
...d64d074382: test %r10d,%r10d
...d64d074385: je ...d64d0743d9 ;*invokevirtual charValue
...d64d074387: mov $0xeef05ab8,%r11 ; {oop(a 'java/lang/Class' = 'HoodPerf')}
...d64d074391: mov 0x58(%r11),%r11d ;*invokestatic valueOf
...d64d074395: movzwl 0xc(%r10),%r10d
...d64d07439a: add %r10d,%r11d
...d64d07439d: mov $0xeef05ab8,%r10 ; {oop(a 'java/lang/Class' = 'HoodPerf')}
...d64d0743a7: mov %r11d,0x58(%r10) ;*putstatic COUNTER
...d64d0743ab: add $0x20,%rsp
...d64d0743af: pop %rbp
...d64d0743b0: test %eax,0x9006c4a(%rip) # ...d65607b000
; {poll_return}
...d64d0743b6: retq Ça sert à quoi ??
charAt
40
... en résumé
Une méthode référence (ou une lambda) qui ne
fait pas de capture est une constante
L'appel a une lambda peut être dévirtualisé et
inliné comme n'importe quel appel
Le code montré est celui générer par le
jdk8b88-lambda avec elision du
boxing/unboxing desactivé :(
41
What's next ?
Updates du JDK8
lambda constante sans check de classe
lambda non-constante mieux dévirtualisée
Java 9
Value Object
Integer, Float, etc ne devrait pas avoir d'identité
=> pas sûr que cela marche
Utilisation du/des GPUs dans les Stream parallele
42
Questions ?
JDK8 Feature Freeze jeudi prochain !
les lambdas sont déjà dans le JDK !
https://jdk8.java.net/download.html
Remonter les bugs sur
la mailing list: lambda-dev
http://mail.openjdk.java.net/mailman/listinfo/lambda-dev
ou bugs.sun.com

Más contenido relacionado

La actualidad más candente

Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++Fabio Hernandez
 
Résumer sur les fichier et les enregistrement
Résumer sur les fichier et les enregistrementRésumer sur les fichier et les enregistrement
Résumer sur les fichier et les enregistrementborhen boukthir
 
Développement informatique : Chaines de caractères et expressions regulières
Développement informatique : Chaines de caractères et expressions regulièresDéveloppement informatique : Chaines de caractères et expressions regulières
Développement informatique : Chaines de caractères et expressions regulièresECAM Brussels Engineering School
 
Programmation fonctionnelle
Programmation fonctionnelleProgrammation fonctionnelle
Programmation fonctionnelleGeeks Anonymes
 
Développement informatique : Algorithmique I : Récursion et arbre
Développement informatique : Algorithmique I : Récursion et arbreDéveloppement informatique : Algorithmique I : Récursion et arbre
Développement informatique : Algorithmique I : Récursion et arbreECAM Brussels Engineering School
 
Chapitre1: Langage Python
Chapitre1: Langage PythonChapitre1: Langage Python
Chapitre1: Langage PythonAziz Darouichi
 
Partie 10: Classes Génériques — Programmation orientée objet en C++
Partie 10: Classes Génériques — Programmation orientée objet en C++Partie 10: Classes Génériques — Programmation orientée objet en C++
Partie 10: Classes Génériques — Programmation orientée objet en C++Fabio Hernandez
 
Scala : programmation fonctionnelle
Scala : programmation fonctionnelleScala : programmation fonctionnelle
Scala : programmation fonctionnelleMICHRAFY MUSTAFA
 
Python avancé : Gestion d'erreurs et mécanisme d'exception
Python avancé : Gestion d'erreurs et mécanisme d'exceptionPython avancé : Gestion d'erreurs et mécanisme d'exception
Python avancé : Gestion d'erreurs et mécanisme d'exceptionECAM Brussels Engineering School
 
Développement informatique : Programmation fonctionnelle, décorateur et génér...
Développement informatique : Programmation fonctionnelle, décorateur et génér...Développement informatique : Programmation fonctionnelle, décorateur et génér...
Développement informatique : Programmation fonctionnelle, décorateur et génér...ECAM Brussels Engineering School
 
Chap3 programmation modulaire en python
Chap3 programmation modulaire en pythonChap3 programmation modulaire en python
Chap3 programmation modulaire en pythonMariem ZAOUALI
 
Partie 4: Fonctions - Programmation orientée objet en C++
Partie 4: Fonctions - Programmation orientée objet en C++Partie 4: Fonctions - Programmation orientée objet en C++
Partie 4: Fonctions - Programmation orientée objet en C++Fabio Hernandez
 
Interception de signal avec dump de la pile d'appel
Interception de signal avec dump de la pile d'appelInterception de signal avec dump de la pile d'appel
Interception de signal avec dump de la pile d'appelThierry Gayet
 
VIM puissance PHP = VI Improved !
VIM puissance PHP = VI Improved !VIM puissance PHP = VI Improved !
VIM puissance PHP = VI Improved !Frederic Hardy
 
Partie 14: Entrée/Sortie — Programmation orientée objet en C++
Partie 14: Entrée/Sortie — Programmation orientée objet en C++Partie 14: Entrée/Sortie — Programmation orientée objet en C++
Partie 14: Entrée/Sortie — Programmation orientée objet en C++Fabio Hernandez
 

La actualidad más candente (20)

Google Developer Group (GDG) Aix-Marseille #1 (27/08/2018)
Google Developer Group (GDG) Aix-Marseille #1 (27/08/2018)Google Developer Group (GDG) Aix-Marseille #1 (27/08/2018)
Google Developer Group (GDG) Aix-Marseille #1 (27/08/2018)
 
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++
Partie 3: Contrôle d'Exécution — Programmation orientée objet en C++
 
Résumer sur les fichier et les enregistrement
Résumer sur les fichier et les enregistrementRésumer sur les fichier et les enregistrement
Résumer sur les fichier et les enregistrement
 
Programmation Fonctionnelle
Programmation FonctionnelleProgrammation Fonctionnelle
Programmation Fonctionnelle
 
Développement informatique : Chaines de caractères et expressions regulières
Développement informatique : Chaines de caractères et expressions regulièresDéveloppement informatique : Chaines de caractères et expressions regulières
Développement informatique : Chaines de caractères et expressions regulières
 
Programmation fonctionnelle
Programmation fonctionnelleProgrammation fonctionnelle
Programmation fonctionnelle
 
Développement informatique : Algorithmique I : Récursion et arbre
Développement informatique : Algorithmique I : Récursion et arbreDéveloppement informatique : Algorithmique I : Récursion et arbre
Développement informatique : Algorithmique I : Récursion et arbre
 
Chapitre1: Langage Python
Chapitre1: Langage PythonChapitre1: Langage Python
Chapitre1: Langage Python
 
Partie 10: Classes Génériques — Programmation orientée objet en C++
Partie 10: Classes Génériques — Programmation orientée objet en C++Partie 10: Classes Génériques — Programmation orientée objet en C++
Partie 10: Classes Génériques — Programmation orientée objet en C++
 
Scala : programmation fonctionnelle
Scala : programmation fonctionnelleScala : programmation fonctionnelle
Scala : programmation fonctionnelle
 
Python après 15 ans de JAVA
Python après 15 ans de JAVAPython après 15 ans de JAVA
Python après 15 ans de JAVA
 
Python avancé : Gestion d'erreurs et mécanisme d'exception
Python avancé : Gestion d'erreurs et mécanisme d'exceptionPython avancé : Gestion d'erreurs et mécanisme d'exception
Python avancé : Gestion d'erreurs et mécanisme d'exception
 
Développement informatique : Programmation fonctionnelle, décorateur et génér...
Développement informatique : Programmation fonctionnelle, décorateur et génér...Développement informatique : Programmation fonctionnelle, décorateur et génér...
Développement informatique : Programmation fonctionnelle, décorateur et génér...
 
Formation python
Formation pythonFormation python
Formation python
 
Chap3 programmation modulaire en python
Chap3 programmation modulaire en pythonChap3 programmation modulaire en python
Chap3 programmation modulaire en python
 
Partie 4: Fonctions - Programmation orientée objet en C++
Partie 4: Fonctions - Programmation orientée objet en C++Partie 4: Fonctions - Programmation orientée objet en C++
Partie 4: Fonctions - Programmation orientée objet en C++
 
Change mind about JS
Change mind about JSChange mind about JS
Change mind about JS
 
Interception de signal avec dump de la pile d'appel
Interception de signal avec dump de la pile d'appelInterception de signal avec dump de la pile d'appel
Interception de signal avec dump de la pile d'appel
 
VIM puissance PHP = VI Improved !
VIM puissance PHP = VI Improved !VIM puissance PHP = VI Improved !
VIM puissance PHP = VI Improved !
 
Partie 14: Entrée/Sortie — Programmation orientée objet en C++
Partie 14: Entrée/Sortie — Programmation orientée objet en C++Partie 14: Entrée/Sortie — Programmation orientée objet en C++
Partie 14: Entrée/Sortie — Programmation orientée objet en C++
 

Destacado

201303 - Golo
201303 - Golo201303 - Golo
201303 - Gololyonjug
 
Presentation jug novembre2015
Presentation jug novembre2015Presentation jug novembre2015
Presentation jug novembre2015lyonjug
 
Kotlin: A pragmatic language by JetBrains
Kotlin: A pragmatic language by JetBrainsKotlin: A pragmatic language by JetBrains
Kotlin: A pragmatic language by JetBrainsJigar Gosar
 
Resume / Cv - Goncalo Silva
Resume / Cv  - Goncalo SilvaResume / Cv  - Goncalo Silva
Resume / Cv - Goncalo SilvaGoncalo Silva
 
DIY: Analyse statique en Java
DIY: Analyse statique en JavaDIY: Analyse statique en Java
DIY: Analyse statique en Javalyonjug
 
Microservices Manchester: Concursus - Event Sourcing Evolved By Domonic Fox
Microservices Manchester: Concursus - Event Sourcing Evolved By Domonic FoxMicroservices Manchester: Concursus - Event Sourcing Evolved By Domonic Fox
Microservices Manchester: Concursus - Event Sourcing Evolved By Domonic FoxOpenCredo
 
Java to Scala: Why & How
Java to Scala: Why & HowJava to Scala: Why & How
Java to Scala: Why & HowGraham Tackley
 
Moving from Relational to Document Store
Moving from Relational to Document StoreMoving from Relational to Document Store
Moving from Relational to Document StoreGraham Tackley
 
Scala: simplifying development at guardian.co.uk
Scala: simplifying development at guardian.co.ukScala: simplifying development at guardian.co.uk
Scala: simplifying development at guardian.co.ukGraham Tackley
 
Swift and Kotlin Presentation
Swift and Kotlin PresentationSwift and Kotlin Presentation
Swift and Kotlin PresentationAndrzej Sitek
 
How elasticsearch powers the Guardian's newsroom
How elasticsearch powers the Guardian's newsroomHow elasticsearch powers the Guardian's newsroom
How elasticsearch powers the Guardian's newsroomGraham Tackley
 
Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performanceintelliyole
 
Little Helpers for Android Development with Kotlin
Little Helpers for Android Development with KotlinLittle Helpers for Android Development with Kotlin
Little Helpers for Android Development with KotlinKai Koenig
 
Kotlin: Why Do You Care?
Kotlin: Why Do You Care?Kotlin: Why Do You Care?
Kotlin: Why Do You Care?intelliyole
 
MBLT16: Elena Rydkina, Pure
MBLT16: Elena Rydkina, PureMBLT16: Elena Rydkina, Pure
MBLT16: Elena Rydkina, Puree-Legion
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlinThijs Suijten
 
Anko - The Ultimate Ninja of Kotlin Libraries?
Anko - The Ultimate Ninja of Kotlin Libraries?Anko - The Ultimate Ninja of Kotlin Libraries?
Anko - The Ultimate Ninja of Kotlin Libraries?Kai Koenig
 
Coding for Android on steroids with Kotlin
Coding for Android on steroids with KotlinCoding for Android on steroids with Kotlin
Coding for Android on steroids with KotlinKai Koenig
 

Destacado (20)

201303 - Golo
201303 - Golo201303 - Golo
201303 - Golo
 
Presentation jug novembre2015
Presentation jug novembre2015Presentation jug novembre2015
Presentation jug novembre2015
 
Kotlin: A pragmatic language by JetBrains
Kotlin: A pragmatic language by JetBrainsKotlin: A pragmatic language by JetBrains
Kotlin: A pragmatic language by JetBrains
 
Resume / Cv - Goncalo Silva
Resume / Cv  - Goncalo SilvaResume / Cv  - Goncalo Silva
Resume / Cv - Goncalo Silva
 
DIY: Analyse statique en Java
DIY: Analyse statique en JavaDIY: Analyse statique en Java
DIY: Analyse statique en Java
 
Microservices Manchester: Concursus - Event Sourcing Evolved By Domonic Fox
Microservices Manchester: Concursus - Event Sourcing Evolved By Domonic FoxMicroservices Manchester: Concursus - Event Sourcing Evolved By Domonic Fox
Microservices Manchester: Concursus - Event Sourcing Evolved By Domonic Fox
 
Java to Scala: Why & How
Java to Scala: Why & HowJava to Scala: Why & How
Java to Scala: Why & How
 
Moving from Relational to Document Store
Moving from Relational to Document StoreMoving from Relational to Document Store
Moving from Relational to Document Store
 
Scala: simplifying development at guardian.co.uk
Scala: simplifying development at guardian.co.ukScala: simplifying development at guardian.co.uk
Scala: simplifying development at guardian.co.uk
 
Swift and Kotlin Presentation
Swift and Kotlin PresentationSwift and Kotlin Presentation
Swift and Kotlin Presentation
 
How elasticsearch powers the Guardian's newsroom
How elasticsearch powers the Guardian's newsroomHow elasticsearch powers the Guardian's newsroom
How elasticsearch powers the Guardian's newsroom
 
GB_Guide_pratique
GB_Guide_pratiqueGB_Guide_pratique
GB_Guide_pratique
 
Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performance
 
Little Helpers for Android Development with Kotlin
Little Helpers for Android Development with KotlinLittle Helpers for Android Development with Kotlin
Little Helpers for Android Development with Kotlin
 
Kotlin: Why Do You Care?
Kotlin: Why Do You Care?Kotlin: Why Do You Care?
Kotlin: Why Do You Care?
 
MBLT16: Elena Rydkina, Pure
MBLT16: Elena Rydkina, PureMBLT16: Elena Rydkina, Pure
MBLT16: Elena Rydkina, Pure
 
No excuses, switch to kotlin
No excuses, switch to kotlinNo excuses, switch to kotlin
No excuses, switch to kotlin
 
Testing with Kotlin
Testing with KotlinTesting with Kotlin
Testing with Kotlin
 
Anko - The Ultimate Ninja of Kotlin Libraries?
Anko - The Ultimate Ninja of Kotlin Libraries?Anko - The Ultimate Ninja of Kotlin Libraries?
Anko - The Ultimate Ninja of Kotlin Libraries?
 
Coding for Android on steroids with Kotlin
Coding for Android on steroids with KotlinCoding for Android on steroids with Kotlin
Coding for Android on steroids with Kotlin
 

Similar a 201305 - Lambda by R. Forax

Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...Normandy JUG
 
Java 8 : Un ch'ti peu de lambda
Java 8 : Un ch'ti peu de lambdaJava 8 : Un ch'ti peu de lambda
Java 8 : Un ch'ti peu de lambdaCh'ti JUG
 
20140123 java8 lambdas_jose-paumard-soat
20140123 java8 lambdas_jose-paumard-soat20140123 java8 lambdas_jose-paumard-soat
20140123 java8 lambdas_jose-paumard-soatSOAT
 
Java 8 - interfaces
Java 8 - interfacesJava 8 - interfaces
Java 8 - interfacesFranck SIMON
 
Android Optimisations Greendroid
Android Optimisations GreendroidAndroid Optimisations Greendroid
Android Optimisations GreendroidGDG Nantes
 
Interface collectionsinter
Interface collectionsinterInterface collectionsinter
Interface collectionsinterRYMAA
 
Annotation Java vs. Decorator Python
Annotation Java vs. Decorator PythonAnnotation Java vs. Decorator Python
Annotation Java vs. Decorator PythonDidier Plaindoux
 
Geek Time Janvier 2017 : Java 8
Geek Time Janvier 2017 : Java 8Geek Time Janvier 2017 : Java 8
Geek Time Janvier 2017 : Java 8OLBATI
 
JDK 8, lambdas, streams, collectors - Bretagne Tour
JDK 8, lambdas, streams, collectors - Bretagne TourJDK 8, lambdas, streams, collectors - Bretagne Tour
JDK 8, lambdas, streams, collectors - Bretagne TourJosé Paumard
 
01 - Introduction à Python chaines de caractères.pdf
01 - Introduction à Python chaines de caractères.pdf01 - Introduction à Python chaines de caractères.pdf
01 - Introduction à Python chaines de caractères.pdfMARYAM510573
 
Généralités sur la notion d’Algorithme
Généralités sur la notion d’AlgorithmeGénéralités sur la notion d’Algorithme
Généralités sur la notion d’AlgorithmeInforMatica34
 
L’environnement de programmation fonctionnelle DrRacket
L’environnement de programmation fonctionnelle DrRacketL’environnement de programmation fonctionnelle DrRacket
L’environnement de programmation fonctionnelle DrRacketStéphane Legrand
 

Similar a 201305 - Lambda by R. Forax (20)

Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
 
Java 8 : Un ch'ti peu de lambda
Java 8 : Un ch'ti peu de lambdaJava 8 : Un ch'ti peu de lambda
Java 8 : Un ch'ti peu de lambda
 
20140123 java8 lambdas_jose-paumard-soat
20140123 java8 lambdas_jose-paumard-soat20140123 java8 lambdas_jose-paumard-soat
20140123 java8 lambdas_jose-paumard-soat
 
Java 8 - interfaces
Java 8 - interfacesJava 8 - interfaces
Java 8 - interfaces
 
Android Optimisations Greendroid
Android Optimisations GreendroidAndroid Optimisations Greendroid
Android Optimisations Greendroid
 
Theme2
Theme2Theme2
Theme2
 
COURS_PYTHON_22.ppt
COURS_PYTHON_22.pptCOURS_PYTHON_22.ppt
COURS_PYTHON_22.ppt
 
Theme2
Theme2Theme2
Theme2
 
TAD (1).pptx
TAD (1).pptxTAD (1).pptx
TAD (1).pptx
 
Héritage et redéfinition de méthode
Héritage et redéfinition de méthodeHéritage et redéfinition de méthode
Héritage et redéfinition de méthode
 
Interface collectionsinter
Interface collectionsinterInterface collectionsinter
Interface collectionsinter
 
Memo java
Memo javaMemo java
Memo java
 
Annotation Java vs. Decorator Python
Annotation Java vs. Decorator PythonAnnotation Java vs. Decorator Python
Annotation Java vs. Decorator Python
 
Geek Time Janvier 2017 : Java 8
Geek Time Janvier 2017 : Java 8Geek Time Janvier 2017 : Java 8
Geek Time Janvier 2017 : Java 8
 
22-reflection.pdf
22-reflection.pdf22-reflection.pdf
22-reflection.pdf
 
JDK 8, lambdas, streams, collectors - Bretagne Tour
JDK 8, lambdas, streams, collectors - Bretagne TourJDK 8, lambdas, streams, collectors - Bretagne Tour
JDK 8, lambdas, streams, collectors - Bretagne Tour
 
01 - Introduction à Python chaines de caractères.pdf
01 - Introduction à Python chaines de caractères.pdf01 - Introduction à Python chaines de caractères.pdf
01 - Introduction à Python chaines de caractères.pdf
 
Généralités sur la notion d’Algorithme
Généralités sur la notion d’AlgorithmeGénéralités sur la notion d’Algorithme
Généralités sur la notion d’Algorithme
 
TP5_2020.pdf
TP5_2020.pdfTP5_2020.pdf
TP5_2020.pdf
 
L’environnement de programmation fonctionnelle DrRacket
L’environnement de programmation fonctionnelle DrRacketL’environnement de programmation fonctionnelle DrRacket
L’environnement de programmation fonctionnelle DrRacket
 

Más de lyonjug

Lightning talk LyonJUG février 2016 - Ansible
Lightning talk LyonJUG février 2016 - AnsibleLightning talk LyonJUG février 2016 - Ansible
Lightning talk LyonJUG février 2016 - Ansiblelyonjug
 
Introduction LyonJUG décembre 2015
Introduction LyonJUG décembre 2015Introduction LyonJUG décembre 2015
Introduction LyonJUG décembre 2015lyonjug
 
Introduction LyonJUG Janvier 2016
Introduction LyonJUG Janvier 2016Introduction LyonJUG Janvier 2016
Introduction LyonJUG Janvier 2016lyonjug
 
201502 - Integration Testing
201502 - Integration Testing201502 - Integration Testing
201502 - Integration Testinglyonjug
 
201311 - Middleware
201311 - Middleware201311 - Middleware
201311 - Middlewarelyonjug
 
201303 - Java8
201303 - Java8201303 - Java8
201303 - Java8lyonjug
 
201301 - Focus Neo4j
201301 - Focus Neo4j201301 - Focus Neo4j
201301 - Focus Neo4jlyonjug
 
201301 - Panorama NoSQL
201301 - Panorama NoSQL201301 - Panorama NoSQL
201301 - Panorama NoSQLlyonjug
 
201209 Lombok & Guava
201209 Lombok & Guava201209 Lombok & Guava
201209 Lombok & Guavalyonjug
 
201209 LT Clojure
201209 LT Clojure201209 LT Clojure
201209 LT Clojurelyonjug
 
Spring Batch Workshop (advanced)
Spring Batch Workshop (advanced)Spring Batch Workshop (advanced)
Spring Batch Workshop (advanced)lyonjug
 
Spring Batch Workshop
Spring Batch WorkshopSpring Batch Workshop
Spring Batch Workshoplyonjug
 
Engagement des sociétés d'Ingénierie dans la contribution open source : un ce...
Engagement des sociétés d'Ingénierie dans la contribution open source : un ce...Engagement des sociétés d'Ingénierie dans la contribution open source : un ce...
Engagement des sociétés d'Ingénierie dans la contribution open source : un ce...lyonjug
 
GlassFish, Application versioning et rolling upgrade en haute disponibilité
GlassFish, Application versioning et rolling upgrade en haute disponibilitéGlassFish, Application versioning et rolling upgrade en haute disponibilité
GlassFish, Application versioning et rolling upgrade en haute disponibilitélyonjug
 
Développement dans le cloud - Sacha Labourey
Développement dans le cloud - Sacha LaboureyDéveloppement dans le cloud - Sacha Labourey
Développement dans le cloud - Sacha Laboureylyonjug
 
Présentation Granite ds lyon 2011 par William Draï
Présentation Granite ds lyon 2011 par William DraïPrésentation Granite ds lyon 2011 par William Draï
Présentation Granite ds lyon 2011 par William Draïlyonjug
 
20091020 JPA2
20091020 JPA220091020 JPA2
20091020 JPA2lyonjug
 
201003 OSGi
201003 OSGi201003 OSGi
201003 OSGilyonjug
 
201003 BIRT
201003 BIRT201003 BIRT
201003 BIRTlyonjug
 
201006 Graniteds
201006 Graniteds201006 Graniteds
201006 Granitedslyonjug
 

Más de lyonjug (20)

Lightning talk LyonJUG février 2016 - Ansible
Lightning talk LyonJUG février 2016 - AnsibleLightning talk LyonJUG février 2016 - Ansible
Lightning talk LyonJUG février 2016 - Ansible
 
Introduction LyonJUG décembre 2015
Introduction LyonJUG décembre 2015Introduction LyonJUG décembre 2015
Introduction LyonJUG décembre 2015
 
Introduction LyonJUG Janvier 2016
Introduction LyonJUG Janvier 2016Introduction LyonJUG Janvier 2016
Introduction LyonJUG Janvier 2016
 
201502 - Integration Testing
201502 - Integration Testing201502 - Integration Testing
201502 - Integration Testing
 
201311 - Middleware
201311 - Middleware201311 - Middleware
201311 - Middleware
 
201303 - Java8
201303 - Java8201303 - Java8
201303 - Java8
 
201301 - Focus Neo4j
201301 - Focus Neo4j201301 - Focus Neo4j
201301 - Focus Neo4j
 
201301 - Panorama NoSQL
201301 - Panorama NoSQL201301 - Panorama NoSQL
201301 - Panorama NoSQL
 
201209 Lombok & Guava
201209 Lombok & Guava201209 Lombok & Guava
201209 Lombok & Guava
 
201209 LT Clojure
201209 LT Clojure201209 LT Clojure
201209 LT Clojure
 
Spring Batch Workshop (advanced)
Spring Batch Workshop (advanced)Spring Batch Workshop (advanced)
Spring Batch Workshop (advanced)
 
Spring Batch Workshop
Spring Batch WorkshopSpring Batch Workshop
Spring Batch Workshop
 
Engagement des sociétés d'Ingénierie dans la contribution open source : un ce...
Engagement des sociétés d'Ingénierie dans la contribution open source : un ce...Engagement des sociétés d'Ingénierie dans la contribution open source : un ce...
Engagement des sociétés d'Ingénierie dans la contribution open source : un ce...
 
GlassFish, Application versioning et rolling upgrade en haute disponibilité
GlassFish, Application versioning et rolling upgrade en haute disponibilitéGlassFish, Application versioning et rolling upgrade en haute disponibilité
GlassFish, Application versioning et rolling upgrade en haute disponibilité
 
Développement dans le cloud - Sacha Labourey
Développement dans le cloud - Sacha LaboureyDéveloppement dans le cloud - Sacha Labourey
Développement dans le cloud - Sacha Labourey
 
Présentation Granite ds lyon 2011 par William Draï
Présentation Granite ds lyon 2011 par William DraïPrésentation Granite ds lyon 2011 par William Draï
Présentation Granite ds lyon 2011 par William Draï
 
20091020 JPA2
20091020 JPA220091020 JPA2
20091020 JPA2
 
201003 OSGi
201003 OSGi201003 OSGi
201003 OSGi
 
201003 BIRT
201003 BIRT201003 BIRT
201003 BIRT
 
201006 Graniteds
201006 Graniteds201006 Graniteds
201006 Graniteds
 

201305 - Lambda by R. Forax

  • 1. Dans les traboules des lambdas Rémi Forax UPEM Mai 2012
  • 2. 2 Moi MCF à l'Université Paris Est Marne-la-vallée Joue avec Java depuis trop longtemp pour l'avouer Créateur de langages dynamiques ou pas Expert pour les JSR 292 (invokedynamic) et JSR 335 (lambda) Contributeur OpenJDK, ASM, Tatoo, PHP.reboot, JDart, etc...
  • 3. 3 Un exemple de lambda enum Gastronomy { rosette, andouillette, coq_au_vin, tripe, cardoon } private static List<Gastronomy> getGastronomyList() { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); Collections.sort(list, new Comparator<Gastronomy>() { @Override public int compare(Gastronomy g1, Gastronomy g2) { return g1.name().compareTo(g2.name()); } }); return list; } public static void main(String[] args) { System.out.println(getGastronomyList()); }
  • 4. 4 Exemple un poil plus compliqué private static ArrayList<Gastronomy> prefixList(String prefix, List<Gastronomy> list) { ArrayList<Gastronomy> list2 = new ArrayList<>(); for(Gastronomy gastronomy: list) { if (gastronomy.name().startsWith(prefix)) { list2.add(gastronomy); } } return list2; } private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); Collections.sort(list2, new Comparator<Gastronomy>() { @Override public int compare(Gastronomy g1, Gastronomy g2) { return g1.name().compareTo(g2.name()); } }); return list2; }
  • 5. 5 Parties codantes private static ArrayList<Gastronomy> prefixList(String prefix, List<Gastronomy> list) { ArrayList<Gastronomy> list2 = new ArrayList<>(); for(Gastronomy gastronomy: list) { if (gastronomy.name().startsWith(prefix)) { list2.add(gastronomy); } } return list2; } private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); Collections.sort(list2, new Comparator<Gastronomy>() { @Override public int compare(Gastronomy g1, Gastronomy g2) { return g1.name().compareTo(g2.name()); } }); return list2; }
  • 6. 6 Closure ?? Expression que l'on veut voir comme une valeur Les closures/lambda existent dans plein d'autres langages Lisp/Clojure, Ruby, Groovy, Scala, C#, JavaScript/Python, et même C++/Objective C récemment En Java, on a des classes annonymes Youpi ! Nan, je rigole :)
  • 7. 7 Problème des classes anonymes Verbeux visuellement rapport signal/bruit pas terrible Sémantiquement bizarre on veut envoyer une expression, créont une classe ... Perf discutable (pour des closures) création d'une instance à chaque appel + 1 classe sur le disque + 1 instance de java.lang.Class et ses métadatas en mémoire
  • 8. 8 Exemple de lambdas (sans lambdas) private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); Collections.sort(list2, new Comparator<Gastronomy>() { @Override public int compare(Gastronomy g1, Gastronomy g2) { return g1.name().compareTo(g2.name()); } }); return list2; }
  • 9. 9 Exemple de lambdas (avec lambdas) private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); Collections.sort(list2, (Gastronomy g1, Gastronomy g2) -> { return g1.name().compareTo(g2.name()); }); return list2; } La syntaxe utilise -> (light arrow) et pas => (fat arrow) comme en Scala ou en C#
  • 10. 10 Inférence de type ! Le compilateur peut calculer le type des paramétres d'une lambda ! la méthode sort() prend une liste de Gastronomy donc elle attends un Comparator<Gastronomy> private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); Collections.sort(list2, (Gastronomy g1, Gastronomy g2) -> { return g1.name().compareTo(g2.name()); }); return list2; } Le compilo n'utilise pas l'expression de la lambda pour faire l'inférence !
  • 11. 11 Exemple de lambdas (avec lambdas + inférence) private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); Collections.sort(list2, (g1, g2) -> g1.name().compareTo(g2.name()) ); return list2; }
  • 12. 12 Syntaxe: Lambda expression sans paramètre () -> System.out.println("Vive l'OL") avec un paramètre (+ inférence) employee -> employee.isManager() avec plusieurs paramètres en déclarant les types (int x, int y) -> x == y sans déclarer les types (+ inférence) (x, y) -> x == y
  • 13. 13 Syntaxe: Lambda instruction sans paramètre () -> { System.out.println("Vive l'OL"); } avec un paramètre (+ inférence) employee -> { return employee.isManager(); } avec plusieurs paramètres (+ inférence) (index1, index2) -> { list.set(index1, list.get(index2)); }
  • 14. 14 Sémantique Typé par une functional interface (ex SAM) Runnable, Callable, Filter, Function, ... Une lambda n'est pas un objet “this” représente la classe courante pas la lambda Une lambda est convertissable en un objet qui implante une functional interface Runnable r = () -> System.out.println("LOL?") objet pas objet
  • 15. 15 Et les collections ? Ici on filtre une liste, donc au lieu de private static ArrayList<Gastronomy> prefixList( String prefix, List<Gastronomy> list) { ArrayList<Gastronomy> list2 = new ArrayList<>(); for(Gastronomy gastronomy: list) { if (gastronomy.name().startsWith(prefix)) { list2.add(gastronomy); } } return list2; }
  • 16. 16 Et les collections ? On aimerait bien écrire private static List<Gastronomy> prefixList( String prefix, List<Gastronomy> list) { return list.filter(g -> g.name().startsWith(prefix)) .toList() } Operation lazy Operation pas lazy Heu, toList() sur une liste, vraiment ??
  • 17. 17 Programmation déclarative list.filter(...) .map(...) .reduce(...) on veut éviter les structures de données intermédiaire lambdas list filter map reduce list filter map reduce Création (pipeline) exécution
  • 18. 18 Programmation déclarative Permet la programmation parallèle On split les données en amont en on envoie le calcul sur différentes threads ● Disponible pour Java 8 Permet d'utiliser les GPUs On émet le code PTX/HSAIL correspondant ● Projet Sumatra (prototype avec Graal) With great power there must also come — great responsibility! L'utilisateur ne doit pas faire d'effet de bord dans les lambdas !!
  • 19. 19 Interface java.util.Stream Sequentielle ou parallele list.stream() ou list.parallelStream() Deux types de methode intermédiaire filter, map, sorted, distinct, flatMap ... terminales forEach, reduce, collect, findFirst ... L'implantation n'utilise pas de structures intermédaires mais un pipeline ! Un effet de bord, t'es mort !
  • 20. 20 Sans l'API des streams private static ArrayList<Gastronomy> prefixList( String prefix, List<Gastronomy> list) { ArrayList<Gastronomy> list2 = new ArrayList<>(); for(Gastronomy gastronomy: list) { if (gastronomy.name().startsWith(prefix)) { list2.add(gastronomy); } } return list2; }
  • 21. 21 Avec l'API des streams private static ArrayList<Gastronomy> prefixList( String prefix, List<Gastronomy> list) { return list.stream() .filter(g -> g.name().startsWith(prefix)) .collect(Collectors.toList()); } Bonus! pas besoin de déclarer la variable locale final !
  • 22. 22 Le coté sombre >= JDK8< JDK 8 Où sont passées mes belles interfaces ?
  • 23. 23 Traits Pour ajouter le support des lambdas au collections Les méthodes stream() et parallelStream() Il faut pouvoir ajouter des méthodes à une interface Il faut mettre du code dans les interfaces Don't panic Cela s'appelle des traits (trivia: les traits de Scala ne sont pas des traits)
  • 24. 24 Default methods Une méthode qui a du code dans une interface doit être taggée default Une méthode par défaut est utilisée par une classe si il n'y a pas de méthode définie ou fournie par une sous classe public interface Iterator<T> { public abstract boolean hasNext(); public abstract T next(); public default void remove() { throw new UnsupportedOperationException(); } }
  • 25. 25 Et le problème du diamand Une interface accepte du code mais pas de champs Pas de problème de redéfinition de champ donc Problème si on implante deux interfaces qui ont chacune une méthode ayant du code – Si une interface hérite de l'autre, on prend la méthode de la sous-interface – Sinon, le compilo plante interface I { default void m() { } } interface J { default void m() { } } class A implements I, J { // compile pas }
  • 26. 26 Super sur des interfaces La syntaxe, I.super.m() permet d'appeler la méthode m de l'interface I. donc pour résoudre le conflit interface I { default void m() { } } interface J { default void m() { } } class A implements I, J { public void m() { I.super.m(); } }
  • 27. 27 Retrofit Avec Java 8, l'interface java.util.List possède enfin une méthode sort (par défaut) qui appele Collections.sort :) private static List<Gastronomy> getGastronomyList(String prefix) { List<Gastronomy> list = Arrays.asList(Gastronomy.values()); ArrayList<Gastronomy> list2 = prefixList(prefix, list); list2.sort((g1, g2) -> g1.name().compareTo(g2.name())); return list2; }
  • 28. 28 Avoir une méthode intermédiaire n'est plus nécessaire, on peut tout écrire dans une seule méthode Et en utilisant Comparators.comparing() private static List<Gastronomy> getGastronomyList(String prefix) { return Arrays.stream(Gastronomy.values()) .filter(g -> g.name().startsWith(prefix)) .sorted(Comparators.comparing(g -> g.name())) .collect(Collectors.toList()); } public static void main(String[] args) { System.out.println(getGastronomyList("c")); } Exemple (suite)
  • 29. 29 Method Reference Il existe une syntaxe spécifique pour les lambdas qui appel juste une méthode g -> g.name() peut s'écrire Gastronomy::name On ne spécifie pas le type des paramètres, le compilateur utilise la fonctional interface pour les trouver Il est aussi possible de capturer une valeur Callable<String> c = "foo"::toUpperCase() System.out.println(c.call()); // prints FOO
  • 30. 30 Avec des Method References Et tout dans le main. public static void main(String[] args) { Arrays.stream(Gastronomy.values()) .filter(g -> g.name().startsWith("c")) .sorted( Comparators.comparing(Gastronomy::name)) .forEach(System.out::println); }
  • 32. 32 Compilation - Création Une référence sur une méthode est crée en utilisant invokedynamic BiFunction<String, Integer, Character> fun = String::charAt; est transformé par le compilateur en code: 0: invokedynamic lambda() #0 ()Ljava/util/function/BiFunction; 5: astore_1
  • 33. 33 Compilation - Création constants: #0: #15 invokestatic java/lang/invoke/LambdaMetafactory.metaFactory: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invok e/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHan dle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; Method arguments: #16 invokeinterface java/util/function/BiFunction.apply :(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; #17 invokevirtual java/lang/String.charAt:(I)C #18 (Ljava/lang/String;Ljava/lang/Integer;)Ljava/lang/Character; code: 0: invokedynamic lambda() #0 ()Ljava/util/function/BiFunction; 5: astore_1 Functional interface Methode de l'interface Methode référencée Signature générique réifiée
  • 34. 34 Intérêt d'utiliser invokedynamic La création de l'objet implantant la functional interface n'est pas écrite dans le code généré Peux changer en fonction des versions du JDK, des optimisations implantées dans la VM Si l'objet est constant, il peut être ré-utilisé Pour le jdk8, utilise ASM pour générer une classe proxy dynamiquement et sans vérification du bytecode
  • 35. 35 Compilation - Appel L'appel se fait en utilisant la méthode de l'interface BiFunction<String, Integer, Character> fun = ... char c = fun.apply("foo", 0); et en bytecode 7: ldc #3 // String “foo” 9: iconst_0 10: invokestatic #4 // Integer.valueOf:(I)Ljava/lang/Integer; 13: invokeinterface #5, 3 // BiFunction.apply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; 18: checkcast #6 // class Character 21: invokevirtual #7 // Character.charValue:()C 24: istore_2
  • 36. 36 Et les perfs ? / un nano-test public class HoodPerf { private static int COUNTER; private static void test() { BiFunction<String, Integer, Character> fun = String::charAt; char c = fun.apply("foobar", 5); COUNTER += c; // side effect } public static void main(String[] args) { for(int i=0; i<10_000; i++) { test(); } System.out.println(COUNTER); System.out.println(end – start); } } Ce code ne marche pas pour faire un benchmark mais ...
  • 37. 37 pour voir de l'assembleur ... {0x00007fd655851530} 'test' '()V' in 'HoodPerf' ...d64d074300: mov %eax,-0x14000(%rsp) ...d64d074307: push %rbp ...fd64d074308: sub $0x20,%rsp ...d64d07430c: mov $0xef010e68,%r10 ; {oop(a 'HoodPerf$$Lambda$1')} ...d64d074316: mov 0x8(%r10),%r8d ; getClass ...d64d07431a: mov $0xeeedaf80,%r11 ; {oop(a 'java/lang/Integer'[256] )} ...d64d074324: mov 0x210(%r11),%r11d ;*aaload ; - java.lang.Integer::valueOf@21 (line 809) ...d64d07432b: cmp $0xc6860240,%r8d ; {metadata('HoodPerf$$Lambda$1')} ...d64d074332: jne ...d64d0743e9 ;*invokeinterface apply ; - HoodPerf::test@13 (line 10) ...d64d074338: mov 0xc(%r11),%ebp ;*getfield value ; - java.lang.Integer::intValue@1 (line 871) ; implicit exception: dispatches to 0x00007fd64d074486 ...d64d07433c: test %ebp,%ebp ...d64d07433e: jl ...d64d074401 ;*iflt ; - java.lang.String::charAt@1 (line 650) ...d64d074344: cmp $0x3,%ebp ...d64d074347: jge ...d64d074401 ;*if_icmplt ; - java.lang.String::charAt@10 (line 650) ...d64d07434d: cmp $0x3,%ebp ...d64d074350: jae ...d64d0743b7 ahah charAt
  • 38. 38 Pour info, le code de String.charAt public char charAt(int index) { if ((index < 0) || (index >= value.length)) { throw new StringIOOBException(index); } return value[index]; } ...070d06a53c: test %edx,%edx ...070d06a53e: jl ...070d06a575 ;*iflt ; - java.lang.String::charAt@1 (line 650) ...070d06a540: mov 0xc(%rsi),%ebp ;*getfield value ; - java.lang.String::charAt@6 (line 650) ...070d06a543: mov 0xc(%rbp),%r10d ;*arraylength ; - java.lang.String::charAt@9 (line 650) ; implicit exception: dispatches to ...070d06a589 ...070d06a547: cmp %r10d,%edx ...070d06a54a: jge ...070d06a575 ;*if_icmplt ; - java.lang.String::charAt@10 (line 650) ...070d06a54c: cmp %r10d,%edx ...070d06a54f: jae ...070d06a562 ...070d06a551: movzwl 0x10(%rbp,%rdx,2),%eax
  • 39. 39 et encore de l'assembleur ... ...d64d074352: mov $0xef015e10,%r10 ; {oop([C)} ...d64d07435c: movzwl 0x10(%r10,%rbp,2),%ebp ;*caload ; - java.lang.String::charAt@27 (line 653) ...d64d074362: cmp $0x7f,%ebp ...d64d074365: jg ...d64d074411 ;*if_icmpgt ; - java.lang.Character::valueOf@3 (line 4570) ...d64d07436b: cmp $0x80,%ebp ...d64d074371: jae 0x00007fd64d0743c9 ...d64d074373: mov $0xeef0e828,%r10 ; {oop(a 'java/lang/Character'[128] )} ...d64d07437d: mov 0x10(%r10,%rbp,4),%r10d ;*aaload ; - java.lang.Character::valueOf@10 (line 4571) ...d64d074382: test %r10d,%r10d ...d64d074385: je ...d64d0743d9 ;*invokevirtual charValue ...d64d074387: mov $0xeef05ab8,%r11 ; {oop(a 'java/lang/Class' = 'HoodPerf')} ...d64d074391: mov 0x58(%r11),%r11d ;*invokestatic valueOf ...d64d074395: movzwl 0xc(%r10),%r10d ...d64d07439a: add %r10d,%r11d ...d64d07439d: mov $0xeef05ab8,%r10 ; {oop(a 'java/lang/Class' = 'HoodPerf')} ...d64d0743a7: mov %r11d,0x58(%r10) ;*putstatic COUNTER ...d64d0743ab: add $0x20,%rsp ...d64d0743af: pop %rbp ...d64d0743b0: test %eax,0x9006c4a(%rip) # ...d65607b000 ; {poll_return} ...d64d0743b6: retq Ça sert à quoi ?? charAt
  • 40. 40 ... en résumé Une méthode référence (ou une lambda) qui ne fait pas de capture est une constante L'appel a une lambda peut être dévirtualisé et inliné comme n'importe quel appel Le code montré est celui générer par le jdk8b88-lambda avec elision du boxing/unboxing desactivé :(
  • 41. 41 What's next ? Updates du JDK8 lambda constante sans check de classe lambda non-constante mieux dévirtualisée Java 9 Value Object Integer, Float, etc ne devrait pas avoir d'identité => pas sûr que cela marche Utilisation du/des GPUs dans les Stream parallele
  • 42. 42 Questions ? JDK8 Feature Freeze jeudi prochain ! les lambdas sont déjà dans le JDK ! https://jdk8.java.net/download.html Remonter les bugs sur la mailing list: lambda-dev http://mail.openjdk.java.net/mailman/listinfo/lambda-dev ou bugs.sun.com