La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

IFT359 – Programmation fonctionnelle Thème #10 Évaluation par environnement et évaluateur méta-circulaire 1.

Présentations similaires


Présentation au sujet: "IFT359 – Programmation fonctionnelle Thème #10 Évaluation par environnement et évaluateur méta-circulaire 1."— Transcription de la présentation:

1 IFT359 – Programmation fonctionnelle Thème #10 Évaluation par environnement et évaluateur méta-circulaire 1

2 Évaluateur méta-circulaire Implémenter un DrRacket minimaliste à partir des primitives de DrRacket ! Ceci revient à implémenter la gestion des environnements –i.e. les applications de primitives se font directement à l’aide de apply On utilise les hash-tables (pour les mêmes raisons qu’au thème 6) –On pourrait utiliser set-mcar!, set-mcdr!

3 Les procédures repl et repl-print 3 (define repl-print (λ (x) (if (compound-procedure? x) (display (list 'procedure … )) (display x)))) (define repl (λ () (let ([input (read)]) (cond [(eq? input 'exit)(exit)] [(eq? input 'stop) …] [else (let ([output (eval input global-env)]) (repl-print output) (newline) (repl))]))))

4 Les procédures eval et read 4 '(λ (x) (+ x 2)) "bonjour " '(begin (+ 3 4)(λ (x) x)) (define eval (λ (exp env) (cond [(self-evaluating? exp) exp] [(variable? exp) (lookup-variable-value exp env)] … [(assignment? exp) (eval-assignment exp env)] [else (printf "expression inconnue :~a!\n" exp)]))) (read)  retourne une s-expression La procédure (eval s-exp) évalue l’expression Les expressions sont évaluées dans un environnement env sauf quoted et self-evaluating.

5 L’environnement global 5 (define global-env (extend-env primitive-procedure-names primitive-procedure-impls empty-env))

6 Les types d’expressions 6 (define eval (λ (exp env) (cond [(self-evaluating? exp) exp] [(variable? exp) (lookup-variable-value exp env)] …) (define self-evaluating? (λ (exp) (or (number? exp) (char? exp) (boolean? exp) (string? exp)))) Il existe toute une série de prédicat pour identifier le type d’expression « Est-ce que c’est un if, un begin … » (define quoted? (λ (exp) (tagged-list? exp 'quote))) La majorité des expressions sont des listes dont le premier élément définit le type de l’expression.

7 Les types d’expression 7 self-evaluating quoted assignment definition if and cond begin λ application Le TP5 vous demande d’ajouter le let et le or

8 Les environnements 8 (define empty-env 'empty-env) (define make-env (λ (env) (cons (make-hash) env))) (define bindings car) ; 1 ier environnement de la liste (define enclosing-env cdr) ; environnement parent (define global-env ; environnement global (extend-env primitive-procedure-names primitive-procedure-impls empty-env)) Les expressions sont évaluées dans un environnement. sauf les expressions de type self-evaluating? i.e. nombre, caractère, booléens et string. Les environnements sont encodées comme une liste de table de hachage.

9 Les environnements 9 (define lookup-variable-value (λ (var env) (cond [(eq? env empty-env) (printf "Variable non-définie '~a' !" var)] [(hash-has-key? (bindings env) var) (hash-ref (bindings env) var)] [else (lookup-variable-value var (enclosing-env env))]))) (define extend-env (λ (vars values env) (let ([new-env (make-env env)]) (for-each (λ (var-value) (define-variable! (car var-value) (cadr var-value) new-env)) (zip vars values)) new-env))) Les environnements sont modifiés par define, set!, let, et les applications.

10 Définition d’une nouvelle liaison avec define 10 (define eval-definition (λ (exp env) (define-variable! (definition-variable exp) (eval (definition-value exp) env) env))) (define define-variable! (λ (var value env) (if (hash-has-key? (bindings env) var) (printf "Variable ~a déja définie!\n" var) (hash-set! (bindings env) var value)))) (define eval (λ (exp env) (cond … [(definition? exp)(eval-definition exp env)] …) (define definition? (λ (exp) (tagged-list? exp 'define)))

11 L’affectation : set! 11 (define eval-assignment (λ (exp env) (set-variable-value! (assignment-variable exp) (eval (assignment-value exp) env) env))) (define set-variable-value! (λ (var value env) (cond [(eq? env empty-env) (printf "Variable non-définie ~a!" var)] [(hash-has-key? (bindings env) var) (hash-set! (bindings env) var value)] [else (set-variable-value! var value (enclosing-env env))]))) (define eval … (cond …[(assignment? exp) (eval-assignment exp env)] …) (define assignment? (λ (exp) (tagged-list? exp 'set!)))

12 L’affectation : begin 12 (define eval-sequence (λ (seq env) (cond [(null? (cdr seq)) (eval (car seq) env)] [else (eval (car seq) env) (eval-sequence (cdr seq) env)]))) (define eval … (cond … [(begin? exp) (eval-sequence (begin-actions exp) env)]…) (define begin? (λ (exp) (tagged-list? exp 'begin))) (define make-begin (λ (seq) (cons 'begin seq)))

13 Les formes syntaxiques : if et and 13 (define eval-and (λ (exp env) (let iter ([res #t] [reste (cdr exp)]) (if (null? reste) res (let ([val (eval (car reste) exp)]) (if val (iter val (cdr reste)) #f)))))) (define eval-if (λ (exp env) (if (eval (if-test exp) env) (eval (if-then exp) env) (eval (if-else exp) env))))

14 La forme syntaxique cond 14 (define cond->if (λ (exp) (expand-clauses (cond-clauses exp)))) (define expand-clauses (λ (clauses) (if (null? clauses) #f ;; patch il faudrait traiter (void) (let ([first (car clauses)] [rest (cdr clauses)]) (if (cond-else-clause? first) (if (null? rest) (sequence->exp (cond-actions first)) (printf "ELSE clause isn't last")) (make-if (cond-predicate first) (sequence->exp (cond-actions first)) (expand-clauses rest))))))) Exercice : Améliorer le code pour retourner void lorsqu’aucune clause est sélectionnée et pour traiter le cas où une clause ne contient qu’un élément.

15 La forme syntaxique cond 15 (define cond-clauses cdr) (define cond-predicate car) (define cond-actions cdr) (define cond-else-clause? (λ (clause) (eq? (cond-predicate clause) 'else))) (define make-if (λ (test then else) (list 'if test then else))) (define (sequence->exp seq) (cond [(null? seq) seq] [(null? (cdr seq)) (car seq)] [else (make-begin seq)])) (define make-begin (λ (seq) (cons 'begin seq)))

16 λ 16 (define λ? (λ (exp) (tagged-list? exp 'λ))) (define make-procedure (λ (parameters body env) (list 'procedure parameters body env))) (define eval (λ (exp env) (cond … [(λ? exp) (make-procedure (lambda-parameters exp) (lambda-body exp) env)] … )

17 Applications 17 (define application? (λ (exp) (and (list? exp) (not (null? exp))))) (define list-of-values (λ (exps env) (map (λ (e) (eval e env)) exps))) (define eval (λ (exp env) (cond … [(application? exp) (apply* (eval (operator exp) env) (list-of-values (operands exp) env))] … )

18 Applications 18 (define apply* (λ (procedure arguments) (cond [(primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)] [(compound-procedure? procedure) (eval-sequence (procedure-body procedure) (extend-env (procedure-parameters procedure) arguments (procedure-env procedure)))] [else (printf "apply ne connait pas ~a!\n" procedure)])))

19 Primitives 19 (define apply* (λ (procedure arguments) (cond [(primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)] …) (define apply-primitive-procedure (λ (pp args) (apply (primitive-implementation pp) args))) (define primitive-procedures (list (list '+ +) (list '- -) …)) (define primitive-procedure-names (map car primitive-procedures)) (define primitive-procedure-impls (map (λ (pp) (list 'primitive (cadr pp))) primitive-procedures))

20 eval du DrRacket eval prend un paramètre optionnel qui par défaut a la valeur de current-name-space et ce dernier est initialement vide dans un module Pour bien comprendre l’évaluation par environnement, on va définir notre propre fonction eval c’est ce qu’on appelle un évaluateur métacirculaire eval dans un module #lang racket (define ns (make-base-namespace)) (eval (+ 1 2) ns) eval évalue une s-expression, i.e. un atome ou une liste de symboles fait les phases suivant celle de la lecture, i.e. extension et évaluation. le quote ne fait que la phase de lecture ( eval '(+ 3 4)) -> 7 doit être fait dans la fenêtre d’interaction (REPL) eval est à éviter


Télécharger ppt "IFT359 – Programmation fonctionnelle Thème #10 Évaluation par environnement et évaluateur méta-circulaire 1."

Présentations similaires


Annonces Google