partie A introduction au langage fonctionnel choisi

publicité
IFT359 – Programmation fonctionnelle
Thème #2
Introduction au langage fonctionnel choisi
1
QUELQUES CONCEPTS DE BASE SUR LES
LANGAGES DE PROGRAMMATION ET SUR
DR-RACKET
2
DrRacket
un langage dérivé du λ-calcul
• Scheme est un dialecte de Lisp
• Lisp a été conçu en 1958
• Scheme a été conçu en 1975
• DrRacket a été conçu en 2009
• DrRacket est un dialecte de Scheme
– Les différences sont pour le cours minimes
• Lisp est basé sur le λ-calcul
• La syntaxe et la sémantique de DrRacket a beaucoup de similarité
avec le λ-calcul
– abstractions, applications, portée lexicale, typage statique, lambda …
– DrRacket ajoute au λ-calcul quelques formes syntaxiques (spéciales),
plusieurs librairies et l’évaluation par environnement.
• Apprendre à utiliser la syntaxe de DrRacket se fait en quelques
heures, c’est la programmation fonctionnelle qui s’acquiert plus
lentement parce que c’est une nouvelle façon de penser.
3
DrRacket
un langage dérivé du λ-calcul
• Langage multi-paradigme mettant l’emphase sur la programmation
fonctionnelle
• L’évaluation se fait par environnement
– Il permet de définir l’affectation
– Il facilite le traitement des définitions de fonctions mutuellement
récursives.
– Pour le moment on peut considérer que l’évaluation par environnement
est identique à l’évaluation par substitution.
• L’ordre d’évaluation est applicatif
– Il est plus performant
– En λ-calcul, l’ordre applicatif ne mène pas toujours à la forme normale.
– Les construits comme le if et define qui peuvent être problématiques
ont une forme spéciale qui ne suivent pas l’ordre applicatif.
4
DrRacket
un langage dérivé du λ-calcul
• Homoiconicité (code = donnée)
• Portée lexicale (statique) des variables
• Typage « dynamique » fort
– L’interpréteur ou le compilateur infère les types
• Offre une Read-Eval-Print-Loop {REPL}
• Ramasse-miette {Garbage Collector}
5
Les types d’expression DrRacket
• Fonction (Abstraction)
– (λ (params …) corps1 corps …)
• Application de fonction
– (fn-expression args …)
• Constante (appelés aussi primitives ou valeurs)
• les types primitifs atomiques (booléens, nombres, symboles, caractères…)
• les types composés (listes, vecteurs, chaînes de caractères…)
• fonctions (appelées aussi opérateurs).
– Le but de l’évaluation est la réduction des expressions pour obtenir une
constante (on fait abstraction des évaluations pour les effets de bord)
• Forme spéciale (appelée aussi forme syntaxique)
– ce sont des applications ayant leur propre schéma d’évaluation
– plusieurs sont prédéfinies
• (if …), (cond …), (define …), (let …) …
– elles permettent de simplifier de beaucoup l’écriture des programmes
6
Typage statique versus dynamique
Le type d’un identificateur
• statique
– le type des identificateurs est explicite ou peut être déduit à partir du
texte du programme
• déverminage plus facile
• le compilateur peut générer un code plus efficace
• une fonction comme eval est impossible
• dynamique
– les identificateurs n’ont pas de type
• un même identificateur peut être successivement lié à des valeurs de types
différents lors de l’exécution d’un programme
– les objets (valeurs) ont toujours un type bien définis
• l’interpréteur ou le compilateur étiquette automatiquement les objets
• identification des opérations menant à une erreur d’exécution avant son
exécution.
7
– code plus facilement réutilisable
– méta programmation plus simple et expressive
Typage fort versus faible
détection des erreurs de type
Que le typage soit dynamique ou statique, ça ne dit pas ce qu’il faut faire
lorsque les types des arguments ne sont pas ceux attendus.
• fort
– Toutes les opérations exigent que leurs arguments soient du bon type
• un message d’erreur est envoyé si ce n’est pas le cas
• typage statique : le message est envoyé au moment de la compilation
• typage dynamique : le message est envoyé par l’interpréteur
• faible
– une opération exigeant un argument d’un certain type tentera de le
traiter comme s’il était du bon type
– cette transformation automatique d’une donnée d’un type dans un autre
type (casting) est souvent utile
var x := 5;
var y := "37";
x + y; ?
8
(x is an integer)
(y is a string)
 42 ou 537 ou run-time error
RACKET ET LAMBDA-CALCUL
11
Abstraction
• Abstraction est aussi appelée fonction ou procédure
• λ-calcul
– λ(xyz)baxy ≡ (λ(x(λ(y)(λ(z)(((ba)x)y))))
• Racket
– (λ (x y z) (b a x y))
• les constantes a et b doivent être définies dans l’environnement où cette
fonction est définie
• dans le texte du programme les valeurs de a et b
– doivent être trouver avant l’application de la fonction
» doivent faire partie du bloc lexical où apparait la fonction ou d’un bloc lexical
parent
– peuvent être après ou avant la définition de la fonction
12
Abstraction
• Racket
– Le corps de la fonction peut avoir plus d’une expression mais seule la
dernière est importante pour la sémantique de la fonction.
– Toutes les autres expressions (i.e. sauf la dernière) ne sont là que pour
les effets de bords,
• Dans un langage fonctionnel permettant l’affectation, les effets peuvent être
aussi désastreux que dans un langage impératif ou structuré.
– (λ (x y z) (+ y z) (print x) (x y z)))
• (+ y z) et (print x) n’a aucun impact sur l’exécution de la fonction
13
Application
• λ-calcul
– (U V W)
• Si U se réduit à une abstraction alors (U V W) se simplifie avec la βréduction
– ((λ (x y) + x y) 3 4)  (+ 3 4)
• DrRacket
– (U V W)
• idem au λ-calcul
• U doit s’évaluer comme une abstraction (fonction anonyme) ou une
procédure système ou définie par l’usager
• ex : ((λ (x y) (+ x y)) 3 4)  7
– (((λ (z) (λ (x y) (z x y))) +) 3 4)
la première expression est ((λ (z) (λ (x y) (z x y))) +) et elle n’est pas une
abstraction ou une procédure mais une application qui se réduit à une abstraction.
14
Définition
• λ-calcul
– le terme ≡
• ne fait pas partie du λ-calcul
• facilite beaucoup l’écriture des programmes
– S ≡ λ(wyx)y(wyx) ;; 3 ≡ λ(sz)s(s(s(z)))
– 4 ≡ S 3
• DrRacket
– define
• permet de créer des liaisons
• (define identificateur expression)
– (define a 1)
– (define b (λ (x) (+ x 4)))
– (b a)  5
• n’est pas une fonction mais une forme syntaxique
– identificateur n’est jamais évalué
• il est possible d’ombrager une liaison existante mais non de la redéfinir
15
– DrRacket ajoute quelques formes syntaxiques et plusieurs définitions
Identificateur
• Toutes les chaines de caractères en excluant ceux
– représentant un nombre
• +1, 5.1, 4, 4+i, +nan.0, 2/3, .123 …
– contenant un des caractères suivants : ( ) [ ] { } " , ' ` ; # | \
• Exemple
–
–
–
–
–
16
1.1.1
λ
+abc
1+
nan
Exécution d’un programme
Évaluation par environnement
• Un environnement est l’ensemble des liaisons accessibles pour
évaluer une expression
– Un environnement est un ensemble contenant des paires (identificateur
valeur) et pointant possiblement sur un autre environnement appelé
environnement parent.
• Deux identificateurs différents peuvent pointer sur la même valeur
– Il existe un autre dictionnaire reliant les valeurs et les objets
• Deux valeurs différentes peuvent pointer sur le même objet
• L’imbrication des environnements est parallèle à l’imbrication
lexicale
• L’environnement racine contient
– les identificateurs prédéfinis
– les identificateurs définis au premier niveau (top level)
20
Évaluation par environnement
d’une fonction
• La définition d’une fonction est une paire
– La première partie est un pointeur vers l’environnement dans lequel est
évaluée la fonction (ne pas confondre avec celui de l’application d’une
fonction)
– La seconde partie contient
• a) les paramètres formels
• b) le corps de la fonction
• L’environnement dans lequel une fonction est définie est donc
conservé avec la fonction pour la durée de la fonction.
– i.e tant que la fonction est utilisée ou référencée par un identificateur
21
Exemple d’évaluation d’une fonction
Évaluation de (λ (a b) (+ a b))
dans l’environnement initial
Environnement Initial
Var : a b
Corps : (+ a b)
22
Exemple d’évaluation d’une fonction
Évaluation de (λ (a b) (+ a b))
dans l’environnement initial
Pour simplifier, je vais souvent dessiner
l’évaluation de la fonction en dehors de
l’environnement
Environnement Initial
Var : a b
Corps : (+ a b)
23
Évaluation par environnement
d’une application
1. ((λ (v1 v2 … vn) ff ...) exp1 exp2 ... expn)
2. (λ (v1 v2 … vn) ff ...), exp1 exp2 ... expn sont évalués tel que décrit
précédemment
3. Un environnement A est créé et pointe vers l’environnement dans
lequel est défini la fonction
– voir la première partie de la définition d’une fonction
4. Les identificateurs v1 v2 … vn sont introduits dans l’environnement
A et sont associés aux valeurs val1 val2 ... valn
5. Les expressions ff ... sont évaluées dans l’environnement A
24
Exemple d’évaluation d’une application
Évaluation de ((λ (a b) (+ a b)) 1 2)
dans l’environnement initial
Environnement Initial
A
Var : a b
Corps : (+ a b)
25
a:1
b:2
(+ a b) sera évalué dans
l’environnement A
Évaluation par environnement
d’un define
Évaluation de (define f (λ (a b) (+ a b))
dans l’environnement initial
Environnement Initial
f
Var : a b
Corps : (+ a b)
26
S’il y a plusieurs define dans un programme alors tous les identificateurs sont
ajoutés à l’environnement courrant
Evaluation de plusieurs define
1. Tous les identificateurs sont ajoutés à l’environnement courant mais
ne sont associés à aucune valeur
2. Pour chaque identificateur, on calcule sa valeur
et on l’associe à l’identificateur
et ce dans l’ordre dans lequel les identificateurs apparaissent
27
•
La valeur d’un identificateur dépend de la valeur des identificateurs
précédents
•
Voir les exemples faits avec DrRacket en classe
Evaluation par environnement
Exercice
• Évaluer par environnement les expressions suivantes
(define f (λ (a b) (+ a b c)))
(define c 7)
(define g (λ (c) (f 1 2)))
(g 3)
– Comparer avec l’évaluation par substitution
28
Initiation au logiciel DrRacket
URL du Logiciel
http://racket-lang.org/
29
Choix du langage et de la syntaxe de sortie
Ctrl-l + montrer les détails
30
La page de référence sur les types de données
LES TYPES PRÉDÉFINIES
31
JE PRÉSENTE PREMIÈREMENT LES TYPES
ET ENSUITE LES PROCÉDURES ET LES
FORMES SPÉCIALES POUR LES
MANIPULER
32
Booléen
• Deux valeurs
•
– #t (true, #T) et #f (false, #F)
Toutes les constantes sont considérées vraies mais ce ne sont pas des
booléens
•
•
33
(boolean? 3)  #f
(if 3 4 5)  4
Nombre
• Tous les nombres sont des complexes
• 3+2i, 1/3+2.1i …
– certains complexes sont des réels
• partie imaginaire absente ou égale à 0
• pi, 3.1234, +inf.0, +inf.f, -inf.0, +nan.0 …
– certains réels sont des rationnels
• tous les réels qui peuvent se représenter comme des float
• 1/3, 4.123, (mais pas +inf.0, +inf.f, -inf.0, +nan.0 …) …
– certains rationnels sont des entiers
• tous les rationnels qui peuvent se représenter de la même façon un fois
arrondi à l’entier le plus près
• 4.0 4 -0.0
– la taille des entiers n’a pas de limite sauf celle de la mémoire
– de même pour les entiers utilisés pour représenter une fraction
• Il y a plusieurs prédicats pour caractériser les nombres
– voir diapositives 47
34
Caractère
• Ce sont des caractères unicode
• la chaine « #\ » annonce un caractère
– #\A et #\u0041 réfèrent au caractère A
– #\λ et #\u03BB réfèrent au caractère λ
– dans #\uXXXX, le XXXX est la valeur unicode du caractère en
hexadécimal (voir http://www.unicodemap.org/)
– certains caractères ont une forme spéciale
• #\space  espace
• #\newline  retour de chariot
• voir la liste à la section 12.6.13 du fichier
35
Symbole
• Un symbole est une valeur atomique qui n’a pas d’équivalent dans
la majorité des langages.
– Très utilisé dans le traitement symbolique, par exemple faire un
programme en mesure de faire de l’intégration symbolique.
– Un symbole s’affiche comme un identificateur précédé d’un ‘.
– Les symboles ont une représentation unique.
• deux symboles qui ont le même nom sont identiques
– ils sont le même objet et occupent le même espace dans la mémoire
• 2 chaînes de caractères identiques peuvent être deux objets distincts et
référer à des espaces différents dans la mémoire
– Les symboles apparaissent comme des identificateurs mais ils n’en sont
pas
– La forme syntaxique quote (') permet de créer un symbole
36
•
•
•
•
(quote a)  a
' a a
(quote left)  left
'λ -> λ
Vecteur
• DrRacket traites les vecteurs de façon similaire aux principaux
langages de programmation
• se code comme une liste précédé par #
• #(1 2 3)
• s’affiche comme une liste précédé par ‘#
• ‘#(1 2 3)
37
Chaîne de caractères
• DrRacket traites les chaînes de caractère de façon similaire aux
principaux langages de programmation
– similaire à un vecteur de caractère
• mais c’est un type à part entière
• il se code et s’affiche de façon distincte
• "ag\nfkldjlf"
38
Paire
• Identique à la notion de paire en mathématiques
• Réunit dans une structure deux objets quelconques
• Une paire réunissant obj1 et obj2 se code et s’affiche comme
‘(obj1 . obj2)
39
Liste
• Une chaîne de paires de la forme
'(o1 . (o2 . --- . (on . ())---))
que l’on écrit généralement sous la forme
'(o1 o2 --- on)
• Exemple
'(1 . (2 . (3 . (4 . ()))))
qui s’affiche comme
‘(1 2 3 4)
• La chaîne de paires peut être vide et nous obtenons la liste de vide
que l’on note ‘() ou null
• Attention
– la liste vide n’est pas une paire
– une liste propre se termine toujours par la liste vide
– mais on peut faire des listes impropres
40
Autres types prédéfinis
•
•
•
•
•
•
•
•
•
•
•
41
Byte Strings
Regular Expressions
Keywords
Mutable Pairs and Lists
Boxes
Hash Tables
Sequences and Streams
Dictionaries
Sets
Procedures (déjà vus, ce sont les (λ …))
Void and Undefined
QUELQUES PROCÉDURES DÉFINIES SUR
LES TYPES PRIMITIFS
42
Booléens
• (boolean? v) → boolean? v : any/c
• (not v) → boolean? v : any/c
• (immutable? v) → boolean?
– V est immutable? s’il est un objet de type string ou vector immutable
– Attention les listes et les paires sont normalement immutables
– J’utilise peu ce prédicat
43
Booléens
• (equal? v1 v2) → boolean?
v1 : any/c
v2 : any/c
– v1 et v2 sont equal? s’ils sont eqv? sauf s’ils sont des éléments
composés, ces derniers ont un traitement spécial
• (eqv? v1 v2) → boolean?
v1 : any/c
v2 : any/c
– v1 et v2 sont eqv? s’ils sont eq? sauf
pour les caractères et les nombres
ces derniers ont un traitement spécial
• (eq? v1 v2) → boolean?
Il existe aussi plusieurs prédicats
spécialisés (char=?, char<? …),
les nombres (=, < …), les string
(string=?, string<? …)…
v1 : any/c
v2 : any/c
– v1 et v2 sont eq? s’ils réfèrent au même objet
44
Les nombres
Procédures
prédicats
=, <, <=, >, >=
number?
complex?
real?
rational?
integer?
zero?
positive?
negative?
even?
odd?
exact?
inexact?
equal? ≠ =
45
+, -, *, /
abs
max
min
gcd
lcm
sqrt
expt
exp
log
sin
cos
tan
asin
acos
atan
Il y en plusieurs autres voir ce fichier
quotient
remainder
modulo
inexact->exact
exact->inexact
make-rectangular
make-polar
real-part
imag-part
magnitude
angle
round
floor
ceiling
truncate
numerator
denominator
rationalize
Caractères
Prédicats
char?
char=?
char<?
char<=?
char>?
char>=?
char-ci=?
char-ci<?
char-ci<=?
char-ci>?
char-ci>=?
46
voir ce fichier
Procédures
char-alphabetic?
char-lower-case?
char-upper-case?
char-title-case?
char-numeric?
char-symbolic?
char-punctuation?
char-graphic?
char-whitespace?
char-blank?
char-iso-control?
char->integer
integer->char
char-utf-8-length
char-general-category
make-known-char-range-list
char-upcase
char-downcase
char-titlecase
char-foldcase
Symbole
symbol?
symbol->string
string->symbol
Vous utiliserez beaucoup les symboles dans ce cours mais la majorité
du temps avec des procédures plus générales ou en lien avec d’autres
stuctures de données :
(eq? s1 s2)
(member s1 listedesymboles)
(cons s1 listedesymbole)
(car listedesymbole)
….
47
voir ce fichier
Vecteur
vector?
make-vector
vector
vector-length
vector-ref
vector->list
list->vector
vector->values
build-vector
vector-map
vector-append
vector-take
vector-take-right
vector-drop
vector-drop-right
vector-split-at
vector-split-at-right
vector-copy
vector-filter
vector-filter-not
vector-count
vector-argmin
vector-argmax
vector-member
vector-memv
vector-memq
vector->immutable-vector
Attention plusieurs des procédures mentionnées
manipulent ou créent des vecteurs mutables
Les vecteurs retournés par le reader sont immutables
48
voir ce fichier
Chaîne de caractères
Procédures
make-string
string
string-length
string-ref
substring
string-copy
string-append
string->list
list->string
string->immutable-string
string-set!
Prédicats
build-string
string-upcase
string-downcase
string-titlecase
string-foldcase
string-locale-upcase
string-locale-downcase
string-append*
string-join
string-copy!
string-fill!
string?
string=?
string<?
string<=?
string>?
string>=?
string-ci=?
string-ci<?
string-ci<=?
string-ci>?
string-ci>=?
Attention la majorité des procédures mentionnées manipulent
ou créent des chaînes de caractères mutables
Les chaînes de caractères retournées par le reader sont immutables
49
voir ce fichier
Paires
• (cons a b) crée une paire
(define x (cons 'a 'b))
(a . b)
(define y (cons 'a (cons 'b '())))
(a . (b . ()) = (a b)
(define z (cons 1 y))
(1 . (a . (b . ()))) = (1 a b)
50
Paires
• (car x) retourne la valeur dans la première cellule d’une paire
(car (1 . 2))  1
(define z (cons 1 (cons ‘a (cons ‘b ()))))  (1 a b)
(car z)  1
• (cdr x) retourne la valeur dans la deuxième cellule d’une paire
(cdr (1 . 2))  2
(cdr z)  (a b)
• (pair? x) ou (cons? x)
51
Listes
null?
empty?
cons
car
cdr
null
list?
list
list*
build-list
length
list-ref
list-tail
append
reverse
map
andmap
52
ormap
for-each
foldl
foldr
filter
remove
remq
remv
remove*
remq*
remv*
sort
member
memv
memq
memf
findf
voir ce fichier
assoc
assv
assq
assf
caar
cadr
cdar
cddr
c...ar
c...dr
first
rest
second
third
fourth
fifth
sixth
seventh
eighth
ninth
tenth
last
last-pair
make-list
take
drop
split-at
take-right
drop-right
split-at-right
add-between
append*
flatten
filter-map
remove-duplicates
count
partition
append-map
filter-not
shuffle
argmin
argmax
make-reader-graph
placeholder?
make-placeholder
placeholder-set!
placeholder-get
hash-placeholder?
make-hash-placeholder
make-hasheq-placeholder
make-hasheqv-placeholder
Ceux en rouge sont à connaître
Listes
• Vous travaillerez beaucoup avec les listes
53
Téléchargement