Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 9: Interpreter nach.

Ähnliche Präsentationen


Präsentation zum Thema: "Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 9: Interpreter nach."—  Präsentation transkript:

1 Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 9: Interpreter nach dem Substitutionsmodell und Streams Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

2 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Rückblick: Das Substitutionsmodell Wir haben die Sprachmechanismen von Scheme bisher informal anhand des Substitutionsmodells verdeutlicht –Zahlen, Symbole etc. sind selbstauswertend –Primitive Operationen: entsprechende Maschinenbefehle ausführen –make-struct, cons : selbstauswertend –(lambda ( … ) …): selbstauswertend –(define …): Erweitere die Umgebung –(local …): Herausziehen der lokalen Definitionen auf oberste Ebene, jeweils neuen Namen vergeben –(operator op-1 … op-n ): Auswertung von operator sowie op-1 … op-n Operator muss (lambda (x-1 … x-n) exp) ergeben Ergebnis ist die Auswertung exp, wobei exp sich aus exp durch Substitution der freien Vorkommen von x-1 … x-n durch die Ergebnisse der Auswertung von op-1 … op-n ergibt –Lexikalisches Scoping 2

3 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Rückblick: Das Substitutionsmodell Der Auswertungsprozess ist selbst ein Rechenprozess, den wir als Prozedur präzisieren und implementieren können –Erinnern sie sich an das Zitat Programming is a Good Medium for Expressing Poorly Understood and Sloppily Formulated Ideas vom Anfang der Vorlesung? 3 Der Interpreter einer Programmiersprache, der die Bedeutung der Ausdrücke in der Programmiersprache festlegt, ist auch nur ein Programm.

4 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Terminologie Die interpretierende Sprache oder Basissprache ist die Sprache, in der der Interpreter implementiert ist Die interpretierte Sprache ist die Sprache, die der Interpreter auswertet Prinzipiell ist es möglich, in jeder Programmiersprache, die ein paar Basiskriterien erfüllt einen Interpreter für jede andere Programmiersprache zu schreiben –Sogenannte Turing-Vollständigkeit Das wird von nahezu jeder universellen Programmiersprache wie Java, C, Scheme, Pascal, Perl, … erfüllt –Eines der fundamentalen Resultate der Informatik Wenn die interpretierte Sprache und die Basissprache identisch sind, spricht man von einem Meta-Interpreter oder metazirkulären Interpreter 4

5 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Interpreter und Programmsemantik Interpreter sind eine Möglichkeit, um die Bedeutung (so genannte Semantik) einer Programmiersprache zu definieren Ein solcher Interpreter kann daher keine Fehler enthalten, weil er die Bedeutung definiert –Ein Fehler kann immer nur in Bezug auf eine Spezifikation festgestellt werden –Zum Beispiel können wir dem Symbol + in einem Interpreter als Bedeutung eine Multiplikationsprozedur zuweisen Das ist kein Fehler, sondern eine mögliche Definition! –Einige Programmiersprachen werden tatsächlich offiziell durch Interpreter definiert (z.B. Scheme, SML) 5

6 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Interpreter und Programmsemantik Allerdings kann die Bedeutung auch anders festgelegt werden –Informelle Sprachdefinitionen –Formale Sprachdefinitionen Denotationelle Semantik abstract state machines … –In diesem Fall macht es wieder Sinn, von Fehlern eines Interpreters relativ zu einer Sprachdefinition zu reden 6

7 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Interpreter und Programmsemantik Wenn man einen Interpreter zur Sprachdefinition benutzt, setzt man voraus, dass der Nutzer die Bedeutung der Basissprache bereits versteht. –Rekursionsanker ist meistens entweder Prosa (deutsch/englisch) oder die Mathematik –Ein vieldiskutiertes Problem in der Mathematik (Modelltheorie vs. Beweistheorie) und der Philosophie, aber nicht Thema von GdI-1. Insbesondere ist ein Meta-Interpreter keine vollständige Definition einer Programmiersprache! –Ein Meta-Interpreter ist zunächst nur eine Menge rekursiver Funktionsgleichungen, die viele oder auch gar keine Lösung haben können. 7

8 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Warum untersuchen wir Interpreter? Geheimnisse aufdecken, wie Prozesse implementiert sind daraus tieferes Verständnis erlangen –Wir betrachten uns selbst als Sprachentwickler und nicht nur als Nutzer einer Sprache, die andere entwickelt haben. Einblick gewinnen, wie neue Sprachen implementiert werden –Die Definition neuer Sprachen ist ein mächtiges Mittel, um Komplexität im Design der Entwicklung zu kontrollieren. –Neue Sprachen erhöhen unsere Fähigkeit, mit komplexen Problemen umzugehen, indem sie uns Mittel zur Verfügung stellen, mit deren Hilfe wir Probleme direkter beschreiben. 8

9 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Warum untersuchen wir Interpreter? Man kann viele Programme als einen Interpreter einer Sprache betrachten. Beispiel: ein Programm zur Berechnung von Polynomen in Scheme –Verkörpert die Rechenregeln für Polynome und implementiert sie als Operationen auf Listenstrukturen in Scheme –Wenn wir dieses Programm durch Prozeduren zum Lesen und Ausgeben von Polynomen ergänzen, haben wir den Kern einer spezialisierten Sprache für die symbolische Mathematik. 9

10 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Ein Interpreter nach dem Substitutionsmodell Wir werden im Folgenden einen Meta-Interpreter für eine Teilmenge von Scheme betrachten, der in Scheme selbst implementiert wird Explizit implementierte Konstrukte –Auswertungsreihenfolge –Substitution –Umgebung Implizit implementierte Konstrukte –Primitive Operationen (Addition, Multiplikation, …) –Primitive Werte (Zahlen, boolesche Werte) –Rekursion, if –Speicherverwaltung Von uns hier ignorierte Konstrukte –define-struct –local 10

11 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Stopp #1 auf dem Weg Randnotiz #1: Scheme ist besonders gut geeignet, um Sprachinterpreter zu schreiben –Einfache Syntax, wenige aber mächtige Sprachkonstrukte Randnotiz #2: Obwohl der Interpreter für Scheme geschrieben wird, enthält er die grundlegende Struktur eines Interpreters für jede Ausdrucks-orientierte Sprache, die verwendet werden kann, um Programme auf einer sequentiellen Maschine zu schreiben. –Genau genommen enthalten viele Programme (nicht nur Interpreter) tief unten einen kleinen Scheme Interpreter 11 Greenspun's Tenth Rule of Programming: Any sufficiently complicated C or Fortran program contains an ad-hoc, informally-specified bug-ridden slow implementation of half of Common Lisp.

12 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Stopp #2 auf dem Weg Studenten sind von Meta-Interpretern häufig verwirrt. Verwechseln Sie nicht die Basissprache mit der interpretierten Sprache! Wenn Sie einen Interpreter in Scheme schreiben, beeinflusst das nicht die Auswertung des DrScheme Interpreters Wenn Ihr Interpreter bei + multipliziert, ergibt (+ 3 5) in DrScheme nach wie vor 8 12

13 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Aufbau des Interpreters Der Interpreter hat eine ähnliche Struktur wie der Interpreter für arithmetische Ausdrücke, die wir bereits kennengelernt haben –Syntaxdefinition anhand entsprechender Datentypen –Parser – transformiert s-expressions in entsprechende Exemplare der Syntax-Datentypen (sogenannter abstract syntax tree - AST) –Auswertungsprozedur (eval...) Neu hinzu kommen folgende Funktionalitäten: –Substitution bei Funktionsanwendung –Umgebung, enthält primitive Operationen und selbst definierte Namen –Startprozedur, setzt die Umgebung auf und führt ein Scheme Programm aus 13

14 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Syntax Definition der abstrakten Syntax 14 ;; An expression exp is either ;; 1. (make-definition var val) where var is a symbol and ;; val is an exp ;; 2. (make-proc params exp) where params is a list-of-symbols ;; and exp is an exp ;; 3. (make-if-clause predicate c a) where predicate, c and a are exp ;; 4. (make-application operator operands) where operator is an exp ;; and operands is (listof exp) ;; 5. (make-variable n) where n is a symbol ;; 6. a number or a boolean or a string (define-struct definition (variable value)) (define-struct proc (parameters exp)) (define-struct if-clause (predicate consequent alternative)) (define-struct application (operator operands)) (define-struct variable (name))

15 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Syntax Wir lassen einige Teile von Scheme, soweit wir es kennen, weg –local -Definitionen –define-struct –cond –Direkte Definition von Prozeduren wie (define (f x) … ) Der letzte Punkt ist keine Einschränkung, da wir lambda Ausdrücke zulassen –Mit lambda Ausdrücken (make-proc … ) können wir diese Form von Prozedurdefinition leicht kodieren: (define (f x-1 … x-n) exp) wird zu (define f (lambda (x-1 … x-n) exp)) Auch cond kann mittels if kodiert werden Die Menge der primitiven Operationen ist in der Syntax nicht festgelegt 15

16 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Parser 16 ;; parse converts an s-expression into an exp structure ;; parse : s-expression -> exp (define (parse sexp) (cond [(number? sexp) sexp] [(string? sexp) sexp] [(boolean? sexp) sexp] [(symbol? sexp) (make-variable sexp)] [(cons? sexp) (local ((define op (first sexp))) (cond [(and (symbol? op) (symbol=? op 'lambda)) (make-proc (second sexp) (parse (third sexp)))] [(and (symbol? op) (symbol=? op 'if)) (make-if-clause (parse (second sexp)) (parse (third sexp)) (parse (fourth sexp)))] [(and (symbol? op) (symbol=? op 'define)) (make-definition (second sexp) (parse (third sexp)))] [else (make-application (parse (first sexp)) (map parse (rest sexp)))]))]))

17 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Parsing und abstrakte Syntax Die Datentypdefinitionen sind eine Abstraktion von der konkreten Syntax des Programms –So sind Klammern, Kommentare etc. verschwunden –Die konkrete Syntax zu dieser abstrakten Syntax könnte auch anders aussehen, z.B. f(op1,op2) statt (f op1 op2) oder 3+5 statt (+ 3 5) –Daher der Name abstrakte Syntax Der Parser ist durch die Verwendung von s-expressions einfach –Ohne s-expressions erhält der Parser lediglich eine Liste von Zeichen und muss daraus die abstrakte Syntax extrahieren Eine Wissenschaft für sich, aber nicht Thema von GdI-1 –Wichtig ist, dass wir anhand des ersten Elements einer Liste im Parser immer bereits entscheiden können, welchen AST- Datentyp wir erzeugen müssen Andernfalls würde das Parsen erheblich komplexer 17

18 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Der abstrakte Datentyp map Zur Implementierung des Interpreters verwenden wir einen neuen Datentyp: map Dieser Datentyp ähnelt Vektoren, doch statt Werte mit Zahlen zu assoziieren, assoziiert er Werte mit Symbolen –Das Symbol ist der Schlüssel, der mit einem Wert assoziiert wird –Der Datentyp map wird häufig benötigt, nicht nur in Interpretern, daher hat die Implementierung dieses Datentyps nichts mit dem Interpreter zu tun 1 (list 1 4) 2 (list 4 5) 3 (list 3) 4 empty 5 (list 2 5) 6 (list 3 6) CDU36.8 SPD36.7 FDP Ein Vektor Eine Map

19 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Der abstrakte Datentyp map Normalerweise würde man diesen Standard-Datentyp nicht selbst implementieren, sondern eine vorhandene Implementierung in einer Standard-Bibliothek benutzen –Wir wollen aber genauer verstehen, wie maps funktionieren –Daher implementieren wir diesen Datentyp selbst 19

20 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Der abstrakte Datentyp map Konstruktoren Selektoren Meist gibt es noch weitere Konstruktoren, Selektoren und Prädikate 20 ;; Data type definition for map ;; ;; A (mapof X) is either ;; 1. (map-create names values) where names ;; is a (listof symbol) and values is a (listof X) ;; 2. (map-extend var val base-env) where var is ;; a symbol, val is an X, and base-env is a (mapof X) ;; 3. (map-remove name a-map) where name is a symbol and ;; a-map is a (mapof X) ;; 4. (map-remove-all names a-map) where names is a ;; (listof symbol) and a-map is a (mapof X) ;; map-lookup: symbol (mapof X) -> X or empty

21 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Der abstrakte Datentyp map Implementierung der Konstruktoren 21 (define-struct binding (name value)) ;; hidden from users of map ;; map-create: (listof symbol) (listof X) -> (mapof X) (define (map-create names values) (map make-binding names values)) ;; map-extend: symbol X (mapof X) -> (mapof X) (define (map-extend var val base-env) (cons (make-binding var val) base-env)) ;; map-remove: symbol (mapof X) -> (mapof X) (define (map-remove name a-map) (filter (lambda (b) (not (symbol=? name (binding-name b)))) a-map)) ;; map-remove-all: (listof symbol) (mapof X) -> (mapof X) (define (map-remove-all names a-map) (foldr map-remove a-map names))

22 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Der abstrakte Datentyp map Implementierung des Selektors 22 ;; map-lookup: symbol (mapof X) -> X or empty (define (map-lookup name a-map) (if (empty? a-map) empty (if (symbol=? name (binding-name (first a-map))) (binding-value (first a-map)) (map-lookup name (rest a-map)))))

23 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Der abstrakte Datentyp map Maps gibt es in fast jeder Programmiersprache –Meist in Form von Bibliotheksfunktionen oder –(Seltener) direkt in die Sprache integriert Unsere Implementierung ist voll funktionsfähig, aber nicht sehr effizient –Lookup kostet O(n), wobei n die Zahl der Einträge ist Es gibt wesentlich effizientere Implementierungen –z.B. über Hash tables (ermöglichen Lookup in fast konstanter Zeit) In vielen Implementierungen können auch andere Datentypen als Symbol als Schlüssel verwendet werden Wir können leicht unsere Implementierung verändern; alle Nutzer vom map Datentyp, die sich an das Konstruktor-Selektor Protokoll halten, funktionieren weiterhin Der Datentyp map hat nichts mit der Listenfunktion map zu tun 23

24 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 (Selbstauswertende) Werte Betrachten wir die Werte, die der Interpreter produzieren kann 24 (define-struct primitive-procedure (the-proc)) ;; A value val is either ;; 1. a number ;; 2. a String ;; 3. a Boolean ;; 4. (make-proc params exp) where params is a list-of-symbols ;; and exp is an exp ;; 5. (make-primitive-procedure p) where p is a Scheme procedure ;; all values are self-evaluating ;; self-evaluating :: exp -> boolean (define (self-evaluating? exp) (cond [(number? exp) true] [(string? exp) true] [(boolean? exp) true] [(proc? exp) true] ;; procedures are self-evaluating!! [(primitive-procedure? exp) true] [else false]))

25 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Auswertung und Umgebung + (make-primitive-procedure +) x5 …… 25 Zum Beispiel env = Zum Beispiel (eval (make-application (make-variable '+) (list (make-variable 'x) 3)) env) 8 ;; Data type env: ;; An environment env is a (mapof val) ;; eval evaluates an expression exp in an environment env ;; eval : exp env -> val (define (eval exp env) …)

26 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Die Auswertungsprozedur Grundstruktur: –Weiterleitung an Spezialprozeduren für jeden Fall 26 ;; eval evaluates an expression exp in an environment env ;; eval : exp env -> val (define (eval exp env) (cond [(self-evaluating? exp) exp] [(variable? exp) (eval-var exp env)] [(if-clause? exp) (eval-if exp env)] [(application? exp) (eval-app (eval (application-operator exp) env) (map (lambda (expr) (eval expr env)) (application-operands exp)) env)] [else (error 'eval (format "Unknown expression type: ~v" exp))])) applikative Reihenfolge

27 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Die Auswertungsprozedur Auswertung von Variablen Auswertung von if Anweisungen 27 ;; evaluates a variable by looking it up in the environment ;; eval-var :: exp env -> val (define (eval-var exp env) (local ((define val (map-lookup (variable-name exp) env))) (if (empty? val) (error 'eval-var (format "Unbound variable: ~v" (variable-name exp))) val))) ;; eval-if : exp env -> val (define (eval-if exp env) (if (eval (if-clause-predicate exp) env) (eval (if-clause-consequent exp) env) (eval (if-clause-alternative exp) env)))

28 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Die Auswertungsprozedur Auswertung von Funktionsanwendungen 28 ;; eval-app: val (listof exp) env -> val (define (eval-app procedure arguments env) (cond [(primitive-procedure? procedure) (apply (primitive-procedure-the-proc procedure) arguments )] [(proc? procedure) (eval (subst (map-create (proc-parameters procedure) arguments) (proc-exp procedure)) env)] [else (error 'eval-app (format "Procedure expected, found: ~v" procedure))])) vgl. Auswertungsregel für zusammengesetzte Prozeduren

29 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Die Auswertungsprozedur Die Prozedur subst ist zunächst einmal auf unserer Wunschliste und wird als nächstes implementiert Die Prozedur apply die innerhalb der Auswertungsprozedur benutzt wird, ist eine primitive Prozedur, mit der die Parameter einer Prozedur als Liste übergeben werden können –(apply + (list 1 2 3)) ( ) –(apply f (list a b)) (f a b) Wir brauchen apply, weil wir nicht wissen, wieviele Argumente die primitive Prozedur benötigt 29

30 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Substitution Substitution wird als rekursive Funktion über Ausdrücken definiert –Fallunterscheidung je nach Typ des Ausdrucks, wie bei eval Die zu ersetzenden Namen und Werte werden in einer map übergeben 30 ;; subst substitutes all occurences of names in exp that are ;; associated with a value in a-map with that value, according ;; to the lexical scoping rules ;; subst : (mapof val) exp -> exp (define (subst a-map exp) …)

31 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Substitution Substitution innerhalb von Prozeduren, Variablen und selbst-auswertenden Ausdrücken 31 (define (subst a-map exp) (cond [(proc? exp) (make-proc (proc-parameters exp) (subst (map-remove-all (proc-parameters exp) a-map) (proc-exp exp)))] [(self-evaluating? exp) exp] [(variable? exp) (local ((define newval (map-lookup (variable-name exp) a-map))) (if (empty? newval) exp newval))]...)) Lokal mit lambda gebundene Namen überdecken äußere Bindungen Variable wird ersetzt, falls entsprechender Eintrag in Substitutionstabelle existiert

32 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Substitution if-clause?, application? : –Einfach in Unterausdrücken ersetzen 32 (define (subst a-map exp) (cond... [(if-clause? exp) (make-if-clause (subst a-map (if-clause-predicate exp)) (subst a-map (if-clause-consequent exp)) (subst a-map (if-clause-alternative exp)))] [(application? exp) (make-application (subst a-map (application-operator exp)) (map (lambda (op) (subst a-map op)) (application-operands exp)))] [else (error 'subst (format "Unknown expression type: ~v" exp))]))

33 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Substitution Die Substitutionsprozedur enthält noch einen Fehler –Wenn der Ausdruck, der eingesetzt wird, eine freie Variable enthält, wird diese möglicherweise durch die Substitution fälschlicherweise gebunden Wir werden diesen Fehler (noch) nicht beheben Die Lösung ist etwas kompliziert –Basisidee: Vor der Substitution in einem Lambda-Ausdruck wird geprüft, ob einer der Parameternamen frei in einem der Ausdrücke in der Substitutionstabelle vorkommt –Falls ja, wird der Parameter umbenannt 33

34 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Primitive Prozeduren Die gewünschten primitiven Operationen bilden die initiale Umgebung Kann leicht um neue primitive Operationen erweitert werden Es besteht kein Zwang, dass eine primitive Operation durch die primitive Operation desselben Namens in der Basissprache implementiert wird –Wir können auch nicht-primitive Scheme Prozeduren benutzen, die dann in der interpretierten Sprache primitiv sind –Wir könnten hier festlegen, dass das Symbol + in unserer Sprache Multiplikation bedeutet 34 (define primitive-procedures (local ((define names '(first rest cons list empty? empty * / - + < = abs)) (define procs (list first rest cons list empty? empty * / - + < = abs))) (map-create names (map make-primitive-procedure procs))))

35 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Ausführen von Programmen Die eval Prozedur kann nur einzelne Ausdrücke auswerten, jedoch keine (define … ) Anweisungen Ein Scheme Programm besteht jedoch aus einer Reihe von Definitionen und einer Reihe von Ausdrücken Die Ausführung eines Programms wird von der Prozedur run-prog erledigt –Erstellt initiale Umgebung –Erweitert Umgebung nach Auswertung einer (define … ) Anweisung –Für andere Ausdrücke werden die jeweiligen Ergebnisse berechnet und zu einer Ergebnisliste zusammengefügt 35

36 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Ausführen von Programmen 36 ;; a program prog is a (listof exp) ;; run-prog :: prog env -> (listof val) (define (run-prog prog env) (if (empty? prog) empty (local ((define exp (parse (first prog)))) (if (definition? exp) (run-prog (rest prog) (map-extend (definition-variable exp) (eval (definition-value exp) env) env)) (cons (eval exp env) (run-prog (rest prog) env)))))) Erweiterung der Umgebung Erweiterung der Ergebnisliste

37 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Benutzung des Interpreters 37 (define testprog '((define ! (lambda (n) (if (= n 0) 1 (* n (! (- n 1)))))) (! 5))) (run-prog testprog primitive-procedures)

38 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Daten als Programme Wir können factorial als Beschreibung einer Maschine verstehen, die Teile zum subtrahieren, multiplizieren und testen auf Gleichheit enthält. Darüber hinaus enthält die Maschine einen Kippschalter und eine andere factorial Maschine. –Die factorial Maschine ist unendlich, da sie eine andere factorial Maschine enthält 38 (define (factorial n) (if (= n 1) 1 (* (factorial (- n 1)) n)))

39 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Interpreter als universelle Maschine 39 Die factorial Maschine = * factorial

40 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Interpreter als universelle Maschine 40 Zum Beispiel: wenn wir dem Evaluator die Definition von factorial übergeben, kann er Fakultäten berechnen. Analog können wir einen Interpreter als eine sehr spezielle Maschine ansehen, die als Eingabe die Beschreibung einer anderen Maschine erwartet. Über diese Eingabe konfiguriert sich der Interpreter selbst, so dass er die in der Eingabe beschriebene Maschine nachbildet. (define (factorial n) (if (= n 1) 1 (* (factorial (- n 1)) n))) eval 6 720

41 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Interpreter als universelle Maschine Unser Interpreter kann als universelle Maschine betrachtet werden. –Er imitiert andere Maschinen, wenn sie als Scheme Programme beschrieben sind. Stellen Sie sich einen analogen Interpreter für elektrische Schaltkreise vor –… ein Schaltkreis, der als Signal die Pläne für andere Schaltkreise empfängt, z.B. ein Filter. Basierend auf diesem Input verhält sich der Schaltkreis wie ein Filter. –So ein universeller elektrischer Schaltkreis ist so komplex, dass er kaum vorstellbar ist. –Dagegen ist es überraschend, wie einfach der Code des Programm-Interpreters ist. 41

42 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Daten als Programme Der Interpreter ist eine Brücke zwischen Datenobjekten, die von unserer Programmiersprache manipuliert werden, und der Programmiersprache selbst. Unser Interpreter-Programm läuft und ein Nutzer gibt Ausdrücke an und beobachtet die Ergebnisse… –Aus dem Blickwinkel des Nutzers ist die Eingabe (* x x) ein Ausdruck in der Programmiersprache, den der Interpreter ausführen soll. –Vom Blickwinkel des Interpreterprogramms ist der Ausdruck nur eine Liste von Symbolen, *, x, und x, die nach festgelegten Regeln manipuliert werden sollen. 42

43 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Normale Auswertungsreihenfolge Mit Hilfe des Interpreters können wir nun sehr präzise ausdrücken, was normale Auswertungsreihenfolge ist und wie sie sich von applikativer Reihenfolge unterscheidet Informal: Bei normaler Auswertungsreihenfolge wird nur der Operator ausgewertet, die Operanden werden hingegen unausgewertet in den Funktionskörper hineinsubstitutiert, nur bei primitiven Operationen auswerten 43

44 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Der Unterschied… eval Funktion bei applikativer Reihenfolge 44 (define (eval exp env) (cond [(self-evaluating? exp) exp] [(variable? exp) (eval-var exp env)] [(if-clause? exp) (eval-if exp env)] [(application? exp) (eval-app (eval (application-operator exp) env) (map (lambda (expr) (eval expr env)) (application-operands exp)) env)] [else (error 'eval (format "Unknown expression type: ~a" exp))]))

45 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Der Unterschied… eval Funktion bei normaler Reihenfolge 45 (define (eval exp env) (cond [(self-evaluating? exp) exp] [(variable? exp) (eval-var exp env)] [(if-clause? exp) (eval-if exp env)] [(application? exp) (eval-app (eval (application-operator exp) env) (application-operands exp) ;; normal order env)] [else (error 'eval (format "Unknown expression type: ~a" exp))]))

46 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Der Unterschied… Die eval-app Funktion bei applikativer Reihenfolge 46 (define (eval-app procedure arguments env) (cond [(primitive-procedure? procedure) (apply (primitive-procedure-the-proc procedure) arguments )] [(proc? procedure)... ] [else... ]))

47 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Der Unterschied… Die eval-app Funktion bei normaler Reihenfolge 47 (define (eval-app procedure arguments env) (cond [(primitive-procedure? procedure) (apply (primitive-procedure-the-proc procedure) (map (lambda (expr) (eval expr env)) arguments) )] [(proc? procedure)... ] [else... ]))

48 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Vorteile von normaler Auswertungsreihenfolge Wir brauchen weniger Sonderformen! –Macht den Interpreter einfacher Jede Sonderform erfordert eine eigene Behandlung im Interpreter –Macht die Sprache einfacher Weniger Regeln/Ausnahmen –Macht die Sprache mächtiger So kann fold auch mit or/and benutzt werden Beispiel: if, cond, or, … müssen keine Sonderformen mehr sein, sondern können ganz normale Funktionen sein 48

49 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Vorteile von normaler Auswertungsreihenfolge Beispiel: if als normale Funktion –Dieses Beispiel würde bei applikativer Reihenfolge nicht funktionieren 49 (define testprog '((define my-if (lambda (c t e) (if c t e))) (define ! (lambda (n) (my-if (= n 0) 1 (* n (! (- n 1)))))) (! 5))) (run-prog testprog primitive-procedures) (list 120)

50 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Streams Normale Auswertungsreihenfolge ermöglicht zudem eine elegante Programmiertechnik: Stream-basierte Programme Modellieren von zeitbehafteten Objekten ohne Zuweisungen Idee: Beschreibe zeitabhängiges Verhalten eines Objektes als (unendliche) Sequenz x1, x2,… Man kann sich diese Sequenz als Repräsentation einer Funktion x(t) vorstellen Wir werden Streams als (unendliche) Listen darstellen. Funktionen arbeiten auf unendlich großen Strömen von Daten 50

51 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Stream-basierte Programmierung Zunächst bauen wir uns Listenkonstruktoren und Selektoren In einer echten Programmiersprache würde der Interpreter diese Konstrukte natürlich bereits (effizient) zur Verfügung stellen 51 (define testprog '((define my-cons (lambda (x y) (lambda (n) (if (= n 0) x y)))) (define my-first (lambda (p) (p 0))) (define my-rest (lambda (p) (p 1)))))

52 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Stream-basierte Programmierung 52 Beispiel: Wir möchten die Wurzel einer Zahl berechnen Näherungsverfahren für Berechnung von (sqrt n): –Beliebige erste Schätzung s 0 –Nächster Schätzwert –In Scheme: (define next (lambda (n) (lambda (x) (/ (+ x (/ n x)) 2)))) Mit Hilfe von Streams können wir dieses Näherungsverfahren implementieren, ohne uns über Abbruchbedingungen Gedanken machen zu müssen: Der Ausdruck (repeat (next n) a) erzeugt die (unendliche) Liste der immer besser werdenden Approximationen von (sqrt n) mit Startschätzung a: a, (f a), (f (f a)), (f (f (f a))), … wobei f = (next n) (define repeat (lambda (f a) (my-cons a (repeat f (f a))))) (define next (lambda (n) (lambda (x) (/ (+ x (/ n x)) 2))))

53 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Stream-basierte Programmierung Unabhängig von der Erzeugung dieses Stroms von Approximationen können wir nun verschiedene Abbruchbedingungen definieren –within: Gib Listenelement zurück, sobald zwei aufeinander folgende Listenelemente sich weniger als eps unterscheiden –relative-within: Schranke eps wird mit derzeitigem Wert multipliziert (besser bei kleinen Werten) 53 (define within (lambda (eps l) (if (< (abs (- (my-first l) (my-first (my-rest l)))) eps) (my-first l) (within eps (my-rest l))))) (define relative-within (lambda (eps l) (if (< (abs (- (my-first l) (my-first (my-rest l)))) (* eps (abs (my-first l)))) (my-first l) (relative-within eps (my-rest l)))))

54 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Stream-basierte Programmierung Zusammenbau der Funktionen und Tests –Bei kleinen Werten ist sqrt-rel genauer 54 (define sqrt (lambda (a eps n) (within eps (repeat (next n) a)))) (define sqrt-rel (lambda (a eps n) (relative-within eps (repeat (next n) a)))) (sqrt ) (sqrt-rel ) (sqrt ) (sqrt-rel )

55 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Stream-basierte Programmierung Bei normaler Auswertungsreihenfolge funktionieren Funktionen wie fold, map, filter automatisch auch auf Streams –Mit derselben Implementierung Beispiel: 55 (my-first (my-rest (filter prime? (enumerate-interval ))) Benötigt viel Zeit und Platz bei appl. Reihenfolge, bei norm. Reihenfolge wird erst bei Bedarf das nächste Listenelemt berechnet Auch möglich: wobei allnats die Liste aller natürlichen Zahlen ist (my-first (my-rest (filter prime? allnats))

56 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Stream-basierte Programmierung Weiteres Beispiel: Alle geraden Fibonacci Zahlen Um dies in unserem Interpreter laufen zu lassen, müssen die entsprechenden Hilfsfunktionen wie filter, even? natürlich erst implementiert werden Der Interpreter selbst muss dazu allerdings nicht verändert werden! 56 (define (f a b) (my-cons a (f b (+ a b)))) (define fibs (f 1 1)) (define evenfibs (filter even? fibs))

57 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T9 Zusammenfassung Alle Funktionsteile sind wiederverwendbar und kombinierbar –next, within, within-rel, repeat, … Ohne Streams wäre das sehr schwierig –Man kann die Abbruchbedingung nicht von der Erzeugung der Werte trennen Die pipes-and-filters Architektur aus T5 lässt sich auch bei unendlichen Datenströmen anwenden –Außerdem werden Ergebnisse dann inkrementell berechnet Die Idee unendlicher Datenströme wird in der Praxis sehr häufig eingesetzt (z.B. Unix Kommandozeile, Java Streams) –Normale Auswertungsreihenfolge muss simuliert werden Streams sind eine wichtige Alternative zum Design mit Zustand und Zuweisungen –Repräsentieren Zeit explizit und nicht implizit wie bei Zuweisungen Die Gründe, wieso normale Auswertungsreihenfolge trotzdem in vielen Sprachen nicht benutzt wird, wurden bereits diskutiert 57


Herunterladen ppt "Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 9: Interpreter nach."

Ähnliche Präsentationen


Google-Anzeigen