July 30, 2012

La programmation fonctionnelle

Le paradigme

Dans la programmation impérative, on dit á l'ordinateur toutes les opérations á exécuter pas á pas.

Dans la programmation fonctionnelle, on définit des fonctions mathématiques.

Au lieu d'écrire la recette pas-á-pas, on definit mathématiquement les données que la machine doit retourner pour chaque ensemble d'entrées possibles.

La logique impérative peut être émulée par une pratique qui s'appelle pipelining (canalisation) - c'est á dire donner la sortie d'une fonction comme argument á la fonction suivante.

Le programme, c'est un fonction!
Tout le programme n'est qu'une grande fonction mathématique, composée de fonctions mineures (qui sont composées de fonctions plus mineures, et caetera...)

Composition

Composer des expressions et des fonctions, c'est une feature trés utile dans toutes les langues, mais c'est en fait le coeur de la programmation fonctionnelle. Les programmes sont réalisés en composant des fonctions.

Expressions sont des fonctions aussi bien. L'opérateur est la fonction elle-même et les opérandes sont ses arguments.

Exemple: 2 + 2 est la même chose que ajoute(2, 2)

Pas de variables...

Il n'y a pas des variables pour stocker nos données! Il n'y a que les fonctions!

Les constantes, elles peuvent être imitées par une fonction ne prennant pas d'entrées est produisant toujours le même résultat. (C'est la fonction constante.) Alors, le programme ne peut pas rédéfinir une fonction...

Dans la programmation fonctionnelle, 'variable' signifie la même chose que dans les mathématiques: elle représente une des valeurs d'un ensemble, n'importe quelle valeur. On ne peut pas la fixer á une valeur concréte.

Exemple:
f(x) = x^2 + 2x + 3

La variable ici est x.
La programmation fonctionnelle est de definir des fonctions comme cette-ci.

Il n'y a pas d'états!
Alors, les variables n'avont pas aucune valeur concréte, car ils représentent n'importe quelle valeur d'un ensemble. Á cette cause, la programme n'a pas aucun "état actuel" (ou aucun d'autres états).

Il ne faut pas dessiner des diagramme d'états pour ces programmes!
(Les diagrammes d'états sont merde!)

Pas d'effets secondaires
L'effet secondaire (side effect), dans la programmation imperative, signifie qu'une fonction peut changer quelque variable dans le monde extérieur.

Encapsulation est un moyen de reduire les effets secondaires, mais jamais complétement. Il peut avoir des variables globales qu'on peut changer d'interieur d'un fonction...

Mais pas dans la programmation fonctionnelle! Il n'y a pas d'effets secondaires. Pas du tout. (Alors, il n'y a pas de variables á changer...)


Les 5 briques de la programmation

Depuis l'arrivée de la programmation structurelle, on sait qu'il n'y a plus que 5 blocs de construction dont tout les programmes peuvent être réaliser. Même les systémes d'exploitation sont construits de ces blocs.

Ils sont:
- Input (entrées)
- Output (sorties)
- Opérations arithmétiques 
- Le conditionnel (IF)
- Répétition (FOR)

Input et Output (I/O) sont realizé d'un façon différente dans chaque langue.
Les opérateurs arithmetiques sont toutes des fonctions.

Alors, qu'en est-il la répétition et le conditionnelle?

Le conditionnel
Le résultat d'un bloc conditionnel dépend dépend si la condition soit vrai ou faux? La condition est une expression logique: prédicats composés á une déclaration utilisant les opérateurs logiques.


Un prédicat dit quelque chose de la valeur d'un variable.

Exemple: "x = 3 and y >10" 
 
Ce sont de deux prédicats composés á l'aide d' un opérateur AND.

La conditionnel existe dans toutes les langues fonctionnels, mais comme une fonction mathématique...

- Les entrées sont les valeurs des variables dans les prédicats
- Les sorties sont les résultats de l'instructions exécutées.

Important: il doit y avoir toujours une section ELSE car une function doit donner quelque sortie pour chaque entrée possible. Elle ne peut pas rester en silence.


Ainsi important: on ne peut pas parlers des "instructions", mais la spécification des valeurs de retour. Il ne peut pas y avoir des autres choses comme changer le valeur d'un variable locale ou globale. (Voir "pas de variables"!)

Exemple:
IF blah blah blah THEN valeur de retour doit
être "asdf".
ELSE
valeur de retour doit être "ghjk".


La répétition...
Le programme est pas une ordre d'instructions mais la définition d'une fonction mathématique, donc il n'y a pas aucune instruction explicite pour la répétition.

Il faut choisir entre deux choses pour faire l'ordinateur repéter l'éxecution d'une fonction, selon la cause á laquelle on veut la faire...

Avec des listes...
La liste devient utile et versatile á l'extréme dans le mond de programmation fonctionnel.

Á lieu d'utiliser l'instruction FOR, on peut définir (ou utiliser) une fonction que prend une liste comme input et pas une seule valeur.

Les langues fonctionnelles fournissent une multitude de choses magnifiques á travailler avec des listes!


Á cause de leur importance dans cet paradigme, une des langues fonctionnelles les plus vielles s'appelle en fait "list processor" (LISP).

Mais il ne doit pas y avoir une fonction des listes, mais on peut itérer (répéter) une fonction des valeurs seules sur une liste soit avec une fonction spécial (fournie par le systéme) ou une liste en compréhension (list comprehension).

(Ces choses sont similaires á l'instruction foreach dans la langue Java.)

Ou avec la récursion
L'autre moyen de répéter une fonction, c'est la récursivité: la fonction qui appelle elle-même.

Example:
def blast(x):
   if x<=0 : return "Ignition!"
   else: return blast(x-1)


(La syntax est celle de Python.)

La récursion fonctionne juste comme l'instruction WHILE dans les langues impératives:  l'auto-appel est toujours mis dans une instruction IF (ou la section ELSE dedans), qui signifie que la fonction sera répétée si long que la condition est vrai (ou faux, s'il est dans la section ELSE).

Listes en compréhension 
La liste en compréhension est fourni par la syntaxe de la langue. Elle est similaire á l'ensemble en compréhension enseigné á l'école.

Exemple:
S = [ 3x+2 | x ∈ [1..360], sin(x) > 0 ]

La fonction: 3x+2
La domaine (liste de source): [1..360]
Le prédicat de filtrage: sin(x) > 0

On peut négliger le prédicate ou remplacer la fonction par un simple 'x'.

No comments: