Ici on voir la possibilité de définir une fonction, et de l'appliquer à toute une liste pour obtenir une nouvelle liste contenant les résultats, et ensuite la combinaison de deux fonctions "au vol" pour faire pareil. Ça n'a rien de révolutionnaire, on peut le faire dans tous les langages, mais c'est plus élégant formulé en fonctionnel (Ruby a trouvé un très bon compris entre fonctionnel et imperatif).
Mais là ou ça devient intéressant, c'est quand on fixe une partie des paramètres d'une fonction, et que ça nous donne une nouvelle fonction (c'est moche en scheme, c'est plus joli en ocaml):
1:=> (define add (lambda (x) (lambda (y) (+ x y))))
add
1:=> ((add 1) 3)
4
Ce qui est intéressant c'est que add est une fonction, et quand on écrit (add 1) on obtient une fonction dans laquelle le premier paramètre est fixé à 1. Par conséquent:
1:=> (map (add 2) ma_liste)
(3 5 44 15 71 12 4)
Je vous l'accorde, ce sont des exemples plutôt maladroits parce que les manipulations sont trop simples et peuvent être faites aussi facilement dans un autre langage. L'idée importante c'est qu'en programmation fonctionnelle, une fonction étant une liste comme une autre, on peut la traiter comme un objet "normal". Par conséquent il est très facile de faire des assemblages de fonctions pendant l'exécution du programme, et donc de faire un programme qui "se réécrit tout seul", c'est pour ça que c'est beaucoup utilisé en intelligence artificielle. On peut faire la même chose en C, mais c'est extrêmement laid.
Ici, au risque d'insister, (map (add 2) ma_liste) est plus intéressant que définir d'abord une fonction toto qui ajoute 2, puis faire (map toto ma_liste). La fonction (add 2) est produite lors de l'évaluation de la ligne, et pourrait être bien plus complexe qu'une addition:
1:=> (map (lambda (x) ((add x) (square x))) ma_liste)
(2 12 1806 182 4830 110 6)
Pour chaque élément x de la liste, on ajoute x au carré de x, et on place le résultat dans une liste.
[^] # Re: un environnement
Posté par Yusei (Mastodon) . En réponse au journal Lisp: pourquoi est-ce different ?. Évalué à 5.
1:=> (define square (lambda (x) (* x x)))
square
1:=> (define ma_liste '(1 3 42 13 69 10 2))
ma_liste
1:=> (map square ma_liste)
(1 9 1764 169 4761 100 4)
1:=> (define add_one (lambda (x) (+ x 1)))
add_one
1:=> (map (lambda (x) (add_one (square x))) ma_liste)
(2 10 1765 170 4762 101 5)
Ici on voir la possibilité de définir une fonction, et de l'appliquer à toute une liste pour obtenir une nouvelle liste contenant les résultats, et ensuite la combinaison de deux fonctions "au vol" pour faire pareil. Ça n'a rien de révolutionnaire, on peut le faire dans tous les langages, mais c'est plus élégant formulé en fonctionnel (Ruby a trouvé un très bon compris entre fonctionnel et imperatif).
Mais là ou ça devient intéressant, c'est quand on fixe une partie des paramètres d'une fonction, et que ça nous donne une nouvelle fonction (c'est moche en scheme, c'est plus joli en ocaml):
1:=> (define add (lambda (x) (lambda (y) (+ x y))))
add
1:=> ((add 1) 3)
4
Ce qui est intéressant c'est que add est une fonction, et quand on écrit (add 1) on obtient une fonction dans laquelle le premier paramètre est fixé à 1. Par conséquent:
1:=> (map (add 2) ma_liste)
(3 5 44 15 71 12 4)
Je vous l'accorde, ce sont des exemples plutôt maladroits parce que les manipulations sont trop simples et peuvent être faites aussi facilement dans un autre langage. L'idée importante c'est qu'en programmation fonctionnelle, une fonction étant une liste comme une autre, on peut la traiter comme un objet "normal". Par conséquent il est très facile de faire des assemblages de fonctions pendant l'exécution du programme, et donc de faire un programme qui "se réécrit tout seul", c'est pour ça que c'est beaucoup utilisé en intelligence artificielle. On peut faire la même chose en C, mais c'est extrêmement laid.
Ici, au risque d'insister, (map (add 2) ma_liste) est plus intéressant que définir d'abord une fonction toto qui ajoute 2, puis faire (map toto ma_liste). La fonction (add 2) est produite lors de l'évaluation de la ligne, et pourrait être bien plus complexe qu'une addition:
1:=> (map (lambda (x) ((add x) (square x))) ma_liste)
(2 12 1806 182 4830 110 6)
Pour chaque élément x de la liste, on ajoute x au carré de x, et on place le résultat dans une liste.