Programmation fonctionnelle Programmation fonctionnelle et création d'un langage orienté objet Sébastien Boisvert Http://boisvert.info LinuQ pavillon Palasis-Prince (Université Laval) local 3313 Jeudi le 20 octobre 2011 30 minutes entre 19h00 et 21h30 1 Plan ● ● Partie 1: programmation fonctionnelle en Scheme Partie 2: langage objet et jeu en Scheme 2 Partie 1: programmation fonctionnelle en Scheme 3 Couleurs ● Bleu: code ● Rouge: nom de fichier 4 Scheme ● Dialecte minimaliste de Lisp ● Lisp: Lots of Irritating Superfluous Parentheses :-) voir http://www.acronymfinder.com/LISP.html 5 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 6 Fonctions ● Tout est une fonction ● 2+3 devient (+ 2 3) ● Print(“Joe”) devient (print “joe”) ● addition.scm 7 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 8 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 9 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")) 10 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 11 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 12 Applications de la paire ● Listes ● Arbres ● Objets ● Classes ● S expressions ● Code lisp/scheme ● Données (équivalent à XML) ● Tout 13 Fonctions list et apply ● (list 1 2 3 4 5) ● (apply + (list 1 2 3)) ● Voir liste.scm 14 Une liste est un paquet de paires (define liste1 (list 1 2 3 4)) (car liste1) (cdr liste1) ● Voir append.scm 15 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 16 map ● (map carré (list 1 2 3 4)) ● Retourne (list 1 4 9 16) ● Voir map.scm 17 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 18 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 19 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 20 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 21 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 22 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";'); ?> 23 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 24 Programmation fonctionnelle impure ● Objets mutables ● Fonction set! ● Le symbol ! indique un effet de bord (define a 1) (set! a (+ a 9)) ● Voir set.scm 25 Partie 2: langage objet et jeu en Scheme 26 Crisis 2 © 2011 Electronic Arts Inc. Trademarks belong to their respective owners. All rights reserved. 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 27 Démonstration du jeu ● ● Jeu en Scheme (PLT Scheme version 360) Disponible sur http://github.com/sebhtml/scheme-asteroid ● Orienté objet ● (3 minutes) 28 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)) 29 Exemples ● AvionJoueur.scm ● Syntaxe claire et simple 30 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)) 31 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 32 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 33 Expansion itérative ● Les macros provoquent une expansion du code ● Exemple avec DrScheme et Roche-demo.scm 34 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 35 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 36 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 37 Questions (a+b)/a = a/b 38