1
Programmation fonctionnelleProgrammation fonctionnelle et création d'un
langage orienté objet
Sébastien BoisvertHttp://boisvert.info
LinuQ
pavillon Palasis-Prince (Université Laval)local 3313
Jeudi le 20 octobre 201130 minutes
entre 19h00 et 21h30
2
Plan
● Partie 1: programmation fonctionnelle en Scheme
● Partie 2: langage objet et jeu en Scheme
3
Partie 1: programmation fonctionnelle en Scheme
4
Couleurs
● Bleu: code● Rouge: nom de fichier
5
Scheme
● Dialecte minimaliste de Lisp● Lisp:
Lots of Irritating Superfluous Parentheses :-)
voir http://www.acronymfinder.com/LISP.html
6
Expressions symboliques
● En C:
fonction(argument1, argument2);
● Avec une S expression:
(fonction argument1 argument2)
● S expression: un opérateur et une liste d'arguments● Un argument peut être une S expression
7
Fonctions
● Tout est une fonction● 2+3 devient (+ 2 3)● Print(“Joe”) devient (print “joe”)
● addition.scm
8
Tout est une fonction
● La fonction lambda défini une fonction anonyme.
(define foo (lambda (x y) (+ x y)))
(foo 1 2)
((lambda (x y) (+ x y)) 1 2)
● Voir anonyme.scm
9
Donner des noms aux fonctions
● Pour définir une variable:
(define a 1)
● Pour définir une fonction
(define b (lambda (x y) (+ x y)))
● Voir fonction.scm
10
Le conditionnel
● La fonction/opérateur if● 3 arguments
(if expressionDeCondition
expressionSiVrai expressionSiFaux)
(if (> 3 1)
(print "3 est plus grand que 1")
(print "3 n'est pas plus grand que 1"))
11
Récursion
● Exemple: factoriel ● 6! = 6*5*4*3*2*1
(define factoriel (lambda (n) (if (= n 1)
1 (* n (factoriel (- n 1))))))
(factoriel 5)
(factoriel 99)
● Voir factoriel.scm
12
La paire
● Une paire contient deux éléments● Créer une paire: (define a (cons 1 2))● Pour obtenir le premier élément: (car a)● Le deuxième: (cdr a)
● Exemple: paires.scm
13
Applications de la paire
● Listes● Arbres● Objets● Classes● S expressions● Code lisp/scheme● Données (équivalent à XML)● Tout
14
Fonctions list et apply
● (list 1 2 3 4 5)
● (apply + (list 1 2 3))
● Voir liste.scm
15
Une liste est un paquet de paires
(define liste1 (list 1 2 3 4))
(car liste1)
(cdr liste1)
● Voir append.scm
16
Fonctions d'ordre supérieur
● Une fonction qui retourne une fonction ou qui prend une fonction en argument
● (define supérieur
(lambda (fonction argument1 argument2)
(fonction argument1 argument2)))
● (supérieur + 1 2)
● Voir supérieur.scm
17
map
● (map carré (list 1 2 3 4))
● Retourne (list 1 4 9 16)
● Voir map.scm
18
Fermetures (closures)
● Capturer une variable dans un environnement lexical
(define prédicat-est-égal (lambda (nombre)
(lambda (x) (= nombre x))))
(define alpha 3)
(define égal-à-alpha (prédicat-est-égal alpha))
(égal-à-alpha 3)
(égal-à-alpha 99)
● Voir fermeture.scm
19
Les paires sont des fonctions aussi !
● cons est une fonction● car est une fonction● cdr est une fonction
● En fait, ce sont des fonctions d'ordre supérieur car ils retournent ou prennent en entrée une fonction
20
Définissons nous-même une paire
● Nous allons implémenter cons, car et cdr● cons prend deux arguments et retourne une
fonction● car prend une fonction en argument● cdr prend une fonction en argument
21
Implémentation 1
● cons prend argument1 et argument2● cons retourne une fonction● Cette fonction retournée prend 1 argument● Si c'est 'car, elle retourne argument1● Si c'est 'cdr, elle retourne argument2● car appelle son argument avec l'argument 'car● cdr appelle son argument avec l'argument 'cdr
● Voir implementer-paires.scm
22
Implémentation 2 (plus compliqué)
● cons prend les arguments x et y et retourne une fonction qui prend 1 argument m
● Si on appelle cette fonction retournée, elle appelle l'argument m avec les arguments x et y
● car prend un argument z et appelle la fonction z avec un argument qui est une fonction qui prend deux arguments p et q et qui retourne p (le premier)
● cdr prend un argument z et appelle la fonction z avec un argument qui est une fonction qui prend deux arguments p et q et qui retourne q (le deuxième)
● Voir implementer-paires-cool.scm
23
Fonction eval
● Dans tous les langages interprétés (ruby, python, perl, lua, lisp, scheme, php, javascript)
● Évalue du code
(define expression (list + 1 2 3))
(eval expression)
● Peut s'implémenter avec la fonction apply
(apply (car expression) (cdr expression))
● Voir eval.scm<?php$foo = "Hello, world!\n";eval('echo "$foo";');?>
24
Programmation fonctionnelle pure
● Sans effet de bord
● On peut créer des variables, mais on ne peut pas les modifier
● On peut seulement définir une autre variable avec le même nom qui va écraser l'ancienne
(define a 1)
(define a (+ a 1))
● Le deuxième a cache le premier a
● Voir pure.scm
25
Programmation fonctionnelle impure
● Objets mutables● Fonction set!● Le symbol ! indique un effet de bord
(define a 1)
(set! a (+ a 9))
● Voir set.scm
26
Partie 2: langage objet et jeu en Scheme
Crisis 2 © 2011 Electronic Arts Inc. Trademarks belong to their respective owners. All rights reserved.
27
Faire de l'orienté objet en Scheme
● Trucs désirés:
● Héritage multiple● Attributs privés et publiques● Méthodes privées et publiques● Notation object.méthode(argument1)● Classes faciles à définir● Opérateur new pour instancier un objet
28
Démonstration du jeu
● Jeu en Scheme (PLT Scheme version 360)● Disponible sur
http://github.com/sebhtml/scheme-asteroid
● Orienté objet
● (3 minutes)
29
Classe AvionJoueur
● En Java:
monAvion.dessiner(canevas);● En Scheme:
(ask monAvion 'dessiner canevas)● Appelle la méthode dessiner de l'objet monAvion avec
l'argument canevas
● Équivalent à
(define méthode (get-method objet 'dessiner))
(apply méthode (list objet canevas))
30
Exemples
● AvionJoueur.scm● Syntaxe claire et simple
31
Les macros
● En C++ et en C, les macros ne sont pas dans le langage.
● C'est le pré-processeur qui s'en occupe
#include <stdlib.h>
#define KILL_PROCESS(process) \
posix_kill(get_process_id(process))
32
Macros en Scheme
● Pas du tout la même chose qu'en C
● Dans le langage
● Fonctions define-syntax et syntax-rules
● Très puissantes, avec expansion itérative
(define-syntax mon-operation
(syntax-rules ()
((mon-operation argument1 ...) (+ argument1 ...))))
(mon-operation 1 2 3 4)
● Voir macro.scm
33
Définition du langage objet
● langage-objet.scm
contient créer-classe et autres
● macro.scm
contient les macro qui “transforme” les fichiers de classes, voir define-syntax classe
34
Expansion itérative
● Les macros provoquent une expansion du code● Exemple avec DrScheme et Roche-demo.scm
35
Fonctions putprop et getprop
● Engin de clés/valeurs dans Scheme● Utilisé pour définir les symboles des classes
(attributs, méthodes et graphe d'héritage)
(require (lib "compat.ss"))
(putprop 'base 'clé 9)
(getprop 'base 'clé)
● Voir putprop.scm
36
Class Objet
● Tous les objets sont des instances de la classe Objet
● Un slot est un attribut ou une méthode
● Méthode getSlot, setSlot et getSlot-cons ● getSlot-cons: recherche en largeur dans l'arbre
d'héritage pour trouver la méthode ou l'attribut désiré
● Voir Objet.scm
37
Classe Classe
● Toutes les classes sont des instances de la classe Classe
● La classe Classe est une instance de la class Classe (en théorie).
(classe Classe
(
(privé methodes)
(privé attributs))
(
(publique Classe (self) null)
))
● Classe.scm
38
Questions
(a+b)/a = a/b