Clojure  (oubliez vos préjugés)Christophe Grand @cgrandLaurent Petit @petitlaurentMix-it 2011, 5 avril
Motivations
MotivationsRéduire complexité accidentelle
Réduire la complexité accidentelle"Out of the tar pit" ( http://ben.moseley.name/frp/paper-v1_01.pdf )   Distinguer la com...
Réduire la complexité accidentelle   "Out of the tar pit" ( http://ben.moseley.name/frp/paper-v1_01.pdf )      Distinguer ...
Réduire la complexité accidentelle   Simple        fiable     orthogonal   peu de syntaxe   peu de concepts  peu de surpri...
MotivationsRéduire complexité accidentelle   Programmation concurrente
Programmation concurrenteMécanismes de bas niveau (lock, synchronized)OOP introduit de la complexité  Myriades de petits é...
MotivationsRéduire complexité accidentelle   Programmation concurrenteExpressivité maximale
Expressivité maximale du langageConcision  Le moins "cérémonieux possible" !Factorisation   Oser passer aux génériques !Ad...
Expressivité maximale du langageApproche combinée Top Down et Bottom Up   Décomposition fonctionnelle .... (top down)   Ma...
Expressivité maximale du langageEncore 1 fois, lOOP par défaut est dans le collimateur !   Plus difficile de généraliser l...
MotivationsRéduire complexité accidentelle   Programmation concurrenteExpressivité maximale                 Langage généra...
Langage généralistePlateforme industrielle   interopérable   performant   déployable   réutilisation de lexistantPas un la...
MotivationsRéduire complexité accidentelle   Programmation concurrenteExpressivité maximale                    Langage gén...
MotivationsRéduire complexité accidentelle   Programmation concurrenteExpressivité maximale                    Langage gén...
MotivationsRéduire complexité accidentelle   Programmation concurrenteExpressivité maximale                    Langage gén...
Caractéristiques
CaractéristiquesBase fonctionnelle
Base fonctionnelle"It is better to have 100 functions operate on one datastructure than to have 10 functions operate on 10...
Base fonctionnelle Sans hypothéquer le pouvoir dabstraction/indirection    Fonctions en paramètres    Fonctions en valeur ...
CaractéristiquesBase fonctionnelleEtats Managés
Etats managésLa base fonctionnelle seule est insuffisanteBesoin dorchestrer la mutation des états   Pour écrire des progra...
Etats managés   Séparation stricte identité / valeur   Identité = stable au cours du temps   Etat = Valeur des caractérist...
CaractéristiquesBase fonctionnelleEtats ManagésLisp
LISPSyntaxe simple et uniformeRapproche donnée et code   "Data is code, and code is data"   En utilisant les macros à la c...
LISPDynamique   REPL = "Read, Eval, Print, Loop"      Le code est évalué (en fait compilé) ligne à ligne      On peut cont...
CaractéristiquesBase fonctionnelleEtats ManagésLispJVM
JVM JVMpragmatisme                   Compiléécosystème                 interactif ou AOT entreprise               *warn-on...
JVM                InteropZéro overhead   java.util.*   Runnable & Callable
CaractéristiquesBase fonctionnelleEtats ManagésLispJVM
Syntaxe
Commentaire ; ligne             #_(bloc de code)         Chaîne "Bonjour Lyon !nBonjour Mix-IT !"       Nombres 42 2/3 3.1...
Commentaire ; ligne             #_(bloc de code)         Chaîne "Bonjour Lyon !nBonjour Mix-IT !"    java.lang.String     ...
Fonctions
Fonctions "anonymes" : définitions       Explicite :       (fn [args] ...code...)
Fonctions "anonymes" : définitions       Explicite :       (fn [args] ...code...)       Contractée 1 argument :       #(fo...
Fonctions "anonymes" : définitions       Explicite :       (fn [args] ...code...)       Contractée 1 argument :       #(fo...
Fonctions "anonymes" : définitions                              Explicite :                              (fn [args] ...cod...
Fonctions "anonymes" : UtilisationExemple 1 : Ajoute 2 à tous les éléments dune séquence(map f s) => Transforme la séquenc...
Fonctions "anonymes" : UtilisationExemple 2 : Somme totale des tailles des éléments duneliste(reduce f val s) => Calcule u...
Fonctions "anonymes" : UtilisationExemple 2 : Somme totale des tailles des éléments duneliste; Forme expliciteuser=> (redu...
Fonctions "anonymes" : UtilisationExemple 2 : Somme totale des tailles des éléments duneliste; Forme expliciteuser=> (redu...
Fonctions globales et constantes  Déclarées dans un espace de noms, un "namespace"    ~ package  Documentation en ligne, i...
Structures "persistantes"  (not= "Persistant" "stockage disque")Valeur originale persiste après "modification"   undo for ...
Structures "persistantes"user=> (def v1 [:a :b :c])#user/v1user=> (def v2 (assoc v1 0 :A))#user/v2user=> [v1 v2][[:a :b :c...
Structures "persistantes" : opérations       génériquesCollections      count, conj, seq                 vector, vec, get,...
Structures "persistantes" : exempleuser=> (def mix-it         {:ou "Lyon",          :stats {:participants 198,            ...
Orthogonalité
Orthogonalité : (lazy) sequencesIterators done rightVue sequentielle dune collection  fonction seq => vue "naturelle"  dau...
Orthogonalité : (lazy) sequencesAbstraction dune liste liée : 3,5 fonctions   constructeur   (cons 1 (cons 2 nil)) => (1 2...
Orthogonalité : (lazy) sequences3 fonctions et demi ?    rest vs next    lazinessMajorité des séquences lazy   non simulta...
Orthogonalité : lazy sequences
Clear upgrade path                     Accès uniforme aux champs                     Polymorphisme non intrusif
Accès uniforme aux donnéesImplémentation plus ou moins évoluée ...   Donnée non typée :(def dnt {:nom "Mix-it", :participa...
Polymorphisme non intrusifCe matin, un lapin ...(defn mk-lapin [couleur]  {:espece :lapin, :couleur couleur})(defn mk-chas...
Polymorphisme non intrusifVersion 1: fonction simple, combinaison despècescombinables close   (defn croise [x y]    (condp...
Polymorphisme non intrusifVersion 2: Multiméthodes = dispatch en fonction desarguments = "héritage simple on steroids"(def...
Polymorphisme non intrusif          Fait remarquable : Code appelant identique dans les 2 cas     user=> (croise     l1 l2...
Polymorphisme non intrusif         Fait remarquable 2 :multiméthodes extensibles et redefinablesintroduire :lapine héritan...
Gestion des états
Mutable stateful objects are thenew spaghetti code:   Hard to understand, test,   reason about   Concurrency disaster
Concurrent  threadsafe    managé    GC-like
Gestion saine des étatsPas que pour le multithreadEtat : ensemble des valeurs prises par toutes lesvariables dun système à...
Confusion valeur identitéQui na jamais douté dune lib tierce ?   A-t-elle garder une référence sur mon objet ?   Cet objet...
Confusion valeur identitéMap container = new HashMap();Map a = new HashMap() {   {this.put("a", 1); this.put("b", 2);}};Ma...
Confusion valeur identitéQuestion clé :Cet objet est-il la valeur présente ou est-il mis à jourpar ailleurs ?Pas de confus...
Confusion valeur/identitéFaut que ça change !   Tout est immuable   Sauf les référencesUne référence est juste une boîte  ...
Le cadeau BonuxRéférences en tant quobjets   first class        passables en paramètre        ou valeurs de retour        ...
Le cadeau Bonuxjava.lang.ref.*   ajoute une logique spécifique pour la   gestion mémoireRéférences Clojure   ajoutent une ...
Le cadeau Bonux  Modèle unifié    @ ou deref pour lire    toujours la même signature pour les    fns de mise à jour(def un...
Y en a unpeu plus, jevous le metsquand même ?
Pour en savoir plusclojure.orgdisclojure.org – excellent daily digestquelques librairies : ring, incanter, compojure, enli...
Questions
(let [prejuge        (= LISP "Lots of Irritating                 Superfluous Parentheses")]  (not= Clojure prejuge))      ...
(let [prejuge        (= LISP "Lots of Irritating                 Superfluous Parentheses")]  (not= Clojure prejuge))Java :...
(let [prejuge        (= LISP "Lots of Irritating                 Superfluous Parentheses")]  (not= Clojure prejuge))Java :...
Orienté Objet   Nous pouvons le reconstruire,Nous en avons la possibilité technique
Mix it 2011 - Clojure
Prochain SlideShare
Chargement dans…5
×

Mix it 2011 - Clojure

2 449 vues

Publié le

Clojure introduction given during the French Mix it 2011 event.

Publié dans : Technologie
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
2 449
Sur SlideShare
0
Issues des intégrations
0
Intégrations
960
Actions
Partages
0
Téléchargements
11
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Mix it 2011 - Clojure

  1. 1. Clojure (oubliez vos préjugés)Christophe Grand @cgrandLaurent Petit @petitlaurentMix-it 2011, 5 avril
  2. 2. Motivations
  3. 3. MotivationsRéduire complexité accidentelle
  4. 4. Réduire la complexité accidentelle"Out of the tar pit" ( http://ben.moseley.name/frp/paper-v1_01.pdf ) Distinguer la complexité inhérente de laccidentelle"Le mythe du mois-homme" ( Frederick P. Brooks, Jr.) Ch. 16: "Pas de balle dargent: lessence et la substance en génie logiciel"
  5. 5. Réduire la complexité accidentelle "Out of the tar pit" ( http://ben.moseley.name/frp/paper-v1_01.pdf ) Distinguer la complexité inhérente de laccidentelle "Le mythe du mois-homme" ( Frederick P. Brooks, Jr.) Ch. 16: "Pas de balle dargent: lessence et la substance en génie logiciel""Comme Aristote, je divise [les difficultés de la technologielogicielle] en essence - celles qui sont inhérentes à lanature du logiciel - et en substance - celles qui gênentaujourdhui sa production, mais ny sont pas inhérentes." (F. P. Brooks dans Le mythe du mois-homme)
  6. 6. Réduire la complexité accidentelle Simple fiable orthogonal peu de syntaxe peu de concepts peu de surprises larges abstractions
  7. 7. MotivationsRéduire complexité accidentelle Programmation concurrente
  8. 8. Programmation concurrenteMécanismes de bas niveau (lock, synchronized)OOP introduit de la complexité Myriades de petits états répartis très difficiles à manipuler de manière cohérente"#antioopargs OO, as practiced e.g. in Java,conflates identity, state and behavior" @stilkov, expert java reconnu
  9. 9. MotivationsRéduire complexité accidentelle Programmation concurrenteExpressivité maximale
  10. 10. Expressivité maximale du langageConcision Le moins "cérémonieux possible" !Factorisation Oser passer aux génériques !Adaptation "Si le problème ne vient pas au langage, le langage ira au problème" !Degrés dabstraction Rester dans le langage, en bonne compagnie !
  11. 11. Expressivité maximale du langageApproche combinée Top Down et Bottom Up Décomposition fonctionnelle .... (top down) Mais construction dun "langage" pour le domaine du problème (bottom up) Equivalent des APIs dites "fluent" en java /* exemple dAPI "fluent" dans JPA */ em.createNamedQuery("Student.findByNameAgeGender") .setParameter("name", name) .setHint("hintName", "hintValue") .getResultList(); = mini-langages "embarqués" (DSLs)
  12. 12. Expressivité maximale du langageEncore 1 fois, lOOP par défaut est dans le collimateur ! Plus difficile de généraliser les algorithmes Plus cérémonieux Mais ne pas jeter le bébé avec leau du bain"Composition, interfaces, héritage : 2 bonnes idées sur 3,pourquoi tt le monde est parti avec la 3ème ?" "Vu sur Twitter" (#antioop)
  13. 13. MotivationsRéduire complexité accidentelle Programmation concurrenteExpressivité maximale Langage généraliste
  14. 14. Langage généralistePlateforme industrielle interopérable performant déployable réutilisation de lexistantPas un langage de niche performant dans le cas général sans perdre les qualités du langage (pas de contorsions)
  15. 15. MotivationsRéduire complexité accidentelle Programmation concurrenteExpressivité maximale Langage généraliste
  16. 16. MotivationsRéduire complexité accidentelle Programmation concurrenteExpressivité maximale Langage généraliste
  17. 17. MotivationsRéduire complexité accidentelle Programmation concurrenteExpressivité maximale Langage généraliste
  18. 18. Caractéristiques
  19. 19. CaractéristiquesBase fonctionnelle
  20. 20. Base fonctionnelle"It is better to have 100 functions operate on one datastructure than to have 10 functions operate on 10 datastructures." - Alan J. Perlis Briques de base simples Fonctions Structures de données génériques Fonctions sans effet de bord Sur leurs arguments Sur leur environnement Retournant une valeur non altérable => Naturellement thread-safe !
  21. 21. Base fonctionnelle Sans hypothéquer le pouvoir dabstraction/indirection Fonctions en paramètres Fonctions en valeur de retour ("closures") Fonctions polymorphes Application : le concept de "séquence" en Clojure:"It is better to have 100 functions operate on one dataabstraction than 10 functions on 10 data structures" - Attributed to Rich Hickey
  22. 22. CaractéristiquesBase fonctionnelleEtats Managés
  23. 23. Etats managésLa base fonctionnelle seule est insuffisanteBesoin dorchestrer la mutation des états Pour écrire des programmes concurrents fiables Mais aussi pour bien organiser son code ! Confiner la mutation des états comme on confine letraitement des entrées-sorties !On installe cette orchestration au coeur du langage =idiomatique et orthogonal
  24. 24. Etats managés Séparation stricte identité / valeur Identité = stable au cours du temps Etat = Valeur des caractéristiques dune identité à un instant t Valeur = ensemble immuable de caractéristiquesLe temps passe, les identités sont stables, leurs valeurschangent PRIMITIVES DE HAUT NIVEAU POUR GERER LES TRANSITIONS DETAT
  25. 25. CaractéristiquesBase fonctionnelleEtats ManagésLisp
  26. 26. LISPSyntaxe simple et uniformeRapproche donnée et code "Data is code, and code is data" En utilisant les macros à la compilation : "code writing code" Alternative à la répétition de certains patterns Possibilité de rester dans le langage plus longtemps (pas de génération de code depuis UML !) Suppression possible des derniers "boilerplates" du code
  27. 27. LISPDynamique REPL = "Read, Eval, Print, Loop" Le code est évalué (en fait compilé) ligne à ligne On peut continuer dévaluer du nouveau code au runtime On peut recharger les valeurs des fonctions/variables à chaud On peut évaluer nimporte quel code de test/initialisation à chaud Très pratique pour le prototypage, le debug .... Un langage "AGILE" !
  28. 28. CaractéristiquesBase fonctionnelleEtats ManagésLispJVM
  29. 29. JVM JVMpragmatisme Compiléécosystème interactif ou AOT entreprise *warn-on-reflection* Performant Java en benchmark Hotspot-friendly
  30. 30. JVM InteropZéro overhead java.util.* Runnable & Callable
  31. 31. CaractéristiquesBase fonctionnelleEtats ManagésLispJVM
  32. 32. Syntaxe
  33. 33. Commentaire ; ligne #_(bloc de code) Chaîne "Bonjour Lyon !nBonjour Mix-IT !" Nombres 42 2/3 3.14 1e6 12.34M 42N Caractères a newline space Booléens true false null nil Regexes #"a*b*" #""[^"]*"" Symboles ma-fonction java.util.List s/split Mots clés :nom :xml/tag ::local Vecteurs [4 5 6 "cueillir des cerises"] Maps {:key "value", 69000 "Lyon", nil -1} Sets #{1 "mixed" :bag}Appel de fonction (println "Bonjour Maître !") (if (test x) Structure de (print "then") contrôle (print "else"))
  34. 34. Commentaire ; ligne #_(bloc de code) Chaîne "Bonjour Lyon !nBonjour Mix-IT !" java.lang.String java.lang.Long Nombres 42 2/3 3.14 1e6 12.34M 42N java.lang.Double Caractères a newline space java.lang.Character Booléens true false javas true & false null nil javas null Regexes #"a*b*" #""[^"]*"" java.util.Pattern Symboles ma-fonction java.util.List s/split Mots clés :nom :xml/tag ::local Vecteurs [4 5 6 "cueillir des cerises"] java.util.List Maps {:key "value", 69000 "Lyon", nil -1} java.util.Map Sets #{1 "mixed" :bag} java.util.SetAppel de fonction (println "Bonjour Maître !") (if (test x) Structure de (print "then") contrôle (print "else"))
  35. 35. Fonctions
  36. 36. Fonctions "anonymes" : définitions Explicite : (fn [args] ...code...)
  37. 37. Fonctions "anonymes" : définitions Explicite : (fn [args] ...code...) Contractée 1 argument : #(foo (bar %) (baz %))
  38. 38. Fonctions "anonymes" : définitions Explicite : (fn [args] ...code...) Contractée 1 argument : #(foo (bar %) (baz %)) Contractée n arguments : #(foo (bar %1) (baz %2))
  39. 39. Fonctions "anonymes" : définitions Explicite : (fn [args] ...code...) Contractée 1 argument : #(foo (bar %) (baz %)) Contractée n arguments : #(foo (bar %1) (baz %2)) Description Forme explicite Forme contractéeIncrémente de 2 (fn [x] (+ x 2)) #(+ % 2)Ajoute la taille de e à sum (fn [sum e] #(+ %1 (count %2)) (+ sum (count e)) )
  40. 40. Fonctions "anonymes" : UtilisationExemple 1 : Ajoute 2 à tous les éléments dune séquence(map f s) => Transforme la séquence s en appliquant àchaque élément x la fonction f : (f x); Forme expliciteuser=> (map (fn [x] (+ x 2)) [1 2 3])(3 4 5); Forme contractéeuser=> (map #(+ % 2) [1 2 3])(3 4 5)
  41. 41. Fonctions "anonymes" : UtilisationExemple 2 : Somme totale des tailles des éléments duneliste(reduce f val s) => Calcule une valeur v de manièreitérative en calculant dabord v0 = (f val e0) puis v1 = (f v0e1), etc. v = (f vn-1 en)Ou encore :on parcourt s avec une valeur quon "accumule" dunélément à lautre, et on retourn la valeur accumuléeuser=> (reduce + 0 [1 1 1])3
  42. 42. Fonctions "anonymes" : UtilisationExemple 2 : Somme totale des tailles des éléments duneliste; Forme expliciteuser=> (reduce (fn [sum e] (+ sum (count e))) 0 ["a" "bc" "def"])6
  43. 43. Fonctions "anonymes" : UtilisationExemple 2 : Somme totale des tailles des éléments duneliste; Forme expliciteuser=> (reduce (fn [sum e] (+ sum (count e))) 0 ["a" "bc" "def"])6; Forme contractéeuser=> (reduce #(+ %1 (count %2)) 0 ["a" "bc" "def"])6
  44. 44. Fonctions globales et constantes Déclarées dans un espace de noms, un "namespace" ~ package Documentation en ligne, introspectable;; Fichier mix_it/clojure.clj(ns mix-it.clojure)(def add-2 (fn [x] (+ x 2)))(defn add-2 [x] (+ x 2))(defn add-2 "Incrémente x de 2" [x] (+ x 2))
  45. 45. Structures "persistantes" (not= "Persistant" "stockage disque")Valeur originale persiste après "modification" undo for free pas de doute sur le comportement des lib tiercesDonnées immuables "modification" = création dune instance modifiéeModifications performantes Pas de copie brutale, stocké en arbre Partage de structure (les branches inchangées) Opérations en O(log32(n)) ~ O(1) pour des n réalistes
  46. 46. Structures "persistantes"user=> (def v1 [:a :b :c])#user/v1user=> (def v2 (assoc v1 0 :A))#user/v2user=> [v1 v2][[:a :b :c] [:A :b :c]]
  47. 47. Structures "persistantes" : opérations génériquesCollections count, conj, seq vector, vec, get, assoc, pop,Vectors ... hash-map, assoc, dissoc,Maps merge, zipmap, ... hash-set, disj, union,Sets difference, intersection, ...Associative update-in, assoc-instructures http://clojure.org/data_structures
  48. 48. Structures "persistantes" : exempleuser=> (def mix-it {:ou "Lyon", :stats {:participants 198, :speakers 25}})#user/mix-ituser=> (update-in mix-it [:stats :participants] + 2){:ou "Lyon", :stats {:participants 200, :speakers 25}}
  49. 49. Orthogonalité
  50. 50. Orthogonalité : (lazy) sequencesIterators done rightVue sequentielle dune collection fonction seq => vue "naturelle" dautres fonctions: rseq subseq rsubseq vals keys...Immuables bien entendu
  51. 51. Orthogonalité : (lazy) sequencesAbstraction dune liste liée : 3,5 fonctions constructeur (cons 1 (cons 2 nil)) => (1 2) first rest (ou next) user=> (let [s [1 2 3 4]] [(first s) (rest s) (next s)]) [1 (2 3 4) (2 3 4)]seq implicite (cons 1 [2 3]) => (1 2 3) (first {:a 1 :b 2 :c 3}) => [:a 1] (next {:a 1 :b 2 :c 3}) => [:b 2 :c 3]
  52. 52. Orthogonalité : (lazy) sequences3 fonctions et demi ? rest vs next lazinessMajorité des séquences lazy non simultanément réalisées en mémoire "medium éphémère de traitement" pipelines !!! vers linfini et au delà ! gros volumes simplification des algos
  53. 53. Orthogonalité : lazy sequences
  54. 54. Clear upgrade path Accès uniforme aux champs Polymorphisme non intrusif
  55. 55. Accès uniforme aux donnéesImplémentation plus ou moins évoluée ... Donnée non typée :(def dnt {:nom "Mix-it", :participants 200}) Donnée typée :(defrecord Event [nom participants])(def dt (Event. "Mix-it" 200))... mais accès aux données uniforme côté "client" :user=> (:nom dnt)"Mix-it"user=> (:participants dt)200
  56. 56. Polymorphisme non intrusifCe matin, un lapin ...(defn mk-lapin [couleur] {:espece :lapin, :couleur couleur})(defn mk-chasseur [arme] {:espece :chasseur, :arme arme})(def l1 (mk-lapin :gris))(def l2 (mk-lapin :noir))(def c1 (mk-chasseur :couteau))(def c2 (mk-chasseur :fusil))
  57. 57. Polymorphisme non intrusifVersion 1: fonction simple, combinaison despècescombinables close (defn croise [x y] (condp = [(:espece x) (:espece y)] [:lapin :chasseur] :fuit [:lapin :lapin] :accouple ;TODO [:chasseur :chasseur] :trinque [:chasseur :lapin] :tue))
  58. 58. Polymorphisme non intrusifVersion 2: Multiméthodes = dispatch en fonction desarguments = "héritage simple on steroids"(defmulti croise (fn [x y] [(:espece x) (:espece y)]))(defmethod croise [:lapin :chasseur] [l c] :fuit)(defmethod croise [:lapin :lapin] ;TODO [l1 l2] :accouple)(defmethod croise [:chasseur :chasseur] [c1 c2] :trinque)(defmethod croise [:chasseur :lapin] [c l] :tue)
  59. 59. Polymorphisme non intrusif Fait remarquable : Code appelant identique dans les 2 cas user=> (croise l1 l2) :accouple user=> (croise c1 c2) :trinque user=> (croise c1 l1) :tue user=> (croise l1 c1) :fuit
  60. 60. Polymorphisme non intrusif Fait remarquable 2 :multiméthodes extensibles et redefinablesintroduire :lapine héritant de :lapinredéfinir croise pour [:lapin :lapin] définir croise pour [:lapin :lapine]
  61. 61. Gestion des états
  62. 62. Mutable stateful objects are thenew spaghetti code: Hard to understand, test, reason about Concurrency disaster
  63. 63. Concurrent threadsafe managé GC-like
  64. 64. Gestion saine des étatsPas que pour le multithreadEtat : ensemble des valeurs prises par toutes lesvariables dun système à un instant donné trop de variables en OO classique difficulté à raisonner sur le systèmeConfusion entre : valeur identité
  65. 65. Confusion valeur identitéQui na jamais douté dune lib tierce ? A-t-elle garder une référence sur mon objet ? Cet objet est-il la valeur présente ou est-il mis à jour en continu ?Ruine la programmation par valeurs
  66. 66. Confusion valeur identitéMap container = new HashMap();Map a = new HashMap() { {this.put("a", 1); this.put("b", 2);}};Map b = new HashMap() { {this.put("a", 1); this.put("b", 3);}};container.put(a, "bientôt introuvable");a.put("b", 3); //System.out.println(container.get(a));// nullSystem.out.println(container.get(b));// nullSystem.out.println(container);// {{b=3, a=1}=bientôt inaccessible}
  67. 67. Confusion valeur identitéQuestion clé :Cet objet est-il la valeur présente ou est-il mis à jourpar ailleurs ?Pas de confusion sur les primitives car immuablesCas décole : JodaTime vs j.u.Calendar immuable = tranquilité desprit immuable = threadsafeIncrédules ? Lisez JCIP !
  68. 68. Confusion valeur/identitéFaut que ça change ! Tout est immuable Sauf les référencesUne référence est juste une boîte contient une valeur dont le contenu peut changerAucune ambiguité Soit cest une identité (référence) Soit cest une valeur Code plus clair Moins de code défensif (je vais me faire une copie au cas où)
  69. 69. Le cadeau BonuxRéférences en tant quobjets first class passables en paramètre ou valeurs de retour etc. peuvent imposer une logiqueDéjà vu ? java.lang.ref.* pardi !
  70. 70. Le cadeau Bonuxjava.lang.ref.* ajoute une logique spécifique pour la gestion mémoireRéférences Clojure ajoutent une logique spécifique pour la gestion de la concurrence !Plusieurs types de références les refs, pour les màj transactionnelles les atoms, pour les màj isolées les agents, pour les màj isolées et asynchrones chaque type est un pattern de coordination
  71. 71. Le cadeau Bonux Modèle unifié @ ou deref pour lire toujours la même signature pour les fns de mise à jour(def une-ref (ref 39))(def un-agent (agent 21))(def un-atom (atom 63))[@une-ref @un-agent @un-atom]; [39 21 63](alter une-ref + 3)(send un-agent * 2)(swap! un-atom * 2/3)
  72. 72. Y en a unpeu plus, jevous le metsquand même ?
  73. 73. Pour en savoir plusclojure.orgdisclojure.org – excellent daily digestquelques librairies : ring, incanter, compojure, enlivele channel irc #clojure et le google grouples multiples livres : Programming Clojure (daté) Practical Clojure Joy of Clojure (érudit) et Clojure Programming (bientôt en rough cut) dautres en préparation : Programming Clojure 2nd ed, Clojure in Action, Meeting Clojure etc.
  74. 74. Questions
  75. 75. (let [prejuge (= LISP "Lots of Irritating Superfluous Parentheses")] (not= Clojure prejuge)) VRAIMENT ? Voyez plutôt ...
  76. 76. (let [prejuge (= LISP "Lots of Irritating Superfluous Parentheses")] (not= Clojure prejuge))Java :obj.getClient().getAdresse().getZipCode() => ()()()Clojure :(-> obj .getClient .getAdresse .getZipCode) => ()
  77. 77. (let [prejuge (= LISP "Lots of Irritating Superfluous Parentheses")] (not= Clojure prejuge))Java :if ( nullable != null ) { ... foo ...} else { ... bar ...} => () {} {}Clojure :(if nullable ... foo ... ... bar ...) => ()
  78. 78. Orienté Objet Nous pouvons le reconstruire,Nous en avons la possibilité technique

×