Il y a 6 ans -
Temps de lecture 12 minutes
ScalaIO 2016
Les 27 et 28 octobre 2016 a eu lieu la 3e édition de scala.io à Lyon. L’absence de l’événement l’année dernière n’a fait qu’augmenter nos attentes ! Il y a eu des conférences pour tous les niveaux. On vous présente nos coups de cœur.
Six years of Scala and counting – Manuel Bernhardt
Manuel Bernhardt est un développeur Scala senior, formateur certifié Lightbend pour Scala et Akka et l’auteur du livre Reactive web applications. Cette conférence est une prise de recul sur l’apprentissage et l’utilisation de Scala.
D’après Manuel Bernhardt, l’intérêt et l’adoption de Scala sont grandissants. Par exemple, le cours Coursera Functional Programming Principles in Scala – donné par Martin Odersky – a connu un nombre de participants et un taux de complétion très élevée. De même, certaines universités choisissent maintenant Scala en tant que langage d’initiation à la programmation. Les opportunités de partage autour de Scala se multiplient aussi au travers des conférences et de meetups tel que le Scala user group. Manuel nous présente aussi ses fonctionnalités favorites de Scala qui sont les typeclasses, les case classes et bien évidemment les fonctions.
L’utilisation de Scala au quotidien est différente de Java. Par exemple, les NullPointerException
font partie du passé car null
est absent de la bibliothèque standard et son utilisation, même si elle est possible, est forcément intentionnelle. Autre point, qui rejoint le précédent, Scala permet de façon générale une sûreté d’exécution plus grande que Java car le nombre d’erreurs détectées à la compilation est plus élevé. Cela est permis par une utilisation abondante du système de type et de frameworks tel que Play! qui compilent URL et templates (et vérifient donc leur validité). Manuel Bernhardt revient aussi sur le support IDE qui est maintenant très bon, et la compilation dont le temps est toujours élevé mais qui est devenue incrémentale grâce à SBT.
En conclusion, Manuel Bernhardt donne quelques conseils pour appréhender le langage. Premièrement, il conseille aux développeurs non Scala de ne pas se laisser décourager par l’apparente complexité du langage. En effet, ce dernier fait beaucoup parler de lui autour de fonctionnalités avancées tel que la méta-programmation, les macros ou encore l’utilisation avancée du système de type. Mais ce sont des utilisations aux limites qui ne reflètent nullement la nature du développement d’applications de gestion. Scala est un langage sans complexité inhérente qui concilie les paradigmes objet et fonctionnel avec une inclinaison vers ce dernier. Finalement, Manuel Bernhardt nous conseille de limiter l’utilisation de la boîte à outils Scala au strict nécessaire afin de réduire la complexité, ce qui n’est pas sans rappeler le Principle of least power.
Practical Scalacheck – Noel Markham
Noel est un consultant senior de 47 deg. Dans cette présentation, il discute de l’importance des tests basés sur les propriétés et leur implémentation avec Scalacheck. Il montre comment Scalacheck nous permet de changer le paradigme dans lequel on fournit les données de notre test vers un autre dans où on spécifie les règles que doit respecter notre code. Ce changement d’approche nous aide également à éviter la construction des stubs et mock, très populaires dans d’autres frameworks de test.
Ensuite, on discute un cas pratique mais typiquement compliqué : tester une implémentation du jeux Yahtzee.
[scala]forAll(chooseNum[Int](1, orderedGens.length – 1)) { idx =>
val (winningGens, losingGens) = orderedGens.splitAt(idx)
forAll(oneOf(winningsGens), oneOf(losingGens)) { (winningHand, losingHand) =>
collect(s"${winningHand.score} vs ${losingHand.score}") {
(winner(winningHand, losingHand) ?= winningHand) && (winner(losingHand, winningHand) ?= winningHand)
}
}
}[/scala]
On aborde principalement des questions plus pointues :
- Comment ne pas ré-implementer le code métier dans les tests ?
- Éviter la croissance exponentielle des cas de test ?
- Comment générer les données ?
À la fin, Noël nous conseille quelques bonnes pratiques :
- Il faut utiliser les générateurs à la place de l’opérateur ‘==>’
- Il faut nommer les générateurs avec ‘|:’
- Il faut créer des données pour le cas de succès et pour les cas échéantes
Finalement, Noël nous informe que bientôt, on aura à disposition un projet créé pour 47 degrés pour nous aider à générer les dates.
CQRS + ES > CRUD, CQFD – Damien Gouyette et Valentin Kasas
Damien Gouyette et Valentin Kasas nous font un retour d’expérience sur la mise en place d’un modèle ES + CQRS dans le cadre du projet HamaK incubée par PagesJaunes.
Damien et Valentin ont commencé par nous rappeler les inconvénients de l’approche CRUD classique. On citera notamment les problématiques de locking et de transactionalité ainsi que la perte d’information lors d’une mise à jour ou d’une suppression à l’opposé de l’approche ES qui est fondamentalement différente.
Une persistance par ES modélise tout changement au travers d’événements séquentiels et immuables. Cette approche apporte donc un audit/historique en plus d’être très efficace dans un environnement concurrentiel de par sa nature immuable.
Cependant, cette approche ES apporte son lot de difficultés. Premièrement, ce modèle de persistance n’est généralement pas viable d’un point de vue lecture, c’est pourquoi il est quasi systématiquement couplé à du CQRS pour garantir des performances constantes. À cela s’ajoute la difficulté face aux inévitables changements de modèle. En effet, contrairement à une persistance CRUD classique où les données peuvent être migrées d’une version à une autre, l’approche ES interdit la modification d’événements immuables. De plus, il peut persister des événements de la version antérieure dans les queues de messages, c’est pourquoi il sera nécessaire de supporter les deux versions.
Finalement, Damien et Valentin nous montrent quelques patterns adroitement utilisés tel que les typeclasses, Reader et ValidationNel de ScalaZ.
À la découverte d’Idris et de ses types dépendants – Benoît Lemoine
Dans ce quickie, Benoît nous fait un live coding en Idris, un langage supportant les types dépendants. Les types dépendants sont une fonctionnalité qui permet à un type de dépendre d’une valeur. On mélange donc deux dimensions habituellement distinctes dans les langages de programmation. On note que cette fonctionnalité est absente de la plupart des langages de programmation y compris Scala (certains diront que les “path dependent types” sont une forme de typage dépendant).
Durant ce live-coding, Benoît implémente le « hello world » du typage dépendant : une liste qui encapsule sa taille dans son type.
Voici un exemple de définition et d’utilisation d’un constructeur de type liste paramétré avec un entier (Nat) et un type (Type)
data List : Nat -> Type -> Type
…
append : List n a -> List m a -> List (n + m) a
La fonction append
ci-dessus permet de concaténer deux listes de taille n et m et de créer une liste de taille n + m. On insiste de nouveau sur le fait que la taille fait partie du type et que la véracité de la signature est donc vérifiée par le compilateur. Un effet de bord de ce typage extrêmement puissant est une inférence très forte qui ressemble presque à de la génération de code. Cela est possible car le compilateur possède beaucoup d’informations et que les implémentations possibles pour une signature donnée minimes voire uniques.
Easy and efficient data validation with Cats – Daniela Sfregola
Dans ce talk, Daniela nous parle de la validation de données de manière élégante avec cats.
Elle nous explique qu’en Scala, il est possible de « sécuriser » une suite de traitements grâce à la monade Option
. Cependant, si une erreur survient, on ne peut pas déterminer quelle partie du traitement a échoué, ni savoir quelle est l’erreur.
Daniela nous présente alors la monade Xor (qui sera supprimée au profit de la monade Either dans scala 2.12) qui permet de déterminer quelle étape du traitement a échoué et pour quelle raison. Cependant, il s’agit d’un « court-circuit » en cas d’erreur, c’est-à-dire que c’est idéal si l’on souhaite un fail fast ou si les différents traitements sont dépendants. Par contre, elle n’est pas adaptée pour la validation de données métiers où l’on souhaite enchaîner les traitements et accumuler les erreurs.
Daniela nous présente alors Validated qui, contrairement à Option et Xor/Either, n’est pas une monade mais un foncteur applicatif. Si on ne peut plus faire un flatMap, il est en revanche possible de chaîner les validations, nous offrant ainsi une validation élégante des données.
[scala]case class Person(mail: String, name: String)
def isEmail(mail: String): Validated[NEL[String], String] =
if (mail.contains("@")) { valid[NEL[String], String](mail)}
else { invalid[NEL[String], String](NEL.of("underage"))}
def nameNonEmpty(name: String) =
if (!name.isEmpty) { valid[NEL[String], String](name)}
else { invalid[NEL[String], String](NEL.of("invalid name")) }
def validatePerson(mail: String, name: String): ValidatedNel[String, Person] = {
val validAge = isEmail(mail)
val validName = nameNonEmpty(name)
(validAge |@| validName)
.map{ case (vAge, vName) => Person(vAge, vName) }
}[/scala]
Développer des APIs Hypermedias simplement avec Scala – Antoine Michel
Antoine Michel (CTO de Zengularity) nous révèle un projet que sa société compte open-sourcer s’il intéresse suffisamment de monde : une bibliothèque facilitant le développement d’API Hypermedia. Il faut bien comprendre que l’on vise là le REST au sens originel du terme, plus connu actuellement sous le terme de HATEOAS.
Les promesses de la bibliothèque sont :
- de pouvoir faire une API auto-documentée, sans passer par un générateur ;
- de simplifier le développement : pas besoin de maîtriser tous les aspects de REST, il suffit de décrire les propriétés et contraintes de ressources.
Antoine Michel fait partie de ces rares personnes dans le monde REST qui ont compris la nécessité, dans ce style d’architecture, de gérer la partie cliente. Le client est souvent un navigateur piloté par un être humain, ce qui rend particulièrement difficile la transposition du Web (naturellement RESTful) au monde des API, consommables par des automates. Cette partie, pas encore réalisée, pourrait aider les SPA à trouver les ressources et à créer automatiquement des règles de validation pour les formulaires. React est la première technologie front qui serait supportée. Au final, quelque soit le langage client, il y aura la possibilité de générer la couche d’accès aux ressources.
Le travail le plus avancé est la partie back. Elle repose sur le format JSON-LD, qui apporte la partie « liens » manquante à JSON pour en faire un hypermedia. JSON-LD permet d’aller plus loin que ce qui est nécessaire pour une API REST consommée par des automates, à savoir la description des contraintes nécessaire à la création d’une IHM. On notera d’autre points forts :
- routes explicites mais aussi déductibles du contexte ;
- reverse-routing obtenu by design ;
- génération d’un AST qui permet détendre l’implémentation pour supporter d’autres manières de naviguer dans les ressources, comme GraphQL ;
- possibilité d’utiliser la bibliothèque en mode CQRS.
En résumé, nous souhaitons vivement qu’une suite soit donnée au projet qui est un changement majeur dans le monde des frameworks REST !
La programmation fonctionnelle, c’est pas juste des lambdas – David Sferruzza
Orientée débutant, cette présentation de David Sferruzza vise à faire découvrir les principes programmation fonctionnelle (PF). Elle s’inscrit dans la politique d’ouvrir le Scala et plus généralement la PF aux développeurs habitués au paradigme objet classique.
Les fondamentaux sont présentés :
- Comment la PF rend la chaîne de traitement plus claire en évitant par exemple de mélanger l’implémentation d’un parcours de boucle et avec le traitement utile comme ce serait fait en programmation impérative
- Les fonction de base sur la classe
List
:map
,filter
,fold
et autres fonctions d’ordre supérieur - Maîtrise de stratégie d’évaluation (par exemple, une stratégie « lazy » permet dévaluer des structures infinies)
- Différences entre
val
,lazy val
,def
- L’immuabilité et ses avantages. David nous rappelle que l’immuabilité est parfois perçu à tort comme pénalisant pour les performances. Au contraire, cela permet de faire des copies superficielles de structure sans risques !
David Sferruzza termine par une bibliographie pour bien commencer en programmation fonctionnelle. Il y inclut un ouvrage sur Haskell, car ce langage fonctionnel pur permet d’après lui de mieux saisir certains principes quand on revient au Scala.
Applying Functional Programming Patterns – Markus Haulk
Dans ce talk, Markus Haulk nous présente différents patterns issus de la programmation fonctionnelle.
Markus commence par nous expliquer sa vision de la programmation fonctionnelle par rapport à la programmation orientée objet (POO). Pour lui, la POO est comparable à des Duplo, on peut construire de grosses briques qui s’imbriquent facilement dans l’environnement où elles sont prévues pour aller, mais sont pour la plupart spécifiques, pas facilement réutilisables. En revanche, il voit la programmation fonctionnelle comme des Lego. Celle-ci est constituée de quelques briques élémentaires simples bien définies, composables et réutilisables à l’infini , permettant ainsi de construire de grands édifices.
Markus nous montre alors deux exemples notables de cette composabilité et son utilisation :
- Les Monoid : Il s’agit d’une structure munie d’un élément neutre, d’une fonction de combinaison et de certaines lois sur cette fonction. À partir de cette structure simple, Markus expose quelles possibilités de combinaisons nous sont offertes et nous présente un exemple d’utilisation des Monoid dans Spark.
- Validated : Autre structure munie d’une opération de composition, celle-ci permet de tester la validité d’une donnée et se compose aisément avec d’autres Validated. C’est une structure très puissante lorsque l’on souhaite valider un ensemble de données tout en cumulant l’ensemble des erreurs rencontrées, comme par exemple lors de la validation d’un formulaire.
Quelques photos
Et pour finir… rien de mieux que quelques photos !
Commentaire