Funktionales Programmieren Programmierparadigmen Evaluierungsordnung M. Kunze Institut für Wissens- und Sprachverarbeitung Fakultät für Informatik Otto-von-Guericke Universität Magdeburg c Sommer 2011, 14. Juni 2011, 2011 M. Kunze M. Kunze PGP 2011 . . . 1 Funktionales Programmieren Gliederung 1 Funktionales Programmieren Evaluierungsordnung Auswertung von Ausdrücken Beispiele Evaluierungsreihenfolgen Ausnahmen in Scheme Lazy-Evaluation M. Kunze PGP 2011 . . . 2 Funktionales Programmieren Evaluierungsordnung Auswertung von Ausdrücken Was liefern die Ausdrücke (g 0 (f 3)) und (g 1 (f 3)) in Scheme und in Haskell mit den folgenden Definitionen?: in Scheme (define (f x) (/ x 0)) (define (g x y) (if (= x 0) 1 y)) in Haskell f x = div x 0 g x y = if (x == 0) then 1 else y M. Kunze PGP 2011 . . . 4 Funktionales Programmieren Evaluierungsordnung Arten der Evaluierungen verschiedene Vorgehensweise bei der Evaluierung von Ausdrücken möglich: in applikativer Reihenfolge in normaler Reihenfolge applikativer Ordnung: Argumente werden ausgewertet bevor die Funktion ausgeführt wird Normalordnung: Argumente werden unausgewertet an eine Funktion übergeben Wenn beide Evaluierungen terminieren, dann müssen sie auch das gleiche Ergebnis liefern. Aber: Es ist möglich, dass eine Evaluierungsordnung nicht terminiert. M. Kunze PGP 2011 . . . 5 Funktionales Programmieren Evaluierungsordnung Beispiele Beispiel 1 (define (double x) (+ x x)) (double (+ 3 2) ) [Sco00] M. Kunze PGP 2011 . . . 6 Funktionales Programmieren Evaluierungsordnung Beispiel 2 Beispiel 2 (define switch (lambda (x a b c) (cond ((< x 0) a) ((= x 0) b) ((> x 0) c)))) (switch -1 (+ 1 2) (+ 2 3) (+ 3 4)) [Sco00] M. Kunze PGP 2011 . . . 7 Funktionales Programmieren Evaluierungsordnung Beispiel 2 normale Reihenfolge > (switch -1 (+ 1 2) (+ 2 3) (+ 3 4)) > (cond ((< -1 0) (+ 1 3)) ((= -1 0) (+ 2 3)) ((> -1 0) (+ 3 4)) > (cond (#t (+ 1 2)) ((= -1 0) (+ 2 3)) ((> -1 0) (+ 3 4)) > (+ 1 2) > 3 M. Kunze PGP 2011 . . . 8 Funktionales Programmieren Evaluierungsordnung Beispiel 2 applikative Reihenfolge > > > > > (switch -1 (+ 1 2) (+ 2 3) (+ 3 4)) (switch -1 3 (+ 2 3) (+ 3 4)) (switch -1 3 5 (+ 3 4)) (switch -1 3 5 7) (cond ((< -1 0) 3) ((= -1 0) 5) ((> -1 0) 7)) > (cond (#t 3) ((= -1 0) 5) ((> -1 0) 7)) > 3 M. Kunze PGP 2011 . . . 9 Funktionales Programmieren Evaluierungsordnung Beispiel 3 Beispiel: (define (null x) 0) (null(quadrat (quadrat(quadrat 2)))) M. Kunze PGP 2011 . . . 10 Funktionales Programmieren Evaluierungsordnung Beispiel 3 applikative Reihenfolge > > > > > > > > (null(quadrat (quadrat (quadrat 2)))) (null(quadrat (quadrat (* 2 2)))) (null(quadrat (quadrat 4))) (null(quadrat (* 4 4))) (null(quadrat 16)) (null(* 16 16)) (null 256) 0 normale Reihenfolge > (null(quadrat (quadrat (quadrat 2)))) > 0 M. Kunze PGP 2011 . . . 11 Funktionales Programmieren Evaluierungsordnung Applikative Reihenfolge ’call by value’, ’eager evaluation’, ’strict evaluation’ Vorgehensweise in Scheme und in vielen imperativen Programmiersprachen Vorteil: Wert der Variablen wird nur einmal berechnet Nachteil: Ausdrücke, die eventuell nicht benötigt werden, werden umsonst berechnet M. Kunze PGP 2011 . . . 12 Funktionales Programmieren Evaluierungsordnung Normale Reihenfolge Argumente werden nur im Bedarfsfall ausgewertet, ’call by need’ in Haskell der Fall Vorteil: Ausdruck wird nur ausgewertet, wenn benötigt Nachteil: Der Wert des Argumentes muß unter Umständen mehrmals berechnet werden. M. Kunze PGP 2011 . . . 13 Funktionales Programmieren Evaluierungsordnung Ausnahmen in Scheme abhängig von der verwendeten Scheme-Version Es gibt Spezialformen in Scheme, die nicht die applikative Reihenfolge verwenden, z.B.: cond if boolsche Operatoren: and, ... M. Kunze PGP 2011 . . . 14 Funktionales Programmieren Evaluierungsordnung Ausnahmen in Scheme Beispiele: > ((or #f #t (= 1 (/ 3 0))) #t > (and #f #t (= 1 (/ 3 0))) #f or wertet solange die Ausdrücke aus, bis ein Ausdruck True ergibt and wertet solange die Ausdrücke aus, bis ein Ausdruck False ergibt cond übernimmt die nicht ausgewerteten Ausdrücke als Argumente und wertet intern nur die car’s der Argumente sequentiell aus, bis ein Ausdruck True zurückgibt M. Kunze PGP 2011 . . . 15 Funktionales Programmieren Evaluierungsordnung Auswertungen von Sonderausdrücken Der Ausdruck (if <term> <then-body > <else-body >) kann auch (non-strict) ausgewertet werden: werte nur <term> aus hat <term> den Wert True, werte <then-body > aus hat <term> den Wert False, wert <else-body > aus M. Kunze PGP 2011 . . . 16 Funktionales Programmieren Evaluierungsordnung Lazy-Evaluation lazy evaluation vereint die Vorteile von applikativer und normaler Evaluierungsreihenfolge führt die Funktionsanwendung vor der Auswertung der Parameter durch bei Funktionsanwendung, werden alle bis auf ein Vorkommen eines Parameters durch einen Verweis auf ein einziges die dieses Vorkommen ersetzt mgl. durch die Forderung nach referentielle Transparenz in funktionalen Programmiersprachen: Die Auswertung eines Ausdruckes ergibt den gleichen Wert.[Set96] M. Kunze PGP 2011 . . . 17 Funktionales Programmieren Evaluierungsordnung Lazy-Evaluation vermeidet die mehrfache Auswertung von Parametern (applikative Reihenfolge) vermeidet die Auswertung von Parametern, die zur Auswertung einer Funktion nicht nötig ist (normale Reihenfolge) M. Kunze PGP 2011 . . . 18 Funktionales Programmieren Evaluierungsordnung Lazy-Evaluation erlaubt auch die Darstellung und Verarbeitung von Datenstrukturen von beliebiger Größe in Haskell möglich in Scheme mittels Spezialformen delay und force möglich M. Kunze PGP 2011 . . . 19 Funktionales Programmieren Evaluierungsordnung Literatur: I Michael Lee Scott. Programming Language Pragmatics. Academic Press, San Diego, CA, USA, 2000. ISBN 1-55860-578-9. Ravi Sethi. Programming Languages – Concepts and Constructs. Addison-Wesley, Reading, Mass. USA, 1996. ISBN 0-201-59065-4. M. Kunze PGP 2011 . . . 20