26 septembre 2026 — Programmation fonctionnelle, Modèles de calcul
Nous choisissons les idées que nous représentons par les symboles non-définis et les faits que nous énonçons par les P non-démontrées; (…) Alors, le système des idées que nous avons choisi d’abord n’est qu’une interprétation du système des symboles non-définis; mais, au point de vue déductif, cette interprétation peut être ignorée par le lecteur, qui peut librement la remplacer, dans sa pensée, par une autre interprétation qui vérifie les conditions énoncées par les P non-démontrées. (…) Ainsi les questions logiques acquièrent une complète indépendance à l’égard des questions empiriques ou psychologiques (et, en particulier, du problème de la connaissance)
— Alessandro Padoa, Essai publié en 1901
Dans cet article, je voudrais vous parler du lambda-calcul, que l’on peut voir comme une sorte de langage de programmation ésotérique basé sur une syntaxe très concise.
Il permet néanmoins d’implémenter les mêmes fonctions qu’un langage de programmation classique : les plus geeks apprécieront peut-être ce projet !
Une façon plus sophistiquée de dire cela est de dire que le lambda-calcul est un modèle de calcul complet au sens de Turing.
Par ailleurs, des langages de programmation fonctionnels comme Haskell, OCaml ou Lean utilisent une représentation interne des programmes fortement inspirée du lambda-calcul, ce qui fait que les considérations abordées ici peuvent avoir des implications très concrètes.
Tout ce que je présente ici est détaillé de façon plus approfondie dans le cours de Jean Goubault-Larrecq.
La syntaxe du lambda-calcul
Le langage du lambda-calcul peut se définir (en notation BNF) de la façon suivante :
Cette notation définit l’ensemble des phrases valides du langage — on parlera plutôt de termes.
désignant l’ensemble des variables, les termes du lambda-calcul peuvent donc être de trois formes :
La β-réduction : un jeu formel ?
Quand on considère une abstraction comme , on a envie de la considérer comme une fonction (dans ce cas l’identité). De même, on pourrait avoir envie de considérer une application comme le fait d’invoquer une fonction (le premier terme de l’application) sur un argument (le second terme).
La β-réduction (beta-réduction) capture en quelque sorte cette idée. Cependant, il ne s’agit pas ici de donner un sens aux termes mais plutôt de décrire un jeu formel qui correspond simplement à des manipulations syntaxiques sur les termes.
Cette opération, notée , consiste à remplacer dans un sous-terme de la forme les occurrences de dans par .
Par exemple :
Dans le troisième exemple, j’ai utilisé implicitement la règle d’α-conversion (alpha-conversion) pour remplacer par . Il s’agit d’une règle qui permet de renommer les variables, permettant notamment d’éviter les conflits de noms.
En pratique, les implémentations du lambda-calcul utilisent généralement des indices positionnels plutôt que des noms pour désigner les variables liées, ce qui permet d’éviter ce genre de considérations (c’est notamment le cas dans Lean).
Ainsi défini, le lambda-calcul semble être un jeu de manipulations formelles sur des chaînes de caractères, la réduction (j’omettrai dorénavant le β) correspondant à une opération que l’on peut effectuer de façon séquentielle, comme une forme de calcul :