Salut à tous !
Voici un petit article pour présenter Haskell aux novices en programmation
fonctionnelle (comme moi) et surtout, pour vous donner l'envie d'en savoir
plus.
Haskell est un langage généraliste récent (moins d'une dizaine d'années),
il introduit une foule de concepts extremement intéressants. Il est
malheureusement encore peu utilisé dans le monde industriel. Mais il vaut le détour !!
Quelques infos pour vous donner envie de lire la suite :
- 10 fois moins de lignes de code qu'en C,
- une grande expressivité, une grande généricité,
- une compréhension, une maintenabilité du code largement accrue,
- très peu de bugs grâce à son système de types évolué!
C'est un langage basé sur une théorie mathématique (la théorie de
catégories). Ce langage est « fonctionnel pur », par opposition aux
langages « impératifs », dont font parties tous les langages les plus
connus (C, C++, Ada, Java, Pascal…).
Cela induit un mode de programmation radicalement différent !
Le "gap sémantique" à franchir est important, ce qui en fait un language
plutôt difficile à apprendre pour quelqu'un comme moi qui vient du monde
impératif, mais le jeu en vaux la chandelle.
Haskell est :
- paresseux
- pleinement fonctionnel
- fortement typé, et supporte l'inférence de type
- pur
Haskell est effectivement paresseux, mais ce n'est pas péjoratif !
Cela signifie qu'il n'évalue pas une expression si ce n'est pas
nécessaire. Si le résultat d'un calcul n'est pas utilisé dans la suite
du programme, il n'est pas évalué.
Cela induit un gain évident en terme de temps de traitement.
Cela améliore aussi le design des programmes puisque cela décharge le
programmeur de coder certaines optimisations, pour se concentrer sur
le métier de son logiciel.
Mais surtout, cela permet de faire certaines abstractions très
intéressantes : comme par exemple des structures de données de taille
infinie.
En Haskell il est tout à fait possible de déclarer un « tableau » de
taille infinie, par exemple une tableau contenant tous les éléments de
la suite de Fibonacci !
Bien sûr vous choisirez de n'afficher que les n premiers éléments, et
Haskell décidera de ne calculer que ceux là. (Voir l'exemple
faramineux de wikipedia: [ame]http://fr.wikipedia.org/wiki/Haskell[/ame])
Ensuite Haskell est pleinement fonctionnel : les fonctions sont des
objets de « 1ere classe ».
Cela signifie que les fonctions peuvent être traitées comme des
variables. Donc une fonction peut être passée en paramètre à une autre
fonction, récupérée en paramètre de retour etc.
Haskell supporte les fonctions anonymes et les fonctions « lambda ».
Cela permet par exemple de décrire une fonction (simple) dans la zone
de paramètres d'une autre fonction.
Un bon exemple vaut mieux qu'un long discours :
map (+1) [1..10]
map est une fonction à 2 arguments : une fonction et une liste (ici
[1..10]). Comme on peut s'y attendre, map applique la fonction à tous
les éléments de la liste et retourne une liste résultante.
Mais mais mais ??? « (+1) » c'est une fonction ? Eh bien oui, c'est
une fonction anonyme (je ne l'ai pas déclarée avec un petit nom).
Et la fonction « + » prend bien 2 arguments ? Je n'en voit qu'un (le 1
dans l'exemple)? Il s'agit du mécanisme d' « évaluation partielle » de
Haskell.
Si vous avez une fonction de 2 paramètres et que vous
fournissez les 2 paramètres, c'est super.
Mais si vous ne fournissez qu'un paramètre, le résultat de l'opération
sera… Une fonction bien sur ! Une fonction de l'autre paramètre.
Et cette fonction à un paramètre est ce qu'attend la fonction map.
Quizz: quel est le résultat de cette ligne de code ?
Haskell supporte la curryfication. Cette opération, du nom de son
inventeur, est à la base d'Haskell. D'ailleurs, devinez le prénom de
ce Mr Curry… Haskell bien sur !!
Il existe bien sùr une algèbre sur les fonctions : l'addition, la composition…
Vous pouvez donc définir une fonction en une ligne par simple
composition de deux autres fonctions à l'aide de l'opérateur rond « °
». Ce qui rend les choses assez lisible : dans un gros programme les
fonctionnalités de haut niveau sont souvent cassés en plusieurs
fonctions plus simple. Une fois définis les fonctions simples, vous
les ressemblez en une ligne avec l'opérateur rond.
Haskell est statiquement et fortement typé.
Le système de typage est très évolué, et vous évitera de nombreuses erreurs
de programmation.
Une fois que votre programme compile (ce qui peut prendre un certain
temps...) vous pouvez pratiquement être sur qu'il marche!
En effet le typage est très fort et filtrera de nombreuses erreurs de logique.
Grâce au système d'inférence de types, vous pouvez vous épargner la peine
d'écrire les types de vos fonctions. Le compilateur déduira lui-même le type le plus général.
Je termine par le plus dur :
Haskell est un langage fonctionnel « pur ».
Cela signifie qu'il n'y a aucuns effets de bords, et donc qu'il ne
supporte pas l'affectation.
Par exemple dans un programme en C, je pourrais avoir l'instruction suivante :
a = f + g
f et g sont des fonctions, a un entier.
Dans le cadre d'un refactoring, je pourrais être amené à vouloir écrire :
a = g + f
Eh bien ce n'est à priori pas possible. En C comme dans d'autres
langages, les fonctions ont des effets de bord : f peut modifier le
contexte qui sera utilisé par g.
En Haskell, le retour d'une fonction dépend uniquement de ses
paramètres, de rien d'autre. Si vous l'appelez à n'importe quel moment
avec les mêmes paramètres, le résultat sera le même.
Cela donne une très grande plasticité et maintenabilité au programme.
Tout devient plus clair !
Mais il faut reconnaître que les programmes sont plus difficiles à écrire.
Cette aspect « pas d'affectation » ouvre la porte à de nombreuses
fonctionnalités impossible sans, dont la paresse.
A noter aussi que comme conséquence, l'ordre des instructions n'a pas
d'importance… Haskell est uniquement déclaratif.
Haskell intègre aussi de nombreuses autres fonctionnalités que je n'ai
malheureusement pas le temps de développer ici, dont :
- la compréhension de listes
- le pattern matching pour les paramètres
- les monades et les classes de types…
Références :
www.haskell.org
http://en.wikipedia.org/wiki/Haskell...ming_language))
Ouvrages de référence :
Yet Another Haskell Tutorial
A Gentle Introduction to Haskell
La traduction en Français par Nicolas Vallée (alias Gorgonite):
A Gentle Introduction to Haskell, version 98
Contrairement à ce que son nom indique, ce dernier ouvrage n'est pas
gentil du tout , je vous conseille plutôt de commencer par :
Haskell for C Programmers
J'ai fait une traduction en Français de ce dernier ouvrage:
Tutorial Haskell pour le développeur C
Corentin DUPONT (Kau)
Partager