aboutsummaryrefslogtreecommitdiff
path: root/content/Informatique/2012-11-09-fonctionnel.rst
diff options
context:
space:
mode:
Diffstat (limited to 'content/Informatique/2012-11-09-fonctionnel.rst')
-rw-r--r--content/Informatique/2012-11-09-fonctionnel.rst190
1 files changed, 0 insertions, 190 deletions
diff --git a/content/Informatique/2012-11-09-fonctionnel.rst b/content/Informatique/2012-11-09-fonctionnel.rst
deleted file mode 100644
index 06d75d0..0000000
--- a/content/Informatique/2012-11-09-fonctionnel.rst
+++ /dev/null
@@ -1,190 +0,0 @@
-
-Programmation fonctionnelle
-###########################
-
-:date: 2012-11-09
-:tags: Programmation
-
-Dans cet article, je vais essayer de présenter différents cas de programmation
-fonctionnelle en essayant de partir d'un cas pratique pour présenter les
-difficultés et solutions disponibles.
-
-Je vais présenter ici des exemples dans le langage python, par ce qu'il s'agit
-d'un langage simple, pouvant être utilisé de manière fonctionnelle (dans une
-certaine limite). Je me contente d'un python `basique` et ne vais pas chercher
-entrer dans des syntaxes spécifiques, le but étant ici de servir de support, et
-non pas de présenter le langage.
-
-Un besoin
-=========
-
-Imaginons la situation suivante : une application reçoit des données d'un
-client et doit les traiter. Ces données arrivent dans des fichiers textes,
-chaque ligne du fichier correspond à une donnée à traiter.
-
-Un programme
-============
-
-Commençons le programme, pour lire le fichier commençons par le localiser :
-
-.. code-block:: python
-
- def get_file(nom):
- chemin = os.path.join("repertoire", nom)
- return open(chemin)
-
-Cette fonction est simple : elle prend en argument un nom de fichier, et
-retourne le fichier correspondant. On peut également dire qu'elle effectue la
-transformation suivante :
-
-.. code-block:: ocaml
-
- get_file: String -> File
-
-Cette notation indique que le type de la fonction est le suivant : elle prend
-un string en entrée, et retourne un file en sortie. Nous l'utiliserons
-régulièrement dans cet article.
-
-Dans notre cas, nous n'avons pas un fichier a traiter, mais une série de
-fichiers. Nous allons donc devoir appeler la fonction sur tous nos nom de
-fichiers. La première solution est la solution itérative, à travers une boucle
-:
-
-.. code-block:: python
-
- def transforme(noms):
- fichiers = []
- for nom in noms
- fichiers.append(get_file(nom))
- return fichiers
-
-À la fin de l'exécution de la boucle, la liste `fichiers` contient la liste des
-fichiers construits à partir de la liste `noms`.
-
-C'est une opération très fréquente et bien qu'elle soit très courte. Essayons
-de réfléchir un peu à ce que nous venons de faire en terme de type : notre but
-est de transformer une liste de String en liste de File de la manière suivante
-:
-
-.. code-block:: ocaml
-
- transforme: List[String] -> List[File]
-
-Si l'on généralise, on peut essayer de créer une fonction qui aurait le schéma
-suivant :
-
-.. code-block:: ocaml
-
- transforme: List[A] -> List[B]
-
-Cette fonction a par contre besoin d'une transformation à appliquer pour
-transformer A en B, dans notre cas, cette transformation a déjà été créée plus
-haut !
-
-Notre schéma devient donc le suivant :
-
-.. code-block:: ocaml
-
- transforme: (A -> B) -> List[A] -> List[B]
-
-Récrivons donc notre fonction transforme de cette manière:
-
-.. code-block:: python
-
- def transforme(func, source):
- results = []
- for nom in source
- results.append(func(nom))
- return results
-
- fichiers = transforme(get_file, noms)
-
-Et voilà ! Nous avons maintenant notre fonction générique, destinée à changer
-le contenu de notre liste. Qu'est ce que cela apporte par rapport à la version
-impérative que nous avons écrit tout à l'heure ? En fait pas grand chose. Sauf
-que la fonction `transforme` est présente nativement dans python. Elle
-s'appelle en fait `map`, et effectue le même travail.
-
-Nous aurions donc tout aussi bien pu écrire :
-
-.. code-block:: python
-
- fichiers = map(get_file, noms)
-
-Une réflexion
-=============
-
-Pourquoi avoir écrit tout ça ? Par ce que semblant de rien, nous avons changé
-notre manière de concevoir le programme : au lieu d'écrire une suite
-d'instructions qui s'exécutent séquentiellement, nous venons d'appliquer des
-transformations dans un contexte : la liste des noms de fichiers est notre
-contexte de base, sur lequel nous appliquons des transformations pour créer un
-autre contexte.
-
-Ces transformations ne modifient pas notre contexte initial, et par la suite
-les transformations que nous continueront d'appliquer ne modifieront rien non
-plus de notre environnement. Dans cet esprit, l'ensemble du programme peut être
-perçu comme un grande transformation qui s'applique sur un point d'entrée
-initial.
-
-Une théorie
-===========
-
-La fonction `map` que nous venons de présenter ici, s'inscrit en fait dans un
-cadre de fonctions plus vaste : les foncteurs_. Il s'agit d'une notion
-mathématique que l'on retrouve appliquée en informatique.
-
-.. _foncteurs: http://fr.wikipedia.org/wiki/Foncteur
-
-Comme vu précédemment, un objet foncteur F est un objet ayant la signature
-suivante :
-
-.. code-block:: ocaml
-
- map: (A -> B) -> F[A] -> F[B]
-
-Le foncteur a deux contraintes, qui sont plutôt intuitives:
-
-identité
---------
-
-Soit la fonction `id` défini comme suit:
-
-.. code-block:: python
-
- def id(x):
- return x
-
-alors on a l'égalité suivante :
-
-.. code-block:: python
-
- map(id, fichiers) == fichiers
-
-Autrement dit, le foncteur ne doit pas modifier la structure de la donnée. On
-peut essayer de repenser la fonction `transforme` écrite plus haut pour briser
-cette règle, je laisse au lecteur le soin de réfléchir à cette question.
-
-composition
------------
-
-La deuxième contrainte est celle de la composition :
-
-.. code-block:: python
-
- map(f(g), source) = map(f, map(g, source))
-
-C'est à dire qu'il est possible de composer les fonctions les entre elles :
-c'est encore heureux, car cela permet de chaîner les traitements entre eux…
-
-Une conclusion
-==============
-
-Notre contexte est ici une liste, mais nous allons voir par la suite qu'il en
-existe beaucoup d'autres, ce qui va nous faciliter la vie… Cela va venir dans
-les articles qui suivent.
-
-Une fois les deux contraintes validées, nous allons pouvoir construire de
-nouveaux types basés sur ce foncteur. Et derrière la solution informatique mise
-en place, je vais essayer de présenter les concepts mathématiques qui sont
-derrière.