Les langages fonctionnels – Synthèse

Le paradigme de programmation fonctionnelle est surtout connu pour son utilisation académique. Pourtant, depuis quelques années, il revient au goût du jour et fait son entrée dans l’industrie. On retrouve par exemple le langage Erlang, créé par la société Ericsson, utilisé pour le développement d’applications connues comme des modules de Facebook ou encore l’application mobile Whatsapp.

Les avantages de la programmation fonctionnelle sont nombreux, comme nous l’avons vu dans les deux derniers articles : Des langages fonctionnels aux langages multi-paradigmes et Avantages de l’approche fonctionnelle. Cependant, nous avons aussi mis en avant les différents inconvénients comme le manque de bibliothèques et de documentation.

C’est en vue de tous ces points que les langages multi-paradigmes ont été créés. Ils permettent de tirer les avantages des langages sur lesquels ils sont basés (par exemple Java pour Scala) et ceux de la programmation fonctionnelle. Les avantages du langage de base sont souvent les bibliothèques et la documentation tandis que les avantages de la programmation fonctionnelle sont surtout des nouvelles approches des problèmes.

Nous avons souvent parlé de l’avantage des langages fonctionnels pour leur capacité à travailler sur des systèmes en parallèle. C’est un point très intéressant et qui va intéresser les développeurs pour les années à venir. De plus en plus, les micro-processeurs ont plusieurs cœurs. Ainsi, la programmation fonctionnelle offre une nouvelle approche qui permettra d’utiliser la totalité des performances.

Voici le plan du rapport final que nous allons produire à l’issu de ces quelques mois de recherche. Sans surprise, il s’appuiera fortement sur les articles que nous avons publiés. Nous commencerons par une définition des langages fonctionnels suivie d’une partie sur l’utilité de ces langages. Ensuite, comme dans la suite de nos articles, nous verrons plus en détail les principales caractéristiques des langages de programmation fonctionnelle à travers l’exemple d’Haskell. Puis, nous insisterons sur les avantages de l’approche fonctionnelle. Enfin, nous terminerons sur la présentation des langages multi-paradigme comme Scala.

Nous espérons que cette série d’articles vous aura donné quelques idées sur ce qu’est la programmation fonctionnelle. Aussi, nous espérons que vous aurez vu l’intérêt croissant porté au paradigme de programmation fonctionnelle, que ce soit à travers les langages de programmation fonctionnelle pure ou les langages multi-paradigmes. De notre côté, nous avons beaucoup appris sur la notion de paradigme en programmation et ce fût un plaisir de partager avec vous le fruit de nos recherches. Cette étude nous a également permis d’ouvrir les yeux sur d’autres langages que ceux, très communs, des paradigmes orientés objet et impératifs.

Références :

http://chercheurs.edf.com/logiciels/sim-diasca-80703.html
http://www.erlang.org/faq/introduction.html#id49893
http://www.laurentbloch.org/MySpip3/IMG/pdf/Francis-Dupont-ParallelCAML-2.pdf


Licence Creative Commons Cette œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé.

Des langages fonctionnels aux langages multi-paradigmes

Nous avons vu dans les articles précédents les différentes caractéristiques de la programmation fonctionnelle, ses particularités ainsi que les limites qu’elle présente. Dans ce cadre, nous allons voir ce qu’ils apportent au développeur et comment les langages fonctionnels multi-paradigmes (ou hybrides) permettent de contourner certaines limites.

1. D’où vient cette idée ?

Comme nous l’avons remarqué au fil de notre étude sur la programmation fonctionnelle c’est qu’elle fait peur, car elle propose des concepts nouveaux avec un langage nouveau. Ce qui est en train de se passer, c’est que les concepts intéressants découverts grâce à l’approche fonctionnelle sont repris par des langages venant d’autres paradigmes. Finalement, plutôt que d’avoir une rupture dans l’utilisation d’un paradigme plutôt qu’un autre, l’idée est d’avoir une étape transitoire avec des langages multi-paradigmes. C’est à ce titre que des langages comme LINQ, F#, ou Scala ont vu le jour. LINQ est un langage dérivé du C++ qui intègre des concepts de programmation fonctionnelle. Il en est de même pour le langage F# de Microsoft.
L’autre exemple intéressant est le langage Scala. C’est un langage multi-paradigmes : principalement basé sur les concepts de la programmation objet, il utilise des principes des paradigmes objets et impératifs. Ce langage est déjà bien connu, puisqu’il en existe un Framework « Lift ». L’avantage de ce langage est qu’il est basé sur Java et donc qu’il bénéficie de tous les atouts bien connus de ce langage (bibliothèques, multiplateformes, …).

2. Avantages par rapport aux langages fonctionnels purs

Voici une liste de quelques avantages qu’on les langages hybrides :

  • Langage compilé : en général ces langages sont compilés, contrairement aux langages fonctionnels purs. Cela présente un avantage en termes de performance et de rapidité d’exécution.
  • Richesse des bibliothèques : Contrairement aux langages fonctionnels qui ont peu de bibliothèques à l’heure actuelle, les langages hybrides profitent des bibliothèques du langage de base choisi. Par exemple F# qui est intégré au Framework .NET et qui peut accéder à l’ensemble des API de cette plate-forme, ou Scala avec la multitude de bibliothèques de Java.
  • Parallélisme : la plupart des langages hybrides introduit la notion de parallélisme afin d’améliorer les performances et d’accélérer le temps de traitement. F# par exemple manipule bien la notion de multithreading.
  • Clarté syntaxique : contrairement aux langages fonctionnels purs qui ont généralement une syntaxe compliquée, les langages hybrides proposent une syntaxe simple et plus accessible aux développeurs novices.

Ces avantages ont donné un succès rapide aux langages fonctionnels hybrides, en particulier dans l’industrie. La capacité de ces langages de manipuler de grandes quantités de données, amène les langages fonctionnels hybrides à être exploités pour la simulation financière, le calcul scientifique et pour la manipulation de datamining.

3. Différences entre Java et Scala par l’exemple

Nous allons prendre un exemple simple et comparer le code entre Java pur tel qu’on l’apprend à l’école et le code Scala.

L’exemple consiste à découper une liste de personnes en deux listes : les mineurs et les majeurs (le test s’effectuant sur l’âge de l’individu).
Voici tout d’abord le code de la classe Personne :

Java
private class Personne
{
  protected String nom;
  protected int age;

  public Personne(String nom, int age)
  {
    this.nom = nom;
    this.age = age;
  }

  public String getNom()
  {
    return nom;
  }

  public int getAge()
  {
    return age;
  }
 }
Scala
class Personne(nomP: String, ageP: Int)
{
  private val nom = nomParam;
  private val age = ageParam;

  def getNom() = nom;
  def getAge() = age;
}

On voit déjà la longueur du code et la simplicité. La notion de constructeur et de getter sont beaucoup plus facile à coder en Scala. Et la différence ne s’arrête pas là, voici la partie du code qui permet de trier :

Java
List population = new ArrayList();
population.add(new Personne("Pierre", 25));
population.add(new Personne("Paul", 15));
population.add(new Personne("Jaques", 22));

List mineurs = new ArrayList();
List majeurs = new ArrayList();
  for (Personne individu : population)
  {
    if (individu.getAge() < 18)
    {
       mineurs.add(individu);
    }
    else
    {
       majeurs.add(individu);
    }
}
Scala
val population: Array[Personne] = Array(
                           new Personne("Pierre", 25),
                           new Personne("Paul", 15),
                           new Personne("Jacques", 22));
val (mineurs, majeurs) = population partition (_.getAge() < 18);

Nous n’allons pas détailler le code Java qui est assez simple. Cependant, en Scala, tout est fait en deux lignes :

  • Ligne 1 : création de la liste des personnes
  • Ligne 2 : création implicite de deux variables : mineurs et majeurs. Mineurs contiendra la partition de la liste Population dont l’âge est inférieur à 18 et Majeurs le reste de la population.

Cet exemple permet de voir assez rapidement les avantages proposés pas le langage Scala qui est un langage multi-paradigmes.

4. Des limites ?

Nous venons de voir de nombreux avantages des langages hybrides. Il faut cependant faire attention car certains inconvénients ne sont pas négligeables. A commencer par les lacunes dans l’environnement de tels langages. Pour revenir à Scala, nous avons pu lire que les outils d’aide au développement se font rares et que le compilateur scalac est lent. Ce sont donc des notions à ne pas oublier avant de migrer vers Scala.

5. Utilisation dans le monde de l’entreprise

Ces langages hybrides ont déjà une place dans des projets informatiques. Par exemple, depuis quelques années, Twitter remplace certaines applications de leur back-end développées en Ruby par des applications développées en Scala. D’après eux, Ruby est très bien pour la partie front-end des applications web mais est limité en termes de performances pour le traitement des données. C’est une des raisons pour lesquelles ils se mettent à utiliser Scala.
La présence du Framework open source « Lift » depuis 2007 incite les développeurs web à utiliser le langage Scala. Les sites internet openstudy.com, sgrouples.com, ou encore fr.foursquare.com ont par exemple été développés à l’aide de ce Framework.
Le langage F# présent dans la plateforme .NET de Microsoft montre que même les grands de l’informatique se mettent aux langages fonctionnels. Ce langage est utilisé dans de nombreux projets que Microsoft met en avant. Voici quelques exemples pour ceux qui sont intéressés : Cabinet de services financiers ou Grange Insurance (Compagnie d’assurance)

Références :

http://scala-boss.heroku.com
http://scala-lang.org/
http://www.theguardian.com/info/developer-blog/2012/nov/02/functional-programming-scala-the-final-push
http://msdn.microsoft.com/fr-fr/vstudio/gg634701.aspx#Who_Uses_F_sharp
http://www.madrognon.net/informatique/haskell-pour-quoi-faire
http://www-igm.univ-mlv.fr/~dr/XPOSE2011/le_langage_scala/presentation.html
http://blogdesexperts.infotel.com/2013/04/30/la-programmation-fonctionnelle-deferle-sur-java/
http://pro.01net.com/editorial/367047/la-programmation-fonctionnelle-aux-portes-de-lentreprise/
https://github.com/paradigmatic/cours_scala/tree/master/1-Introduction
http://www.scriptol.fr/programmation/scala.php
http://blogdesexperts.infotel.com/2013/04/30/la-programmation-fonctionnelle-deferle-sur-java/
http://www.artima.com/scalazine/articles/twitter_on_scala.html
http://blog.normation.com/fr/2012/04/16/choisir-scala-en-entreprise-est-ce-bien-raisonnable/


Licence Creative Commons Cette œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé.

Avantages de l’approche fonctionnelle

Dans cet article, nous allons présenter les avantages non négligeables de l’approche fonctionnelle dans le développement et pour le développeur.

1. Les avantages de l’approche fonctionnelle

Comme nous l’avons déjà vu, une particularité des langages fonctionnels est la décomposition en fonctions les plus simples possibles. Cette notion apporte de nombreux avantages comme la modularité du code mais aussi la facilité de débogage et de réalisation des tests unitaires. Ceci est un plus non négligeable et surtout dans le développement en entreprise où les tests et le débogage sont très importants. Les fonctions sont partout et peuvent même être passées en paramètres d’autres fonctions. Ce principe favorise la réutilisation d’algorithmes mais aussi l’utilisation des callbacks, qui sont beaucoup utilisées dans les interfaces graphiques.

Il est aussi important de préciser que la gestion de la mémoire est implicite dans la programmation fonctionnelle ce qui facilite la tâche pour le développeur.

Les langages fonctionnels sont fortement typés ce qui permet d’éviter de très nombreuses erreurs de programmation parmi les plus graves. Cela facilite grandement le développement, ce qui explique que ces langages sont beaucoup utilisés dans le prototypage et dans le milieu de la recherche.

La vision fonctionnelle fait que le développeur doit décrire les fonctions plutôt que les calculs. Cela confère donc à l’ordinateur et plus précisément au système d’exploitation une grande liberté pour organiser l’exécution. C’est particulièrement intéressant pour le parallélisme.

Les langages fonctionnels sont basés sur des théories mathématiques comme le ?-calcul et la logique combinatoire. De fait, certains types de problèmes d’arithmétique peuvent être résolus plus rapidement avec la programmation fonctionnelle. Le deuxième impact est que les développeurs qui ont fait des études scientifiques avec des mathématiques sont particulièrement à l’aise avec la vision fonctionnelle.

L’absence d’effet de bord permet l’utilisation de certaines techniques d’optimisations du code comme :

  • la transparence référentielle : elle exprime le fait de pouvoir simplifier une expression en la remplaçant par son résultat sans affecter le fonctionnement du programme.
  • la mémoïsation : optimisation de code consistant à réduire le temps d’exécution d’une fonction en mémorisant ses résultats d’une fois sur l’autre. Bien que liée à la notion de cache, la mémoïsation désigne une technique bien distincte de celles mises en oeuvre dans les algorithmes de gestion de la mémoire cache. (Wikipédia)

Voici un tableau assez intéressant du site MSDN qui montre des différences entre l’approche impérative et l’approche fonctionnelle sur certains points précis qui concernent directement le développeur :

Caractéristique Approche impérative Approche fonctionnelle
Focus du programmeur Comment effectuer des tâches (algorithmes) et comment assurer le suivi des modifications d’état. Les informations souhaitées et les transformations requises.
Modifications d’état Importantes. Non-existantes.
Ordre d’exécution Important. Peu important.
Contrôle de flux principal Boucles, conditions et appels de fonctions (méthodes). Appels de fonctions, y compris la récursivité.
Unité de manipulation principale Instances de structures ou classes. Fonctions en tant que collectes de données et objets de première classe.
2. Exemples sur quelques fonctions
a) Premier exemple : factorielle d’un entier (n!)

Ce premier exemple montre la différence de développement entre les visions impérative et fonctionnelle pour le calcul de la factorielle d’un entier.

Vision impérative (en C) Vision fonctionnelle (en OCaml)
Code
01. int fact (int n)
02. {
03.   if (n==0 || n==1) { return 1; }
04.   else
05.   {
06.     int i, res;
07.     res = 1;
08.     for (i=2;i<=n;i++)
09.     {
10.       res = res * i;
11.     }
12.     return res;
13.   }
14. }
1. let rec fact n =
2.   if (n=0 || n=1) then 1
3.   else n * fact (n-1);;
Remarques La syntaxe est lourde et on utilise une boucle for. Utilisation de la récursivité et pas d’accolades, ce qui allège énormément le code.
b) Deuxième exemple : fonction de recherche de racines par dichotomie

Vision fonctionnelle (en OCaml) :

Code
1. let rec dicho f min max eps =
2.  let fmin = f min and fmax = f max in
3.   if fmin *. fmax > 0.
4.   then failwith "Aucune racine"
5.   else if max -. min < eps then (min +. max) /. 2.
6.   else let mil = (min +. max) /. 2. in
7.    if (f mil) *. fmin < 0.
8.    then dicho f min mil eps
9.    else dicho f mil max eps ;;
Commentaires L1. Déclaration de la fonction récursive dicho qui prend les 4 paramètres suivants : f, min, max et eps
L2. Déclare et défini les variables fmin (=f évalué en min) et fmax (=f évalué en max), uniquement pour le calcul qui suit (les variables ne sont pas disponibles après (mot-clef “in”))
L3. Teste la valeur du produit fmin par fmax.
L4. Si le produit est positif, sortie avec un message indiquant qu’il n’y a pas de racines
L5. Sinon si max et min sont très proches (à epsilon près), affichage du milieu qui représente la valeur cherchée
L6. Sinon déclaration et définition (=centre du segment [min, max]) de la variable mil, uniquement pour le calcul qui suit
L7. Teste la produit de l’évaluation de f au milieu avec fmin
L8. fmil*fmin=0 : Lance la fonction dicho avec les paramètres : f, mil, max et eps
Remarques Utilisation de la récursivité et pas d’accolade, ce qui allège le code.
Ici, on réfléchit d’avantage à ce que la fonction doit faire, sans trop penser à la manière dont la machine va faire les calculs. Pour lancer la fonction dicho, on peut passer très facilement une fonction en paramètre avec la syntaxe suivante : (fun x -> x *. x +. x -. 2.)

Vision impérative (en C) :

Code
01. float dichotomie(float Xmin, float Xmax, float eps)
02. {
03.   while (Xmax-Xmin > eps)
04.   {
05.     float Xmil = (Xmin + Xmax) / 2;
06.     if ((fonction(Xmin) * fonction(Xmil)) > 0)
07.     {
08.       Xmin = Xmil;
09.     }
10.     else
11.     {
12.       Xmax = Xmil;
13.     }
14.   }
15.   return (Xmin + Xmax) / 2;
16. }
Commentaires Vision plus classique, avec une boucle while plutôt que la récursivité.
Remarques Comme nous l’avons indiqué plus haut dans l’article, la première idée qui vient quand on code en impératif est de réfléchir à ce que la machine va faire. Le passage de fonction en paramètre n’est pas très aisé dans les langages de type impératif.
3. A quel prix ?

Nous avons vu de nombreux avantages des langages fonctionnels mais ceci a un coût lié à toutes les contraintes de la programmation fonctionnelle pure résumée ci-dessous :

  • Pas d’effets de bords : pas d’affectation, pas de variables modifiables
  • Une fonction ne peut pas changer ce qui lui est extérieur
  • Le comportement d’une fonction ne peut pas être modifié de l’extérieur
  • La récursivité est à utiliser afin de coder les boucles

Un autre inconvénient des langages fonctionnels c’est le fait qu’ils sont interprétés. C’est un inconvénient majeur d’un point de vue des performances.

Notre prochain article traitera de la programmation multi-paradigme qui permettra de trouver des compromis aux inconvénients que nous venons de montrer.

Références :

http://msdn.microsoft.com/fr-fr/library/bb669144.aspx
http://opera.inrialpes.fr/people/Tayeb.Lemlouma/Papers/Garbage_Collector.pdf
http://www.michael.monerau.com/Reports/Monades.pdf
http://www.defmacro.org/ramblings/fp.html
http://www.pps.univ-paris-diderot.fr/~balat/pfav/pfav.pdf
http://blog.clement.delafargue.name/files/intro_fp.pdf
http://blog.molluskgames.com/tag/programmation-fonctionnelle
http://www-verimag.imag.fr/~mounier/Enseignement/INF121/1-intro-simpleexpr-simpletypes.pdf
http://fr.wikipedia.org/wiki/OCaml


Licence Creative Commons Cette œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé.

Un langage de programmation fonctionnelle : Haskell

Maintenant que nous avons vu ce qu’est la programmation fonctionnelle et les domaines dans lesquels elle est utilisée, nous allons présenter un langage en particulier. Ce langage Haskell nous semble intéressant à explorer car il est l’un des premiers langages de programmation fonctionnelle et il est très utilisé dans l’industrie comme à l’école dans certaines filières.

1. Histoire

Tout d’abord, le langage Haskell tient son nom d’un de ses concepteurs, Haskell Brooks Curry. Ce langage est apparu au début des années 1990 en version 1.0 dans le but de mettre en commun tous les principes de base des langages fonctionnels déjà existants.
Il a connu une évolution rapide dont voici les majeures versions :

  • Haskell 98 qui est la base standard des autres versions.
  • Haskell 2010 qui a ajouté la notion d’interfaces entre langages Haskell
  • Des versions issues de résultats de recherches universitaires sont apparues dès 2012 parmi lesquelles on peut citer : Distributed Haskell, Cloud Haskell et O’Haskell.

Les différentes versions de Haskell utilisent de manière intensive les principes du Lambda-Calcul et de la logique combinatoire.

2. Exemples d’utilisation

Avant de rentrer dans le détail des caractéristiques de ce langage de programmation fonctionnelle, nous allons balayer quelques exemples d’utilisation pour montrer l’étendue des applications possibles de ce langage :

  • jeu vidéo Frag, un FPS en 3D
  • gestionnaire de fenêtre : xmonad qui propose une manière particulière d’organiser les fenêtres sur le bureau
  • éditeur de texte : Yi
  • un IDE pour développer en Haskell : Leksah
  • logiciel de gestion de versions : Darcs

Mais le Haskell est aussi utilisé en entreprise sur de multiples projets. Voici quelques exemples :

  • Alcatel-Lucent: création de prototypes pour des systèmes en temps réel de communication radio à bande étroite.
  • Ericsson AB : mise en œuvre d’un langage de programmation embarqué pour du traitement de signaux numériques.
  • Facebook : développement d’un outil (lex-pass) qui sert à automatiser des traitements à effectuer sur du code source PHP.
  • Google : utilisation sur des projets internes du système d’information. Dans les ressources, vous verrez un rapport qui présente le retour sur expérience de l’utilisation d’Haskell sur des projets internes à Google.
  • Clever Cloud : développement de sites institutionnels et de documentations.

3. Caractéristiques principales

Fonctionnel pur : comme nous l’avons précisé dans le précédent post, la pureté est une caractéristique des langages fonctionnels. Ce point est particulièrement important dans le langage Haskell puisque toutes les fonctions écrites dans ce langage sont pures.

Paresseux : le langage Haskell fait partie des langages de programmation fonctionnelle dit à évaluation paresseuse. En résumé, cela signifie que lors de l’exécution du programme, tant que le résultat d’un calcul n’est pas nécessaire, il n’est pas calculé. Une utilité principale est la gestion de l’infini. Voici un exemple tiré du tutoriel indiqué dans nos sources, et qui permet de bien comprendre ce phénomène :

Étudions une fonction doubleMe qui multiplie par deux chaque membre de la liste passée en argument et la retourne. Imaginons que l’on souhaite multiplier par 8 la liste suivante {1, 2, 3, 4}, en appliquant doubleMe(doubleMe(doubleMe({1, 2, 3, 4}))). Dans un langage non paresseux, on effectuerait trois fois l’opération et tous les champs seraient parcourus pour obtenir la liste multipliée par 8 en résultat.

Dans un langage paresseux, le fait d’appeler la méthode doubleMe trois fois n’exécute pas le calcul. Le programme enregistre juste l’action souhaitée. Ensuite, si le programme doit afficher le résultat, alors il sera demandé de manière récursive en commençant par le troisième appel qui demandera le résultat au deuxième puis au premier.

Typé statiquement : les types (des variables, arguments et fonctions) ne doivent pas forcément être explicites dans le code, le compilateur se charge de les détecter. D’autre part, la compatibilité des types est vérifiée pars le compilateur. Il est cependant recommandé de préciser le type de certaines variables s’il est ambigu afin d’éviter un comportement non souhaité.

Bibliothèques disponibles : la plus importante est appelée Prelude et inclut les fonctions les plus utilisées, et depuis Haskell 2010 les bibliothèques GHC (bibliothèques standards de Haskell).

 

Références :

http://lyah.haskell.fr (Tutoriel)
http://www.haskell.org/haskellwiki/Haskell (Wiki du site officiel)
http://fr.openclassrooms.com/informatique/cours/apprenez-la-programmation-fonctionnelle-avec-haskell (Site du Zéro)
http://fr.wikipedia.org/wiki/Haskell (Article Wikipédia)
http://k1024.org/~iusty/papers/icfp10-haskell-reagent.pdf (Rapport d’expérience sur l’utilisation de Haskell dans des projets interne de Google)


Licence Creative Commons Cette œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé.

A quoi sert la programmation fonctionnelle ?

Le paradigme de programmation fonctionnelle fait partie des paradigmes les plus importants, mais son utilisation est restée limitée et ne s’est pas répandue. Cela est principalement dû à l’ignorance par les développeurs de ses caractéristiques et propriétés. Dans cet article, nous allons mettre en avant les différents traits des langages fonctionnels et leurs utilisations dans divers domaines.

1. Principe générale

Dans ce paradigme, les variables mutables sont oubliées et les seuls objets manipulés sont des fonctions et des constantes. En fait, son principe s’appuie sur la notion de valeur. Les fonctions elles-mêmes sont considérées comme des valeurs et elles peuvent être passées en argument à d’autres fonctions. En poussant cette idée à l’extrême, le programme principal est considéré comme une fonction font le seul rôle et de faire appel à d’autres fonctions. Cela donne souvent une formulation très compacte et générique d’algorithmes. Un programme fonctionnel est essentiellement constitué d’expressions et le calcul consiste en l’évaluation de ces expressions.

2. Principales caractéristiques

Dans cette partie, nous allons préciser quelques caractéristiques d’un langage de programmation fonctionnelle. Bien sûr, certaines d’entre elles sont caractéristiques d’autres langages.

  • Pureté : tout calcul est fait sans effets de bord, c’est-à-dire qu’une fonction ne renverra jamais un résultat inattendu. Pour arriver à ce résultat, sont interdits : les opérations d’affectation, les boucles itératives, et les assignations de variables. Une fonction pure donne toujours le même résultat avec les mêmes arguments quel que soit l’endroit d’exécution. L’avantage de la pureté est le fait d’être sure que la fonction réalise bien ce que l’on veut. De plus, la pureté facilite les tests unitaires de fonctions et accélère le débogage. Les questions d’optimisation sont plus simples à résoudre. Il existe des langages fonctionnels purs et des langages fonctionnels impurs, la différence étant qu’un langage impur autorise certains aspects de la programmation impérative.
  • Gestion automatique de la mémoire : il n’y a pas d’allocation de mémoire manuelle dans la programmation fonctionnelle, elle est gérée automatiquement. De plus, la libération de mémoire se fait automatiquement par l’intermédiaire du Garbage Collector (ramasse-miettes). Cette gestion simplifie grandement la tâche du programmeur.
  • Fortement typé : le typage fort de la plupart des langages fonctionnels permet d’éviter les erreurs de développement liées au typage avant d’exécuter le programme.
  • Fonctions d’ordre supérieur : une fonction peut prendre en argument des fonctions et peux même produire une fonction comme résultat. Cette capacité de manipuler les fonctions comme valeurs est appelée ordre supérieure, ce qui rend le niveau de raisonnement plus élevé.
  • La récursivité : c’est le fait d’inclure l’appel d’une fonction dans sa propre définition. Elle remplace les boucles itératives et l’allocation de mémoire. L’utilisation de la récursivité est privilégiée parce que l’appel de fonctions coûte très peu cher en mémoire.
  • Deux approches d’évaluation :
    Applicative : stratégie d’évaluation dans laquelle les arguments de la fonctions sont évalués avant que la fonction soit appliquée
    Exemple : dans le langage Scheme, c’est le fonctionnement par défaut
    Paresseuse : stratégie d’évaluation dans laquelle les arguments de fonctions sont évalués seulement quand ils sont nécessaires pour le calcul. Cette approche est utile pour traiter des gros flux de données
    Exemple : dans le langage Scheme (en utilisant les streams), Haskell
3. Domaines d’utilisation
Malgré ses propriétés et ses caractéristiques principales qui offrent des avantages sans équivalent par rapport à la programmation impérative, la programmation fonctionnelle est restée longtemps exclusivement académique. Elle était très présente dans les laboratoires de recherche et dans les universités. Depuis seulement quelques années, elle commence à connaître un succès dans l’industrie. Elle était principalement prisée par les entreprises touchant aux finances mais elle est maintenant utilisée dans plusieurs domaines : industriel, militaire, robotique, intelligence artificielle. On peut classer les domaines d’utilisation selon le type de langage s’il elle est totalement pure ou non :
  • Les langages purs sont utilisés pour les logiciels qui nécessitent un degré élevé de précision et une grande quantité de calcul :
    > Miranda : c’est le premier langage fonctionnel conçu dans le but de développer des applications commerciales plutôt dans un but de recherche.
    > Erlang : créé par Ericsson, il est utilisé dans des projets industriels mais aussi dans certains projets informatiques liés aux réseaux comme le célèbre serveur XMPP ejabberd.
  • Langages impurs :
    > Lisp : ce langage est spécialisé dans le traitement de listes (d’où son nom extrait de : LISt Processor). Il est donc beaucoup utlisé dans le calcul numérique et sert donc dans le domaine de la recherche et des jeux vidéo.
    > Common Lisp : utilisé pour des applications embarquées comme dans le robot Mars Pathfinder de la NASA.
    > Ocaml : ce langage est utilisé pour le calcul symbolique (preuves mathématiques, compilation, interprétation, analyses de programmes), le prototypage rapide, la programmation distribuée et l’industrie (utilisé par des grandes entreprises pour développer des gros logiciels: Startups, CEA, EDF, France Télécom, Simulog).

Références :

http://www.techno-science.net/?onglet=glossaire&definition=5383 http://fr.answers.yahoo.com/question/index?qid=20080903034057AA4zSJI http://www.michael.monerau.com/Reports/Monades.pdf http://deptinfo.unice.fr/~roy/progfonc.html http://blog.developpez.com/damien-guichard/p8623/programmation-fonctionnelle/qu_est_ce_que_la_programmation_fonctionn http://fr.wikipedia.org/wiki/Programmation_fonctionnelle


Licence Creative Commons Cette œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé.

Les langages fonctionnels – Définition

1. Définition d’un langage de programmation

Avant de commencer, il faut bien comprendre ce qu’est un langage de programmation. C’est une syntaxe qui sert d’intermédiaire entre des idées et le langage machine. Il permet d’écrire un ensemble d’instructions qui seront réalisées par un ordinateur et de les structurer. Il est régit par des règles strictes. D’ailleurs, ces restrictions permettent de créer des outils d’aide au développement. Ils vérifient la cohérence de ce que le programmeur écrit. D’après Wikipédia, un langage de programmation est une notation conventionnelle destinée à formuler des algorithmes et produire des programmes informatiques. Les premiers langages de programmation sont apparus dès 1950. L’ensemble des langages de programmation qui partagent le même mode de réflexion reflète un paradigme de programmation.

2. Définition de paradigme en informatique

Tout d’abord, d’après le Larousse, un paradigme en informatique est une méthode théorique de pensée qui oriente la recherche et la réflexion scientifiques. Un paradigme en informatique est donc une vision de la manière dont un problème informatique peut être résolu. Chaque paradigme de programmation privilégie un ensemble particulier de stratégies d’analyse et de descriptions. Certains types de problèmes se traitent plus facilement avec un paradigme que les autres. Contrairement à ce que l’on peut imaginer, un langage de programmation peut être en accord avec plusieurs paradigmes différents. Il existe de nombreux paradigmes fonctionnels, environs 29, qui sont liés les uns avec les autres. Un schéma tiré du site internet de l’Université catholique de Louvain (UCL) représente les interactions entre eux (voir dans les références). Les trois grands paradigmes de programmation sont les paradigmes :
- Impératif (ex : C) : concept de procédure (série de tâches à réaliser)
- Objet (ex : Java) : assemblage de briques de bases appelées objets qui représente une entité physique ou un concept
- Fonctionnel (ex : Haskell) : tout est fonction dans ce modèle

3. Pourquoi étudier plusieurs paradigmes ?

La diversité des problèmes informatiques en termes de complexité et de domaine d’application amène à les traiter de différentes manières. Les paradigmes permettent justement de décrire et résoudre ces problèmes de manière adaptative. L’étude de différents paradigmes de programmation facilite aussi la création de nouveaux langages qui sont plus adaptés à un type d’application. D’autre part, l’apprentissage des langages de programmation diffère grandement selon les paradigmes de programmation. Cela permet à des personnes issues de différentes filières d’étude de s’adapter à un type de langage plutôt qu’à un autre.

4. Qu’est-ce que la programmation fonctionnelle ?

Le paradigme de programmation fonctionnelle est apparu pour la première fois avec le langage Lisp créé en 1958 par McCarthy. Comme son nom l’indique, ce paradigme traite tout en fonctions. La programmation fonctionnelle réside en une multitude de fonctions. Chaque fonction reçoit des paramètres et retourne seulement un résultat qui dépend uniquement des paramètres. Aussi, l’analyse dans ce type de programmation peut être  descendante ou ascendante. Un autre point important est qu’il n’y a pas d’affectation dans la programmation fonctionnelle. Cela signifie que les fonctions sont indépendantes et qu’elles ne peuvent pas interférer entre elles. Cela assure l’absence d’effets de bords. Cette notion de fonctions omniprésentes explique pourquoi dans certains parcours d’études supérieures scientifiques, les langages fonctionnels comme le Haskell sont étudiés. Le premier langage Lisp était faiblement typé, comme ses successeurs Scheme (1975) ou Common Lisp (1984). D’autres langages plus typés sont sortis comme ML (1973), Erlang (1982-85), Haskell (1987), OCaml (1996) ou F# (2002). Le plus connu de ces langages est très certainement Haskell.


Références :

https://sites.google.com/site/informatiquefondamentale/master-01-cours-1/paradigmes-des-langages-de-programmation
http://fr.wikipedia.org/wiki/Programmation_fonctionnelle
http://www.info.ucl.ac.be/~pvr/paradigmes.html (voir le schéma sur ce site)


Licence Creative Commons
Cette œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé.

Les langages fonctionnels – Introduction

Dans le cadre du projet de veille technologique sur Les langages fonctionnels, ce premier article vous présente la problématique étudiée et définit le plan d’attaque que nous nous sommes fixé.

1. Présentation de la problématique

Dans le cadre de ce projet de veille technologique, nous allons nous intéresser au paradigme de programmation fonctionnelle. Ce type de programmation est souvent peu connu. Par exemple, il existe peu de formations dans lesquelles les langages fonctionnels sont enseignés. Mais ce paradigme semble retrouver une place importante et en particulier dans le monde de l’industrie. Pourquoi un tel engouement pour ce type de programmation ? C’est une des questions majeures de notre réflexion. Outre la définition de ce qu’est ce paradigme, la problématique est de comprendre les différences avec les autres types de programmation : les langages impératifs et les langages objet. Un dernier point de la réflexion concerne l’étude des langages qui combinent les trois visions de la programmation : objet, impératif et fonctionnel.

2. Plan général d’attaque du sujet

Dans un premier temps, nous allons nous attarder sur l’étude de ce qu’est le paradigme de la programmation fonctionnelle. Nous ne connaissons pas ce type de programmation, c’est donc un travail de découverte qui nous attend. Cette étude passera probablement par la recherche des différents langages utilisant ce paradigme. Ensuite nous axerons notre recherche sur la question : « pourquoi cette programmation revient au goût du jour ? ». Cette deuxième phase nous permettra de voir les domaines d’utilisation de ce langage. Puis, nous ferons une étude comparative entre les trois paradigmes : objet, impératif et fonctionnel. La manière de faire la comparaison est encore à déterminer. Les questions de performance et de facilité d’utilisation seront très certainement à étudier. Nous porterons aussi un intérêt sur les avantages et les limites. Enfin, nous travaillerons sur une dernière partie qui concerne les langages de programmation qui utilisent un mélange des trois paradigmes.

3. Compte rendu de la prise de contact avec l’encadrant du projet

La première réunion avait deux objectifs principaux. Tout d’abord, nous avons pu nous présenter, cela permet de savoir avec qui nous travaillons ; d’autant plus que nous ne connaissions pas cet enseignant. Ensuite l’encadrant du projet nous a expliqué ce qu’il attendait de nous avec ce projet. C’est ce qui nous a aidé à construire notre plan d’attaque.


Licence Creative Commons
Cette œuvre est mise à disposition selon les termes de la Licence Creative Commons Attribution 3.0 non transposé.