Skip to main content

Programmation fonctionnelle - Introduction

Concepts et terminologie

  • Ecriture fonctionnelle : programmation par applications de fonctions plutôt que par l'exécution de séquences d'instructions
  • Transparence référentielle : chaque expression peut être remplacée par son résultat sans changer le comportement du programme - sans effets de bord
  • Programmation fonctionnelle pure : sans effets de bords, avec transparence référentielle
  • Fonctions de première classe : type fonction, constantes fonction, opérateurs sur les fonctions
  • Type dynamique : les variables sont typées au moment de l'exécution et non au moment de la compilation
  • Références : ce sont les adresse sur des objets, elles sont utilisées chaque fois que les contenus ne sont pas utiles (passages de paramètres, retours de fonctions)
  • Garbage collector : gestion dynamique et automatique de la mémoire. L'utilisateur ne s'occupe pas de désallouer la mémoire

Le λ\lambda-calcul

  • Variables : x,y,...x,y,...
  • Applications : si uu et vv sont des λ\lambda-termes uvuv est aussi un λ\lambda-terme. On peut alors voir uu comme une fonction et vv comme un argument, uvuv étant alors l'image de vv par la fonction uu.
  • Abstractions : si xx est une variable et uu un λ\lambda-terme alors λxu\lambda x u est un λ\lambda-terme. Intuitivement, λx.u\lambda x.u est la fonction qui à xx associe uu

La substitution

Cette opération permet de remplacer les occurences d'une variable par un terme pour réaliser le calcul des λ\lambda-termes. On note t[x:=u]t[x:=u] la substitution dans un lambda terme tt de toutes les occurrences d'une variable xx par un terme uu.

  • Variables : si tt est une variable alors t[x:=u]=ut[x:=u]=u si x=tx=t et tt sinon
  • Application : si t=vwt=vw alors t[x:=u]=v[x:=u]w[x:=u]t[x:=u]=v[x:=u]w[x:=u] si vv et ww sont des termes
  • Abstraction : si t=λyvt=\lambda y v alors t[x:=u]=λy(v[x:=u])t[x:=u]=\lambda y (v[x:=u]) si xyx \neq y et yy n'est pas une variable libre de uu. Si yy est une variable libre de uu, on renomme yy avant de substituer. Si x=yx=y le résultat est tt.

La β\beta-réduction

On appelle rédex un terme de la forme (λx.u)v(\lambda x.u)v. On définit alors la β\beta-réduction

(λx.u)vu[x:=v] (\lambda x .u)v \rightarrow u[x:=v]a$

  • La réduction du terme (λx.u)v(\lambda x.u)v est la valeur de la fonction λx.u\lambda x.u appliquée à la variable vv
  • uu est límage de xx par la fonction (λx.u)(\lambda x.u)
  • L'image de vv est obtenue en substituant dans uu,xx par vv

La normalisation

Un lambda terme tt est dit en forme normale si aucune β\beta-réduction ne peut lui être appliquée, c'est à dire si tt ne contient aucun rédex.

Lien avec la syntaxe lisp

La syntaxe lisp est complètement basée sur le λ\lambda-calcul. Les parenthèses servent à délimiter les termes et les application

  • Variables : xx, et constantes de types numériques, symbolique, fonctionnel etc
  • Abstractions fonctionnelles : λx.y\lambda x.y s'écrit (lambda(x),y)
  • Application : uvuv s'écrit (u v)

Développement incrémental

Boucle Read Eval Print : REPL

  1. Read : Lecture d'une expression
  2. Eval : calcul (réduction) de l'expression
  3. Print : affichage du résultat (forme normale)
  4. Affichage du prompt > et retour à 1