Fonctions de première classe et anonymes

En Common Lisp, les fonctions sont souvent utilisées pour paramétrer le comportement d'autres fonctions. Pour cela, il est nécessaire de passer une fonction en argument à une autre fonction. On qualifie de première classe un objet qui peut être ainsi passé en argument d'une fonction, être la valeur d'une variable ou encore être renvoyé en tant que valeur d'une fonction. En Common Lisp, les fonctions sont de première classe.

À cause des multiples espaces de noms (voir section 7.1), on ne peut pas passer directement une fonction définie globalement comme argument à une autre fonction. Il faut un moyen de traverser les espaces de noms.

Pour passer de l'espace des noms de fonctions à celui des noms de variables, on utilise l'opérateur spécial function. Cet opérateur accepte un seul argument, le nom de la fonction. La valeur de l'expression est la fonction. L'effet est similaire à celui de symbol-function, sauf que function tient compte des définitions locales de fonctions (voir section 7.3) :

* (defun bla () 88)

BLA
* (flet ((bla (x) x))
    (eq (symbol-function 'bla) (function bla)))

NIL
*

L'utilisation de function est tellement fréquente, que la fonction read propose l'abréviation : #'. De plus, c'est la syntaxe utilisée par print :

* '(function f)

#'F
* (car '#'f)

FUNCTION
* (cdr '#'f)

(F)
*

L'opérateur function permet aussi de construire une fonction anonyme à partir d'une lambda-expression. Une telle expression est simplement une liste dont le premier élément est le symbole lambda suivi d'une liste de paramètres (voir section 7.2), suivie du corps de la fonction. Exemple :

* (setf (symbol-function 'g) #'(lambda (x) (+ 4 x)))

#<Interpreted Function (LAMBDA (X) (+ 4 X)) 480137E1>
* (g 2)

6
*

Pour simplifier encore, la macro lambda permet de supprimer l'opérateur function :

* (setf (symbol-function 'h) (lambda (x) (* x x)))

#<Interpreted Function (LAMBDA (X) (* X X)) 48028B09>
* (h 10)

100
*

Irene DURAND
2011-10-14