Retour

Lundi 16 avril 2018

Programmation fonctionnelle avec Scala

 Programmer, c’est penser. Quand on pense, on a tendance à avoir chacun ses propres idées, ses propres lignes conductrices, ses propres approches.
Pareil en programmation, un développeur doit se positionner face au problème et poser la question : Comment dois-je m’approcher vis-à-vis ce type de problème ? Une toute première piste, serait de bien choisir le paradigme de programmation (la feuille de route, en quelque sorte). En programmation on en cite plusieurs, dont principalement et les plus connus et utilisés :
  • Paradigme procédural (ou classique) : Un paradigme se reposant sur une suite d’instructions sous forme de procédures, et s’orientant dans l’ordre d’exécution du programme.Principaux langages : C, Cobol, Perl, Pascal
  • Paradigme orienté objet (POO) : Il s’agit d’un concept reposant sur des entités appelées objets.Principaux langages : Java, C#, C++, VB.NET, Python
  • Paradigme fonctionnel : C’est un paradigme entièrement différent des deux précédents, s’inspirant du POO mais avec un appui sur les fonctions comme cœur de concept, et considérant le calcul et l’évaluation des fonctions mathématiques comme opération unitaire et fondamentale.
Principaux langages : Scala, F#, Haskell Quelles sont les forces de ce paradigme ? Et quelles sont les raisons qui peuvent pousser un développeur de s’orienter vers un concept totalement différent de ceux d’actualité ?
  • Les fonctions pures Quand on évoque la programmation fonctionnelle, et comme son nom l’indique, on se repose principalement sur les fonctions, mais pas n’importe quelles fonctions : Les fonctions pures. Une
    fonction pure est une fonction mathématique dont son résultat d’évaluation ne dépend que de la valeur de ses arguments, et pas d’un objet ou d’un état externe, et qui retourne le résultat d‘une certaine évaluation mathématique. Dans ce cas, les fonctions pures ne peuvent jamais avoir des effets de bord.
  • Immutabilité
Le paradigme fonctionnel appelle à l’utilisation d’objets immutables : C’est-à-dire, des objets dont l’état/valeur ne changent pas après leur création. Cette approche permet d’écrire de plus en plus un code « thread-safe » et de s’assurer de l’intégrité des données.
  • Récursivité
Le paradigme fonctionnel met en place la récursivité comme solution aux boucles (très déconseillées en vue de leur performance, et aussi parce que cela requiert l’utilisation de ressources mutables (non recommandable dans un paradigme fonctionnel). Le but principal étant – avec le gain de performance remarquable – c’est le fait d’avoir un contrôle total sur les objets utilisés dans un contexte distribué (multi-threadé) : L’absence de mutations signifie que le programme n’aura pas le risque d’un deadlock, ni d’effets secondaires sur les valeurs portées par les objets.
  • « Refactoring »
Les langages fonctionnels permettent de réécrire un code en POO d’une façon plus élégante et concise, et s’approchant le maximum des écritures mathématiques.
  • Fonction comme objet
L’une des forces du paradigme fonctionnel, est l’utilisation des fonctions en tant qu’ « objet ». Cette option a été introduite dans Java 8 (expressions lambda) en s’inspirant notamment de Scala, et a toujours été utilisée dans Javascript. On peut donc passer une fonction en tant que paramètre d’une autre fonction, et on peut également retourner une fonction par une fonction. C’est une approche 100% mathématique.
  • Modularité
On critique souvent dans Java son manque de modularité : Dès que l'on veut qu'une classe ou une méthode soit accessible à partir d'un autre package, il sera nécessaire de la déclarer publique. Ce n’est ni pratique, ni ergonomique (au sens du CleanCode). Avec le paradigme fonctionnel, on peut créer des packages imbriqués, dont la visibilité est réduite à leur scope de définition (même principe dans Javascript).
  • Transparence des exceptions En Java par exemple, la gestion des exceptions est fortement recommandée. Une référence nulle peut facilement mener à un plantage partiel ou complet de notre application.
Dans ce sens, Scala – en tant que langage fonctionnel – offre des mécanismes permettant de réduire la possibilité de finir avec cette exception. Il s’agit d’une classe dénommé « Option » introduite afin d’être utilisée comme type abstrait de retour de toute fonction qui est susceptible de renvoyer null. Dans ce cas, notre programme continuera de fonctionner normalement, il ne reste qu’à gérer la valeur renvoyée dans Option sans se soucier du déroulement de notre programme.
  • Typage statique
Scala – comme langage fonctionnel - est un langage à typage statique : C’est-à-dire, il peut deviner quelques types tout seul, sans que le développeur intervienne pour typer ses objets.