Coder en Scala pour fiabiliser vos applications métier

/Coder en Scala pour fiabiliser vos applications métier

Coder en Scala pour fiabiliser vos applications métier

J’ai eu le plaisir de me rendre à la Scala IO qui s’est déroulée les 29, 30 et 31 octobre 2018 à Lyon. Ce billet a pour but d’introduire Scala avec une bonne dose de pragmatisme, un fond de théorie, quelques cuillerées d’exemples et des retours d’expérience autour de ce langage que nous utilisons quotidiennement chez nos clients.

Scala, qu’est-ce donc ?

Scala est un langage de programmation conçu pour écrire du code dans une forme concise et élégante.

Scala désigne aussi un mollusque gastropode marin, mais cela n’a rien à voir avec notre recette 😉

Notre Scala, celui du monde informatique, repose sur les paradigmes de la programmation orientée objet et de la programmation fonctionnelle. Il concilie ces deux paradigmes habituellement opposés pour permettre aux développeurs de sélectionner la manière la plus appropriée de répondre à leurs besoins.

Carte d'identité

Auteur : Martin Odrersky, professeur à l’EPFL
Paradigmes : Programmation orientée objet et Programmation fonctionnelle
Version actuelle : 2.12 (2018)
Licence : Berkeley Software Distribution (BSD)
Site Web : scala-lang.org

Logo Scala

Programmation impérative versus Programmation fonctionnelle

La programmation impérative est fondée sur les types d’instructions principales suivantes :

  1. Instructions séquentielles
  2. Assignations ou affectations
  3. Conditions
  4. Boucles

Ces types d’instructions sont utilisées par les langages courants tels que le C, C++ ou Java*. Les programmes ainsi développés sont focalisés sur des changements d’état.

La programmation fonctionnelle repose quant à elle sur deux concepts fondamentaux :

Immutabilité

Un objet immutable est un objet dont l’état ne peut pas être modifié après sa création. Ce concept s’inscrit en opposition avec celui d’objet variable.

Pureté

Une fonction pure possède les propriétés suivantes :

  • Sa valeur de retour est toujours la même pour les mêmes paramètres en entrée. Il n’y a pas de variation avec des variables statiques locales, des variables non locales, ou des arguments mutables. La fonction est alors dite idempotente.
  • Son évaluation n’a pas d’effet de bord. Il n’y a pas de modification sur des objets extérieurs à la fonction.

Les fonctions pures présentent plusieurs avantages :

  • Prédictibilité– Elles ne dépendent que des arguments d’entrée, leur exécution est donc parfaitement prévisible.
  • Testabilité – Il n’est pas nécessaire d’avoir un contexte pour les tester.

Concrètement, le principe est d’organiser la donnée en une liste d’éléments et d’utiliser le mécanisme de récursivité pour calculer et produire un résultat en fonction de propriétés.

En Scala, les objets sont immutables par défaut et la création de fonctions pures est largement encouragée.

*  A noter que Java commence à intégrer certains concepts de la programmation fonctionnelle depuis la version 8.

Voilà pour la théorie. Passons du côté pragmatique !

Pourquoi choisir Scala et la programmation fonctionnelle ?

Voici quatre problèmes classiques de la programmation impérative, qui disparaissent avec Scala et la programmation fonctionnelle.

Qui ne s’est jamais retrouvé face à une application « plantée », avec pour seule information, le fameux message « Null Pointer Exception », ou en d’autres termes « La référence de l’objet que vous souhaitez manipuler n’existe pas ».

En effet, lorsqu’une requête en base de données ne retourne pas de résultat, que la fonction appelée ne renvoie rien ou qu’un champ d’un objet n’est pas rempli, les langages de programmation impératifs renvoient « null » au lieu du résultat. Mais cela n’est pas explicite au moment du développement. Si le développeur n’a pas pensé à rattraper l’exception, le programme s’arrête brutalement.

Copy to Clipboard

Scala introduit le type Option. Ainsi, une fonction susceptible de ne pas renvoyer de résultat aura le type de retour Option, qui peut être :

  • Some, lorsqu’il y a un résultat.
  • None, lorsqu’il n’y en a pas.

La possibilité d’absence de résultat devient explicite. Le développeur est alors obligé de gérer les deux cas, sinon une erreur sera levée à la compilation.

Copy to Clipboard

En résumé les Options sont plus puissantes que null car :

  • Elles sont explicites. Nul besoin de lire la documentation pour savoir si la valeur null peut être retournée.
  • Le contrôle se fait à la compilation et non à l’exécution.
  • En java, même si la valeur null est gérée, le développeur risque de renvoyer une valeur absurde pour respecter le type de retour.

La gestion des exceptions en Java se fait à l’aide de blocs « try – catch ».

Copy to Clipboard

Scala introduit Try qui peut renvoyer deux types différents :

  • Success, avec un résultat.
  • Failure, lorsqu’une exception a été levée dans le Try.

Copy to Clipboard

Try offre ainsi une syntaxe fonctionnelle, composable – il est tout à fait possible de faire un Try à l’intérieur d’un autre Try – et élégante pour gérer les exceptions.

La programmation impérative favorise les boucles pour effectuer un traitement sur une collection d’éléments.

En Java, il est très fréquent de faire une boucle for ou while :

Copy to Clipboard

Cette boucle est séquentielle, alors qu’en réalité rien n’empêcherait de traiter toutes les cases du tableau simultanément.

En Scala, le même traitement est effectué à l’aide d’une liste sur laquelle est appliquée une opération map :

Copy to Clipboard

Ici, nous appliquons la fonction matchTypes sur chaque élément de la liste, séquentiellement. Pour rendre cette action parallèle, il suffit d’appeler la méthode par.

Copy to Clipboard

En résumé, la possibilité de parallélisation apparaît de manière plus évidente. De plus, elle est très simple à mettre en œuvre sur une liste avec la méthode par.

Les interactions avec des ressources extérieures sont souvent primordiales dans une application. En programmation impérative, ces opérations doivent être encapsulées dans des blocs try – catch ou encore async – await, qui ne sont pas toujours simple à appréhender.

La programmation fonctionnelle apporte son lot d’abstractions permettant de gérer plus précisément les IO et de composer ces opérations (à l’instar du Try détaillé plus haut). La bibliothèque Cats Effects IO est spécialement conçue pour cela.

Java vers Scala, une transition en douceur

Le code Scala est compilé en bytecode Java, ce qui génère un exécutable devant être déployé sur une JVM. Cela offre une grande souplesse car le langage est compatible avec les bibliothèques écrites en Java. A l’opposé, du code Scala peut également être invoqué dans les programmes Java. Scala bénéficie ainsi de la maturité de l’écosystème Java et des bibliothèques qui en font la force depuis plus de 20 ans.

La question se pose alors de la maintenabilité. Le code Scala, concis et majoritairement fonctionnel, ne sera-t-il pas difficile à maintenir ? En effet, tous les développeurs ne sont pas nés dans la marmite du fonctionnel et certains concepts peuvent sembler abstraits de prime abord. Nous n’avons pas de réponse miracle à cette question, mais deux principes que nous appliquons :

  • Le respect de bonnes pratiques est primordial. Nous ne dresserons pas ici de liste à la Prévert, mais il est recommandé d’utiliser une convention de nommage des fonctions qui reflète leur type de retour. Ou encore, écrire explicitement le type des objets et fonctions déclarés (car Scala ne l’impose pas).
  • Restez pragmatique ! Pensez au nouvel arrivant qui héritera de votre projet et ne cherchez pas à utiliser tous les artefacts du langage pour leur simple beauté. Lorsqu’il s’agit d’itérer sur une liste, la récursivité n’est peut-être pas la solution la plus lisible.

L’écosystème Scala

Deux grands acteurs sont présents dans l’écosystème Scala : Lightbend et Typelevel.

Lightbend

Logo LightbendLightbend est une entreprise qui offre du support autour de Scala. Elle propose une transition simple depuis Java grâce à ses bibliothèques Scala mixant programmation orientée objet et programmation fonctionnelle.

Ces principales bibliothèques sont :

  • Akka – Streaming et message-driven runtime.
  • Play! – Applications Web et services REST/API.
  • Lagom – Architectures micro-services.
  • Slick – Requêtes en bases de données.
  • SBT – Scala Build Tool – Build et gestion des dépendances des applications Scala.

Ces sont des bibliothèques relativement faciles d’accès pour les novices en programmation fonctionnelle. De plus, de nombreuses ressources et exemples sont disponibles sur Internet.

Typelevel

TypelevelLogo Typelevel est une communauté Open-Source promouvant la programmation fonctionnelle pure et proposant un grand nombre de bibliothèques construites sur ce principe.
En d’autres termes, Typelevel ouvre la porte à une nouvelle façon de penser.

Ces principales bibliothèques sont :

  • Cats – Abstractions de base de la programmation fonctionnelle
  • Monix – Actions asynchrones et event-driven runtime.
  • Doobie – JDBC pour Scala.
  • HTTP4S – Client/serveur HTTP
  • Circe – Manipulation de JSON
  • Shapeless – Programmation générique
  • FS2 – Streaming fonctionnel pour Scala
  • Cats Effets IO – Gestion des entrées/sorties

Les avantages sont ceux des fonctions pures décrits précédemment : prédictibilité et testabilité. Cela facilite l’évolutivité du code et rend le refactoring plus sûr. Cette communauté encore jeune fournit un support actif.

Adopter Scala dans votre organisation

Vous êtes maintenant convaincu par les avantages de Scala et de la programmation fonctionnelle ? Mais comment introduire cette nouveauté sans vous heurter aux craintes de la hiérarchie ou à la réticence de vos collègues ?

Je vous conseille d’y aller [petit à petit/pas à pas].

  • Commencez par identifier des fonctionnalités SI sur lesquelles vous souhaitez démontrer que la programmation fonctionnelle apporte de la valeur.
  • Isolez ce petit périmètre, définissez-en les inputs et outputs.
  • Lancez vos premiers projets Scala en respectant les concepts de la programmation fonctionnelle.

Vous prouverez alors que la programmation fonctionnelle peut apporter de la valeur à votre organisation. Cette business value se trouvera à différents niveaux :

  • L’absence d’effet de bord, grâce aux fonctions pures.
  • Une plus grande ré-utilisabilité du code, grâce à une composabilité accrue.
  • Une diminution des bugs, grâce à l’immutabilité et à l’absence de valeur null.
  • Une approche facilitant la parallélisation.

La programmation fonctionnelle n’attend plus que vos projets !

Scala vs Java

By | 2018-11-27T00:03:19+00:00 novembre 13th, 2018|Categories: Big Data, Technique|Tags: , , |0 Comments

About the Author:

Leave A Comment

Artik Consulting / Informations de contact

40 Rue d'Oradour-sur-Glane 75015 Paris

Phone: 01 84 06 36 09

Fax: 09 82 63 63 58