4è Geneva JUG : Lambda J

L'URL courte de cet article est : http://inagua.ch/JIqlV

Désolé pour le délais, mais ces dernières journées ont été chargées…

lambdaj

Mardi 27 avril… En arrivant, je croise Chrislain qui attend dehors… Evidemment pour un fan de Clojure ;)… Lui au moins, il est venu, contrairement à mon associé ;)


18h38, ce nouveau JUG commence…. Xavier me fait l’honneur d’attendre après moi :

  • Xavier : ” J’attend que tu sois prêt pour démarrer, car il y a des news ! “
  • Jacques ” J’attend que mon MacAir démarre… “

… Ca y est, je suis une star ;))… Cela mérite bien une petite photo prise sur le vif !

jug4-xavier

A ce propos, je tenais à remercier tout particulièrement le JUG et Xavier, car grâce à eux, et à vous, lecteurs, nous avons fait une pointe de 161 consultations uniques sur le post du dernier JUG Maven.

Plus sérieusement, “seulement” 38 personnes dans la salle cette fois… Ceci est un premier indicateur ! Avec ces langages fonctionnels, on semble loin des préoccupations des développeurs Java “mainstream”.

A moins que ça ne soit la peur de l’anglais ?…

Mise en bouche

C’est parti, Xavier prend la parole. Il annonce ce nouvel “exercice” assuré par le JUG : la revue de livre. La première est celle de Nicolas Frankel, sur le livre d’Arnaud dont nous avions parlé au dernier JUG : Apache Maven.

Je trouve cet exercice très intéressant. Une bonne idée… A voir comment cela va évoluer ?… Comment cela va être exploité ??

Puis Xavier annonce un nouveau sponsor annuel : Genesis, le 6e.

Il présente ensuite les résultats du sondage :

  • 72 réponses
  • 86% pour les technos google
  • 72% pour le langage de la jvm scala
  • Enfin : ” 3 ME TROUVENT NULS, j’en connais 2 ;)) “

Il y a 5 gagnants !… dont Andrew qui arrive juste a ce moment : quelle synchronisation !

Puis vient la traditionnelle mise à nue : le précédent gagnant du t-shirt Atlassian relève son pull et bombe fièrement le torse pour l’exposer à l’auditoire ;)

Xavier enchaine avec l’agenda à venir :

  • le JUG de mai : les technos Google par Didier Girard
  • jazoon debut juin
  • le 9 juin : le Dev Day iPhone (GJUG pour pour le code)… Depuis, il a encore été reporté au 23 juin.
  • le JUG de juin : Glassfifh v3
  • le JUG de fin aout : Flex et Java Pascal Romanens
  • soft-shake.ch en octobre (on y travaille… plus de news dans quelques jours…)

Concernant ces news, Xavier ajoute que certains n’aiment ni linkedin ni twitter…… Il va donc certainement créer un google group.

C’est ensuite au nouveau sponsor de prendre la parole… Le mot de Christophe pour Genesis… et 8 slides !… Pourquoi pas Marc-Elian ?… Sacré Daniel, son équipe attaque en force ;)

La session

18h53… Mario prend la parole, venu en voiture de Lugano !

Il travaille chez exmachina.ch / EXM

Il commence en nous avouant que son portable à planté hier soir et que du coup il a essayé de le récupérer… Sans succès. Il a donc du, le coeur lourd, se dépanner avec un PC sous Windows… Une larme chaude coulait sur sa joue, accompagné de noms d’oiseaux, alors qu’il nous vantait tout le bien qu’il pense de Windows ;))

Le premier slide sur Lambda J annonce : “An international DSL to manipulate without loops”

Mario nous dit que la meilleure façon de comprendre ce langage et de voir comment il est né : chez Generali à Londres. La logique métier est plus ou moins toujours la même :

  • on fait un tri sur une propriété
  • selon une règle

On boucle souvent sur des collections. Or ces boucles très dures à lire : le code est souvent plus dur à lire qu’à ecrire.

J’aime bien cette remarque : ” Le logiciel est souvent plus dur à lire qu’à écrire “. On touche là toute la problématique d’un code simple, de ce thème abordé par l’agilité et l’eXtreme Programming, ou encore par des livres comme ” Clean Code “. Autant XP prône “une conception simple” et “des standards de code”, autant on finira toujours par buter au final sur le langage, si ce dernier n’est pas “limpide”. Je relativiserais cela, avec la notion d’habitude : je pense que le plus simple bout de code Lambda J, paraitra plus austère à un expert Java que n’importe quel bout de code Java…

Le but est d’écrire la logique business le plus près du métier : facile à lire !

Pour ma part, j’ajouterais que la Quête agile du Saint Gral, à savoir un code lisible par le business, n’est pas uniquement pour faciliter la lecture. L’objectif sous jacent et moteur, est que le business puisse arriver à valider les fonctionnalités en relisant le code. C’est pour cela que l’on cherche à écrire des tests fonctionnels qui soient 1) automatisables (mais là, c’est encore une autre histoire ;) et 2) lisibles par le client XP, afin que ce dernier, en validant le test, valide que la fonctionnalité est implémentée et correctement implémentée (si le test passe). On parle bien du code, et non pas d’une spécification, car cette dernière devra être interprétée par le développeur pour être réalisée, introduisant un risque d’écart, et un bug dans la réalisation.

Par le contre je rejoins totalement Mario qui dit qu’un code plus lisible est un code plus (aisément) maintenable.

A nouveau cette phrase qui présente Lambda J comme un DSL pour manipuler des collections, pseudo fonctionnel avec les actions standard :

  • convert
  • filter
  • sort
  • group
  • index
  • aggregtate
  • extract

Une petite remarque au passage : Mario aurait peut-être du définir en début de présentation ce qu’est un DSL. Au moins donner la forme développée de l’acronyme (Domain Specific Language), voir ce que cela sous-tend… Sans parler de l’opposition aux General Purpose Languages, mais au moins aborder le fait que : “ On s’est beaucoup intéressé aux langages dédiés pour améliorer la productivité et la qualité de l’ingénierie logicielle. Les langages dédiés peuvent fournir un ensemble robuste d’outils pour une ingénierie logicielle efficace. De tels outils commencent à faire leurs preuves dans le développement du logiciel associé à des systèmes critiques. ” (Wikipedia).

L’agiliste que je suis est lui très intéressé par les DSL essentiellement dans le cadre des frameworks de tests qui commencent à se répandre. Ils permettent d’écrire des tests (unitaire ou fonctionnel) qui soient quasiment lisibles par un non développeur. Au delà du DSL, il y a même la notion de DDD, pour Domain Driven Development, qui commence à se propager (n’est-ce pas Benoit C. ;).

Seul interrogation de ma part : il y a quelques années, quand on parlait de DSL, les gens nous regardaient bizarrement. Aujourd’hui, le simple fait d’écrire 3 méthodes / helpers qui encapsulent des détails techniques et on se vente d’avoir écrit un DSL !…

Mario insiste sur le fait que Lambda J a vu le jour dans une compagnie d’assurance, lieu par excellence de l’informatique de gestion.

Il poursuit en expliquant que ce langage est basé sur deux fonctionnalités clefs :

  1. Manipuler une collection comme si c’était un bean
  2. Permettre de définir un pointeur de fonction

Le premier point permet d’écrire l’exemple de code suivant (on peut chainer les appels) :

forEach(personsInFamily).setLastName("Fusco");

Cela passe par un proxy (dynamique) : la méthode static forEach retourne un proxy du simple bean et propage la méthode appelée sur les beans de la collection.

Quand au second point, un bon exemple est le tri de collection :

sort(persons, on(Person.class).getAge());

19h05 : Le slide “That’s all falks !…” nous indique que c’est la fin de la théorie, Mario d’ajouter pour insister : “C’est tout ce que vous avez à savoir pour comprendre le fonctionnement de Lambda J”.

Les slides qui suivent nous exposent alors des exemples de code comparé (entre code “itératif” (java classique) et Lambda J), que nous commente Mario.

Ces exemples reposent sur une même modèle d’objets : un vendeur de voitures.

Bonne idée ce code comparé !

1er exemple

Concaténer la marque des voitures

  • Le code Java prend 4 lignes (et sans mettre d’accolades dans le for… c’est mal !!)
  • Pour 1 ligne en LambdaJ :
String brands = joinFrom(db.getCars()).getBrand(); // joinFrom renvoie un proxy

2e exemple

Choisir toutes les Ferrari

  • 4 lignes en java (et sans les accolades dans le for… ET dans le if… c’est TRES mal !!)
  • 1 ligne en LambdaJ

Avec ce second exemple, j’ai déjà quelques impressions…

Certes en Lambda J cela ne prend qu’une seule ligne “logique”… Mais qui s’écrit sur plusieurs lignes physiques car c’est verbeux !… Il n’y a plus de End-Of-Line / Retour-chariot. Se pose alors la question de “Où je coupe la ligne ?” et tous les soucis de conventions de code et d’habitude à la lecture qui vont avec. N’étant pas habitués, sommes nous prêts à lire ces longues lignes de code ?

Par contre cela se lit à haute voix comme de la prose anglaise ! C’est cool !

De coup, je me demande “Quid de la coloration syntaxique ?”… Je poserais la question a la fin !

Une première question fuse alors.

  • Question> Est ce que le select fait un appel à chaque fois ??
  • Mario> “Off course !” répond Mario, en ajoutant : on a une perte de performance avec Lambda J car il y a de la retrospection, des proxy dynamiques, de nombreux parcours de collections…

D’autres exemples, avec leurs snippets de code, se succèdent…

J’apprécie ces exemples de code, mais regrette que Mario se contente de slides sans dérouler ses exemples en temps réel, qu’il manipule du code directement dans une console ou un IDE. L’avantage des slides est qu’ils nous permettent d’avoir sur un même, côte à côte, les deux portions de code (Java et Lambda J).

Dans l’un de ses exemples, il parle de matcher… Cela me rappelle RSpec… Justement un de ces harnais de test issu du monde Ruby On Rails, et qui offre un DSL !

Encore d’autres exemples…

A mesure que ces exemples précis se succèdent, cela précise mon sentiment.

En java on ne lit pas directement le fonctionnel du code, par contre la structure saute au yeux : On a un for avec un if dedans, on comprend donc qu’on est en présence d’une itération avec une condition… Après on va voir de plus près sur quoi on itère (sachant que la signature de la fonction peut permettre de déjà connaitre la réponse), on peut donc se focaliser sur la condition du ” if “.

Il me semble que l’on perd cette vue macroscopique, de haut niveau avec Lambda J. On a une phrase de plusieurs lignes avec une succession de mots.

En itératif (java “classique”) on voit la tactique au premier abord… Sans voir la technique… En Lambda J on ne voit pas du tout la technique (dissimulée sous le DSL), mais la tactique semble moins sauter aux yeux, est moins visuelle.

Je me focalise sur la lisibilite car :

  1. c’est un des arguments avancés par le speaker
  2. c’est très important pour l’agiliste xp que je suis

Autre exemple

Trier les ventes par coût

L’avantage en Lambda J, est que pour les tris on ne crée pas d’annonymous class (new Comparator()) en :

Question de Mario : Comment ça marche en interne ?…

Réponse de Mario : Beaucoup de proxy dynamiques créés partout…. Il vaut mieux comprendre comment ca fonctionne… car :

  • cela évite de faire des erreurs
  • c’est cool

Ce deuxième point fini d’enlever le doute à ceux qui en aurait encore : Mario est un amoureux du code ;)

Car fastestCar = max(forEach(sales).getCars(), on(Car.class).getSpeed());
  • forEach(sales) : retourne une classe de type Sale qui implemente aussi Iterable
  • forEach(sales).getCars() : un autre proxy est cree

Suite à la question d’Andrew, Mario rapproche les proxy dynamiques à la programmation par aspect…

A chaque fois que Lambda J crée une collection il crée aussi un proxy pour pouvoir faire des appels dessus.

  • on(Car.class) cree un proxy sur la classe pour memoriser l’appel

Une question est a nouveau posée :

  • Q> Les proxy sont dans le permspace de java et ce n’est pas fait pour cela… Trop de proxy créés peuvent être difficiles à gérer ?
  • Mario> Pour les JDK 5 et 6, pas besoin de gérer les pools : c’est un faux problème !

On en vient à parler de garbage collector ?!… C’est dingue : pour avoir fait à peine moins de C++ que de Java dans ma carrière (en terme de durée), je n’ai pas eut le 10e des problèmes/bugs sur gestion de la mémoire en C++ de ce que j’ai rencontré en Java !!! Ce Léon, un nettoyeur automagique, qui devrait régler tous mes problèmes, fait que le développeur lambda (sans rapport avec le langage ;), ne se préoccupe pas du tout de la gestion de la mémoire… Et quand il y a de vrais problèmes, on est obligé de mettre en place des stratégies de garbage collector qui nécessitent d’être 3 ème dan en gestion de la mémoire et GrandGuru++ en Vaudou… Sans parler de ces hacks de contournement avec des weaks références !…

Puis vient un slide intéressant avec un tableau comparatif sur les performances entre itératif et Lambda J : un facteur 5 (fois plus lent en Lambda J) en moyenne… Et Mario insiste sur le fait que ces résultats sont ce qu’il a obtenu de mieux après un travail d’optimisation en Lambda J.

jug4-mario

Il ajoute alors : ” Est-ce un problème ces performances ?… Ca dépend ! ” :

  • Prenons l’exemple d’hibernate et de spring… Ils utilisent cglib, et souffrent donc du même genre de ralentissement. Développer plus rapidement vient avec un prix ! Ici, le runtime est effectivement plus lent car il y a beaucoup de réflexion Java pour peupler les beans, des proxy dynamiques… C’est le prix pour un code plus lisible.
  • De plus, sur 95% de vos applications, la performance n’est pas le goulot d’étranglement. C’est d’avantage l’accès à la base de données, les I/O…

J’ai bien aimé sa franchise et sa lucidité ! Il est vrai qu’on pourrait faire ce même slide pour Hibernate et pour Spring… Je pense que l’on aurait ce même ordre de grandeur de performance entre un code sans Spring ni Hibernate, et un code utilisant ces frameworks… Pourtant, je ne suis pas sûr d’arriver à convaincre une seule équipe, un seul architecte, d’abandonner Spring et/ou hibernate, avec l’unique argument que son code sera plus rapide !…

Par contre, je connais quelques développeurs qui me paieraient cher pour que j’arrive à convaincre leur hierarchie d’abandonner ces frameworks car ils transforment leur application en une usine à gaz ou la moindre intervention est devenue une punition… Là, pour le coup, on a l’inconvénient du framework et l’effet inverse de ce qu’il devait apporter : une application lente et pourtant un code non maintenable… C’est paradoxal, non ?

Mario en vient à parler des limitations de Lambda J :

  • ” lack of reified generics ” : on a une exception si le paramètre de forEach est null ou vide
  • il est impossible de générer un proxy sur une classe finale

En voyant ces exemples avec des exceptions et en repensant à ces frameworks (hinernate, spring…) : je me pose la question de la lisibilité de la stack trace des exceptions dues à notre code ? Il n’est en effet pas rare en JEE de tomber sur une trace d’exception qui n’apporte absolument aucune information sur la cause véritable de l’erreur, ce qui est bien dommage pour les développeurs que nous sommes. Je me demande donc comment cela se passe avec Lambda J, étant donné qu’il génère également des proxy intermédiaires et use abondamment de l’introspection.

… C’est une autre question à poser à la fin !

Une nouvelle question :

  • Q> Le type de l’élément d’une collection est inféré sur le 1er élément de la collection : quid si la collection contient des éléments de classes différentes ?
  • Mario> ClassCastException !

Cela termine la première partie… Mario prend ensuite un peu plus de hauteur, regarde vers l’avant…

Il se confie : “J’ai étudié Scala à l’école, et j’ai adoré… En venant à Java : il me manquait quelque chose ! “…

Il enchaine en parlant de la grande nouveauté dans Lambda J 2.0 : Closures.

En fait, ce ne sont pas des closures à proprement parler. Lambda J offre des fonctions de 1ere classe… Du coup, je pourrais me dire “Pourquoi ne pas tout jeter et prendre les closures dans java… Mais ca fait 4 ans que j’attend… Et il n’y a toujours pas de consensus en perspective.”

Lambda J offre donc la possibilité d’écrire des closures, ou fonction de 1ère classe, avec pré-compilation :

  • closure factory methode : closure()
  • Closure println = clorsure(); {
       of(System.out).println(var(String.class));
    }
  • invocation unique :
  • println.aplly("one");
  • ou plusieurs fois :
  • printl.each("1", "2", "3");
  • typed closes :
  • Closure2<Integer, Integer> adder = closure(...
  • Curry… Là, la plupart se regardent avec des grands yeux en se disant “Là, on l’a perdu !”… Il lance alors un “Qui connaît curry ?…” Effectivement pas grand monde !

Curry… C’est de la programmation fonctionnelle :

Closure1<Integer> adder10 = adder.corry2(10);

Les accolades sont du “sucre syntaxique” : il prend ce qu’il trouve dans le of() et l’envoie dans un autre thread

Les fonctionnalités :

  • 1)) Keep unbound the object on which the closure is invoked
  • 2)) Define a closure without use a ThreadLocal

20h18 : un grand moment !… Mario veut alors écrire un bout de code à la main… sur le tableau… Il sort une craie blanche et écrit sur un *vrai* tableau noir ! Pour une session sur une techno. naissante… Je crie à l’anachronisme… Cool ;))

List<P> ps =  new ArayList<Pp> {{
add(me)
add(him)
}}

Et une question :

* Q> Quelles sont les questions contre ThreadLocal ?

* Mario> Well… Code smell en programmation concurrente…

  • 3)) Define the invocation of a static method
  • 4)) or a constructor : the factory pattern

Puis quelques mots sur les switcher…

Scala et le pattern matching c’est tres puissant !

Ok ça peut sembler lourd à cause de toutes ces accolades… Mais c’est a cause de java : en Scala c’est limpide !

Encore et toujours ce verbeux java qui est en cause… Et je partage !… Je pourrais refaire un post à ce sujet…

Autre point : pas mal le pattern Stratégie rapidement implémenter… D’où cette question qui germe dans mon esprit : un “bon” langage serait-il un langage où l’on peut simplement implémenter un design pattern ?

20:36 : fin des réjouissances !

Mario nous donne l’URL du projet :

code.google.com/p/labdaj

Et quelques chiffres sur les dernières release… Pas mal pour un one-man-project !

Il insiste à nouveau sur le fait que le gros travail du développeur en informatique de gestion est de manipuler des collections !… Il est vrai, je n’avais pas encore réalisé.

Finalement, tout le monde semble pressé que la présentation s’arrête. Je ne vais donc pas poser mes questions.

20h43 : Applauses !

20h44 : La lumiere se rallume… ouf ! Un peu assommé, je suis.

Et Mario de conclure : ” You have to switch to Scala ! “

Aaaaah, c’est présentation c’était pour ça : nous convertir à Scala ! Le bougre ;)

… Du coup, la lumière aidant, les premières conclusions arrivent dans ma tête…

Pour que cela fonctionne, il faut un éditeur à la hauteur ! Pour ceux qui ont lu mon post sur Play!, ils savent l’importance que je donne aux IDE… Coloration syntaxique, reformatage, mais aussi refactoring…

Vient la tombola :

  • le tee shirt Atlassian
  • Olivier Lange qui rate la licence JRebel (de toute façon il ne la mérite pas, n’est-ce pas Olivier ;)
  • Puis la licence IntelliJ pour… Genesis… Sacré Christophe : il va devoir passer de .Net à Java ;) Même si je suis témoin de l’impartialité du tirage au sort (surtout connaissant Xavier), je ne peux m’empêcher de crier ” Ouuuuuh ! Collusion avec les sponsors ! “… Non content de truster les livres offerts en fin des Agiles Tour, Genesis trust les licences ;))
  • Enfin l’ebook : Jordan et Chris, nos précédents gagnants, sont de nouveau tirés au sort !

On se donne RDV la prochaine fois, exceptionnellement pas le dernier mardi du mois, mais le lundi 17 mai… La semaine prochaine, déjà !

Toute fin à 20h49.

Conclusion de l’auteur… Euh c’est à dire moi !

Prenons un peu de recul…

Je viens de passer 2h de session vraiment technologique, sur un domaine que je connaissais peu… C’est dur après la journée de boulot !

Au final, une belle présentation, où j’ai appris de nouvelles choses… Dommage que Mario n’ait pas montré de code en live mais que des slides (on mettra cela sur le dos de son portable qui a craché la veille ;) !

L’argument qui revient souvent dans la bouche de Mario est que le code est plus court… Pour ma part, je dirais surtout qu’il est :

  1. Plus dense
  2. Plus ” human readable

Globalement, on transforme N courtes lignes (logique et physique) du Java itératif (traditionnel) en une ligne Lambda J que l’on lit comme de la prose anglaise : une ligne logique qui tient sur plusieurs lignes physiques, tout comme la prose.

Ce qui me fait aborder l’autre argument de Mario : ” C’est plus facile à lire ! “. Là, je relativiserais. Autant, entre un développeur .Net qui se met à Java (et inversement), la lisibilité du code reste la même, autant passer de Java à Lambda J, ça dépend vraiment de l’habitude : j’ai presque envie de comparer Java (ou .Net) à des prises de notes, elliptiques sous forme de liste, et Lambda J à un texte pleinement rédigé. Chacun sa préférence. Comme disait Coluche : ” les goûts et les couleurs… ” ;)

Forcément, l’autre question qui découle de cela, ce sont les conventions de code ! Où je mets le 3 ème argument ? A la ligne ? Avec une tabulation ? Vous pouvez penser que je chipote sur des détails, mais le développeur eXtreme Programming que je suis sais que cela est vital pour un code homogène dans l’équipe (donc facilement maintenable par n’importe quel développeur).

Mais le fan des DSLs que je suis, surtout dans les tests automatisés, apprécie ce langage, pour la syntaxe des exemples simples (quid de la maintenance quand le code se complique ??). Et la perte de performance me semble dérisoire à la vue de ce que cela apporte. Par contre, si on veut vraiment aller dans le sens d’un langage fonctionnel, avec les forces que cela implique, pourquoi rester tributaire d’un langage lourdaud comme Java ? Pourquoi ne pas faire le pas complètement ?…

En tout cas merci d’avoir fait le déplacement de Lugano !

On se revoit donc dans une semaine… Et encore une fois, vos feedback / commentaires sont les bienvenus !

Ah, j’allais oublié… L’orga a demandé notre feedback sur l’organisation elle même :

  1. Chapeau pour le buffet ! Je suis bien placé que c’est chaque fois un défi… Bien maitrisé dans votre cas.
  2. Peut-être bien définir les règles dés le départ… Je pense notamment à la timebox : Mario ne semblait pas trop savoir combien de temps il avait… Et puis même avec l’auditoire : c’est important, je pense, de définir un “contrat” et de le respecter.
  3. Mettre l’adresse et le plan du lieu de rencontre sur le site du Geneva JUG.

Note de l’auteur : je fais exception à la règle en n’ayant pas soumis ce post à relecture auprès de l’orateur, mais cela est du au fait qu’il ne parle pas français.


L'URL courte de cet article est : http://inagua.ch/JIqlV

3 réflexions au sujet de « 4è Geneva JUG : Lambda J »

  1. Merci pour ce compte-rendu, excellent comme d’habitude !

    et Mario avait bien prévu de nous faire des démos de code mais malheureusement il a tout perdu dans le crash de son portable la veille …

  2. I don’t speak french, but I can read it quite well. Don’t forget we had 2 centuries of french domination in South Italy and for this reason my hometown dialect it is very similar to french.

    I am sorry I hadn’t a chance to show some live code. But if somebody will be in San Francisco in September he will see it there. They just notified me that they accepted my talk about lambdaj at JavaOne :)

    You’re right, I took DSLs too much for granted. This is a good advice for my next talks.

    To reply to your question about exception handling in lambdaj, the library tries to recognize unwanted behaviors and to rethrow any exception wraping it in a (possibly) more readable one. Of course this is not always possible and sometimes you will have to face with some very hard to decode errors.

    Thanks a lot for this extremely complete resume and to all the JUG guys for the wonderful hospitality.

    Let’s stay in touch.

    Bye
    Mario

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*


*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>