• Aucun résultat trouvé

Lambda-calcul et programmation

N/A
N/A
Protected

Academic year: 2022

Partager "Lambda-calcul et programmation"

Copied!
80
0
0

Texte intégral

(1)

Lambda-calcul et programmation

Jean-Jacques L évy INRIA

9-12-2009

mardi 8 décembre 2009

(2)

Plan

Quelques langages de programmation:

-

Lambda calcul pur

-

PCF pur

-

PCF typé

-

Caml

-

Haskell

Programmation fonctionnelle

Impacts de la programmation fonctionnelle

Futur

(3)

Lambda-calcul pur

mardi 8 décembre 2009

(4)

Le langage

Les lambda-expressions

M, N, P ::= x, y, z, ... (variables)

| λx.M (M fonction de x)

| M ( N ) (M appliqué à N)

Calculs “réductions”

(λx.M)(N) M{x := N}

(5)

Exemples de calcul

Exemples

(λx.x)N N

(λf .f N)(λx.x) (λx.x)N N

mardi 8 décembre 2009

(6)

Exemples de calcul

Exemples

(λx.x)N N

(λx.xx)(λx.xN) (λx.xN)(λx.xN) (λx.xN)N NN (λx.xx)(λx.xx) (λx.xx)(λx.xx) · · ·

(λf .f N)(λx.x) (λx.x)N N

(7)

Exemples de calcul

Exemples

(λx.x)N N

(λx.xx)(λx.xN) (λx.xN)(λx.xN) (λx.xN)N NN (λx.xx)(λx.xx) (λx.xx)(λx.xx) · · ·

(λf .f N)(λx.x) (λx.x)N N

f (Yf ) f (f (Yf )) · · · f n(Yf ) · · ·

Yf = (λx.f (xx))(λx.f (xx)) f ((λx.f (xx))(λx.f (xx))) = f (Yf )

mardi 8 décembre 2009

(8)

Calculer dans le lambda- calcul

Booléens

Paires et projections

Entiers ...

Vrai = λx.λy.x = K Faux = λx.λy.y

0 = �Vrai, Vrai� n + 1 = �Faux, n�

Vrai M N M Faux M N N

π1�M, N� M π2�M, N� N

Zero? 0 Vrai

Zero?(n + 1) Faux

�M, N� = λx.xMN π1 = λx.x (Vrai) π2 = λx.x (Faux)

(9)

Calculer dans le lambda- calcul

... Entiers

Succ = λx.�Faux, x�

Pred = λx. Zero? x 0 π2

mardi 8 décembre 2009

(10)

Calculer comme Church

Lambda-I calcul

λx.M (M fonction non constante de x)

Entiers de Church n = λf .λx.f n(x)

Paires et projections

I = λx.x n I I

�M, N� = λx.xMN

π1 = λp.p(λx.λy.y I x) π2 = λp.p(λx.λy.x I y

π1�m, n� m π2�m, n� n

K = λx.λy.x

pas de

n ≥ 1

(11)

Calculer comme Church

Lambda-I calcul

λx.M (M fonction non constante de x)

Entiers de Church n = λf .λx.f n(x)

Paires et projections

I = λx.x n I I

�M, N� = λx.xMN

π1 = λp.p(λx.λy.y I x) π2 = λp.p(λx.λy.x I y

π1�m, n� m π2�m, n� n n ≥ 1

mardi 8 décembre 2009

(12)

Calculer comme Church

... Entiers

Succ = λn.λf .λx.n f (f x) Pred = λn. π33 (n φ �1, 1, 1�)

où sont les 3 projections sur les tripletsπ13, π23, π33

4 3 2

3 2 1

2 1 1 φ registre à décalage! FIFO

φ = λt.(λx.λy.λz.�Succ x, x, y�)(π13 t)(π23 t)(π33 t)

(13)

Calculer comme Church

Alonzo Church

Stephen Kleene

mardi 8 décembre 2009

(14)
(15)

mardi 8 décembre 2009

(16)
(17)

mardi 8 décembre 2009

(18)

PCF

(19)

Le langage

Les termes

M, N, P ::= x, y, z, ... (variables)

| λx.M (M fonction de x)

| M ( N ) (M appliqué à N)

| n (constante entière)

| M ⊗ N (opération arithmétique)

| ifz P then M else N (conditionnelle)

Les calculs (“réductions”)

(λx.M)(N) M{x := N} m ⊗ n m⊗n

ifz 0 then M else N M ifz n+1 then M else N N

mardi 8 décembre 2009

(20)

Exemples de termes

(λx. x + 1)3 3 + 1 4

(λx. 2 ∗ x + 2)4 2 ∗ 4 + 2 8 + 2 10

(λf .f 3)(λx. x + 2) (λx.x + 2)3 3 + 2 5 (λf .λx.f (f x))(λx.x + 2) ...

(21)

(λf .λx.f (f x))(λx. x + 2) ...

mardi 8 décembre 2009

(22)

(λf .λx.f (f x))(λx. x + 2) ...

(23)

(λf .λx.f (f x))(λx.x + 2)3 ...

mardi 8 décembre 2009

(24)

Exemples de termes

s’écrit Fact(3)

Fact = Y (λf .λx. ifz x then 1 else x � f (x − 1)) Y = λf .(λx.f (xx))(λx.f (xx))

(λ Fact . Fact(3))

( (λY .Y (λf .λx. ifz x then 1 else x � f (x − 1))) (λf .(λx.f (xx))(λx.f (xx))) )

(25)

mardi 8 décembre 2009

(26)

(27)

mardi 8 décembre 2009

(28)
(29)

mardi 8 décembre 2009

(30)
(31)

mardi 8 décembre 2009

(32)
(33)

mardi 8 décembre 2009

(34)
(35)

mardi 8 décembre 2009

(36)
(37)

mardi 8 décembre 2009

(38)

Propriétés

Beaucoup de calculs différents

Unicité du résultat (confluence -- Church Rosser)

Plusieurs stratégies de réduction

- Appel par nom (contracter le redex le + à gauche, le + externe)

- Appel par valeur (on calcule d’abord la valeur des arguments)

- Appel par nécessité (variante de l’appel par nom avec partage)

(39)

-Appel par nom

-Appel par valeur

mardi 8 décembre 2009

(40)

- Appel par nécessité

(λf .λx.f (f x))((λy.λx.x + y)2)3 ...

(41)

Calcul par valeur

Une valeur est tout terme stable par réduction et par substitution par des valeurs [i.e. un terme dont le résidu est toujours une valeur].

Valeurs possibles:

x, y, z, ... (variables)

λx.M (M fonction de x)

n (constante entière)

mardi 8 décembre 2009

(42)

Calcul par nécessité

Le partage n’est pas simple dans le calcul, car il faut partager des fonctions !

Le partage est facile à réaliser dans le lambda

calcul dit faible où on ne réduit pas sous les lambda (ex: Haskell)

(43)

PCF typé

mardi 8 décembre 2009

(44)

Le langage

Les termes

Les calculs (“réductions”)

(λx.M)(N) M{x := N} m ⊗ n m⊗n

ifz 0 then M else N M

M, N, P ::= x, y, z, ... (variables)

| λx.M (M fonction de x)

| M ( N ) (M appliqué à N)

| n (constante entière)

| M ⊗ N (opération arithmétique)

| ifz P then M else N (conditionnelle)

| Y (récursion)

(45)

Le langage

Les termes

Les calculs (“réductions”)

(λx.M)(N) M{x := N} m ⊗ n m⊗n

ifz 0 then M else N M ifz n+1 then M else N N

M, N, P ::= x, y, z, ... (variables)

| λx.M (M fonction de x)

| M ( N ) (M appliqué à N)

| n (constante entière)

| M ⊗ N (opération arithmétique)

| ifz P then M else N (conditionnelle)

| Y (récursion)

YM M(YM)

: int

:(τ τ) τ

Les types

τ si x M si M τ N

: int si M,N:int si P:int M,N

mardi 8 décembre 2009

(46)

Intér êt du typage

+ = ???

Jamais

λx.xx

Jamais

λf .(λx.f (xx))(λx.f (xx))

3 + λx.x 4(5) 20(λx.x) ifzλx.x then 1 else 3

(47)

Intér êt du typage

λx.xx

Jamais

λf .(λx.f (xx))(λx.f (xx))

3 + λx.x 4(5) 20(λx.x) ifzλx.x then 1 else 3

mardi 8 décembre 2009

(48)

Intér êt du typage

λx.xx

Jamais

λf .(λx.f (xx))(λx.f (xx))

(49)

Intér êt du typage

mardi 8 décembre 2009

(50)

Intér êt du typage

Jamais de bogues de typage à l’exécution

termes plus naturels

PCF typé non récursif (sans Y ) est fortement normalisable [tous ses calculs terminent]

il faut un opérateur de récursion Y pour exprimer autant que PCF pur

(51)

Normalisation forte

pourquoi PCF typé non récursif termine ?

(λx.· · ·xN · · ·)(λy.M) · · ·(λy.M)N · · ·

(λx.λy.M)NP (λy.M)P

σ τ σ σ

σ τ

τ τ

+ théorème des développements finis crée

crée

mardi 8 décembre 2009

(52)

ML

(53)

Le langage

initialement le méta-langage de LCF (logic for computable functions) [robin milner, 1978]

PCF typé avec des types polymorphes

types de données récursifs (listes, arbres, etc)

filtrage (pattern matching)

inférence de type

quelques données sont modifiables : références, tableaux, champs d’enregistrements, ...

mardi 8 décembre 2009

(54)

Le langage

Les termes

M, N, P ::= x, y, z, ... (variables)

| λx.M (M fonction de x)

| M ( N ) (M appliqué à N)

| n (constante entière)

| M ⊗ N (opération arithmétique)

| ifz P then M else N (conditionnelle)

| Y (récursion)

| let x = M in N (définition polymorphe)

: int

Les calculs (“réductions”)

mêmes règles que pour PCF typé + règle suivante

:(τ τ) τ

Les types

τ si x M si M τ N

: int si M,N:int si P:int M,N {α := �τ} si x:α σ

si x:α σ M

(55)

Le langage

L’identité a le type suivant

succ = λx.x + 1 : int → int λx.x : α → α

let f = λx.x in f (3) + f (succ)(10)

Donc, l’expression suivante est typée

α.α α

int int

(int int) (int int) type polymorphe

mardi 8 décembre 2009

(56)

Le langage

let f = λx.x in f (3) + f (succ)(10) est typé,

(λf . f (3) + f (succ)(10))(λx.x) n’est pas typé.

Dans une fonction, toutes les occurences de l’argument ont un même type.

Ne pas confondre let x = M in N et (λx.N)M :

(57)

Le langage

Tout terme de ML a un type principal (le + général)

L’algorithme Damas-Milner, fondé sur l’unification de termes de 1er ordre, calcule ce type principal.

La complexité de cet algorithme est super exponentielle, mais quasi linéaire en pratique.

En ML, il y a donc inférence de type. Pas la peine d’entrer les types des termes manuellement.

mardi 8 décembre 2009

(58)

Le langage

Listes, tableaux, enregistrements polymorphes prédéfinis.

On définit aussi des types récursifs polymorphes à partir de constructeurs et autres types par sommation ou produit.

Le filtrage permet d’accéder facilement aux arguments des constructeurs.

Ocaml

(59)

Ocaml

mardi 8 décembre 2009

(60)

Le langage

Un vrai langage de programmation (pas de lettres grecques...)

version INRIA de ML [xavier leroy, et al]

a aussi des données modifiables (références, tableaux, chaînes de caractères, enregistrements)

stratégie d’évaluation en appel par valeur

modules pratiques et compréhensibles

a une partie orientée-objets

très bon environnement de programmation

simple et très efficace

plutôt sophistiqué comme premier langage

(61)

Le langage

L’identité a le type suivant

λx.x α → α

Donc, l’expression suivante est typée

α.α α

int int

(int int) (int int)

type polymorphe

mardi 8 décembre 2009

(62)

Le langage

Ne pas confondre let x = M in N et (λx.N)M :

(63)

Filtrage

Filtrage sur les listes

opérations avec types polymorphes

fonctions non destructives : arguments non modifiés.

mardi 8 décembre 2009

(64)

Filtrage

récurrence structurelle == récursion + filtrage

(65)

Filtrage

les fonctions sont des valeurs comme les autres

mardi 8 décembre 2009

(66)

Filtrage

les fonctions sont des valeurs comme les autres

(67)

Modules

Types abstraits

encapsulation des implémentations

compositionalité

implémentation

implémentation signature

mardi 8 décembre 2009

(68)

Haskell

(69)

Le langage

Un autre vrai langage de programmation

version GHC [simon peyton-jones, et al]

sépare les données modifiables (références, tableaux, chaînes de caractères, enregistrements) dans des monades

les monades peuvent utiliser tous les termes, mais seuls les monades peuvent appeler des monades

stratégie d’évaluation en appel par nom (langage paresseux)

permet la surcharge avec des type-classes

très bon environnement de programmation

un peu complexe

mardi 8 décembre 2009

(70)

Programmation fonctionnelle

(71)

Langages fonctionnels

Principalement des expressions:

-

PCF, booléens, n-uplets, listes, arbres, tableaux, records, chaînes

Aussi des instructions qui modifient la mémoire:

-

affectations, données modifiables (tableaux, records, chaînes), entrées/sorties

En Haskell, on sépare expressions et instructions avec les

``monades’’.

Principe des langages fonctionnels:

Réduire le nombre d’effets de bord dans les programmes

avec un minimum d’états mémoire et de données modifiables

Les types servent à identifier les données modifiables

mardi 8 décembre 2009

(72)

Langages fonctionnels

Un langage fonctionnel par valeur (Caml) vérifie:

(λx.M)N ≡ M{x := N}

(λx.M)V ≡ M{x := V}

Un langage fonctionnel par nom (Haskell) vérifie:

Des optimisations comme le partage des sous-expressions communes ou l’évaluation parallèle sont valides

Le raisonnement équationnel est aussi valide

La programmation devient plus sûre

(73)

Impact de la programmation fonctionelle

mardi 8 décembre 2009

(74)

Quelques succès

F# dans Visual Studio

generics de .NET, programmation fonctionnelle populaire chez les programmeurs .NET

generics, queries, lambdas, type inference, expression-tree meta-programming dans C#

FP for "data rich" problems (e.g. statistical machine learning or symbolic programming) or

"control rich" problems (e.g. parallel and asynchronous programming)

Ocaml: Jane Street Capital [société d’arbitrage à New-York et Londres]

F# a gagné le concours adPredict

``There is essentially near-universal agreement in industry and academia that elements of functional programming (immutability, queries, task parallelism, controlling side-effects,

data parallelism, functional reactive programming) are essential in applied parallel and concurrent programming both in the short, medium and long terms. This plays out in different ways in different languages and tool chains ‘’ [don syme - MSRC]

Erlang: Ericsson, programmes dans les téléphones

(75)

Quelques succès

coq, twelf, hol, isabelle, hol-light, bonne partie de nuprl sont écrits en ML. (outils puissants de vérification avec déjà de belles applications)

une bonne partie des compilateurs modernes

sql a un noyau fonctionnel

tous les applications de Galois Connections sont écrites en Haskell (analyse de prog.)

Bluespec (Arvind) est un langage fonctionnel pour le hardware.

unison (le meilleur synchroniseur de fichiers) est écrit en Ocaml

beaucoup des problèmes de la programmation objet ont des solutions proches de celles pour les langages fonctionnels

Frama-C (CEA, flottant), Astrée, l’analyseur statique pour C (airbus A380)

IABC, le vieil analyseur d’alias d’Alain Deutsch (Ariane 502)

et ... tous les autres oubliés par ma faute

mardi 8 décembre 2009

(76)

Conclusion

(77)

Conclusion et Futur

en route vers le logiciel certifié

[beaucoup plus dur que le hardware certifié]

des progrès en cours sur les types [système F, ou plus haut dans la hiérarchie des types]

refinement types avec formules logiques (et puissants SMTs)

langages pour programmer les Data Centers

etc...

La longue route du lambda-calcul aux langages modernes !!

a démontré l’intérêt du typage fort et expressif

mardi 8 décembre 2009

(78)

Slogans de fin

Les langages de programmation issus du lambda- calcul sont propres et expressifs

Le lambda-calcul est propre et expressif

(79)

Références

Alonzo Church, The calculi of Lambda-Conversion, AMS studies 6, Princeton University Press, 1941.

Gordon D. Plotkin. LCF considered as a programming language. Theoretical Computer Science, 5:223-255, 1977.

Peter J. Landin. The next 700 programming languages. Communications of the ACM, 9(3):157-166, March 1966.

Robin Milner. A theory of type polymorphism in programming. Journal of Computer and System Sciences, 17:348-375, August 1978.

Gordon Plotkin. Call-by-name, call-by-value, and the λ-calculus. Theoretical Computer Science, 1:125-159, 1975.

mardi 8 décembre 2009

(80)

Références

Documents relatifs

En C++, les chaînes de caractères sont stockées dans des variables de type string : string prenom = "Robert"; // string pour les chaînes de caractères.. Les chaînes

Pour accéder à un élément, dans une itération donnée, on le fait via le registre SI...

Il consiste simplement à interpréter les ensembles ordonnés ci-dessus (et applications croissantes) en termes de catégories (et foncteurs):.. C'est un modèle, dans la catégorie

(et ses flèches) sont définissables dans le seul langage de £ par des sytèmes de flèches de £ devant vérifier un système d'é- quations et soumises à des conditions d'existence

Exercice 4: Écrire une fonction qui supprime la première occurrence d’un caractère motif dans une chaîne de caractères source,2. void supp (char motif,

Complétez ce code de sorte à ce qu’il vous permette de découvrir où est stocké le paramètre t de la fonction fct, par rapport à la position en mémoire où le tableau tmp

Dans un langage de programmation sans orientée objet (Pascal, C, … ), il est interdit d'utiliser le même nom pour deux sous-programmes différents. Les langages C#, C++, JAVA,

– considérée comme un tableau de caractères qui peut être manipulé d'une manière globale (sans le faire caractère par caractère)... Chaînes constantes