Scheme als funktionale Sprache: Scheme als funktionale Sprache: • Funktionen Objekte erster Ordnung • Diskussion von Scheme im Vergleich mit Haskell 1 ]=> (define pi 3.1415) ;Value: pi • m.a.W. Gemeinsamkeiten und Unterschiede • Haskell als ‘Blaupause’ für funktionale Sprachen 1 ]=> pi ;Value: 3.1415 Grundlegendes: 1 ]=> (define quadriere (lambda (zahl) (* zahl zahl))) ;Value: quadriere • Interpreter • Definition von Werten mit define 1 ]=> (quadriere pi) ;Value: 9.86902225 (define <name> <wert>) c Prof. Dr. D. Rösner; erstellt: 19. Juni 2007 Sommer 2007, Programmierparadigmen (PGP), 209 c Prof. Dr. D. Rösner; erstellt: 19. Juni 2007 Sommer 2007, Programmierparadigmen (PGP), Scheme: Anonyme Funktionen 210 Scheme: Anonyme Funktionen alternative Syntax für benannte Funktionen • Syntax: • (define (<name> <par-1> ... <par-n>) <koerper>) (lambda <parameterliste> <koerper>) • überall dort verwendbar, wo auch mit Symbol auf Funktion verwiesen werden kann 1 ]=> ((lambda (n) (* n n)) 3) • statt (define <name> (lambda (<par-1> ... <par-n>) <koerper>)) ;Value: 9 c Prof. Dr. D. Rösner; erstellt: 19. Juni 2007 Sommer 2007, Programmierparadigmen (PGP), 211 c Prof. Dr. D. Rösner; erstellt: 19. Juni 2007 Sommer 2007, Programmierparadigmen (PGP), 212 Scheme vs. Haskell Scheme: Übersicht • in Scheme: Klammerung innerhalb geschachtelter Ausdrücke; in Haskell: Vorrangregeln • vordefinierte Datentypen – Zahlen: ganze, rationale, Fliesskomma, ... – Strings – Zeichen – boolesche Werte: #t, #f • in Scheme: keine Typisierung; in Haskell: strenge Typisierung • Scheme: strikt; Haskell: non-strikt • wichtigster aggregierter Datentyp: Liste – Konstruktor: cons – Selektoren: car, cdr – Prädikate: null? • in Scheme nicht vordefiniert vorhanden sind u.a. Listenkomprehension und Fallunterscheidung durch Pattern Matching • Kontrollstrukturen: – if – cond • in Haskell: verzögerte Auswertung (lazy evaluation) für alle Argumente in Scheme: Auswertung für alle Argumente; aber: verzögerte Auswertung und call-by-need möglich mit delay und force • Funktionen zur Konversion zwischen verschiedenen Typen c Prof. Dr. D. Rösner; erstellt: 19. Juni 2007 Sommer 2007, Programmierparadigmen (PGP), 213 c Prof. Dr. D. Rösner; erstellt: 19. Juni 2007 Sommer 2007, Programmierparadigmen (PGP), Striktheit vs. Non-Striktheit Scheme: Programm-Daten-Äquivalenz • Eine (seiteneffekt-freie) Funktion heisst strikt, wenn gefordert wird, dass alle ihre Argumente definiert sind und so die Evaluationsordnung das Ergebnis nicht verändert. • Eine Funktion heisst non-strikt, wenn für sie die Forderung nach Striktheit nicht erhoben wird. • Programme haben die Form von Listen • Scheme (und Lisp) sind homoikonisch, d.h. selbstrepräsentierend • Programme können mit allen Listenfunktionen bearbeitet werden • Beispiel: • Eine Sprache heisst strikt, wenn gefordert wird, dass alle ihre Funktionen strikt. (define compose (lambda (f g) (lambda (x) (f (g x))))) • Eine Sprache heisst non-strikt, wenn sie die Definition non-strikter Funktionen zulässt. 1 ]=> ((compose car cdr) ’(1 2 3)) ;Value: 2 c Prof. Dr. D. Rösner; erstellt: 19. Juni 2007 Sommer 2007, Programmierparadigmen (PGP), 214 215 c Prof. Dr. D. Rösner; erstellt: 19. Juni 2007 Sommer 2007, Programmierparadigmen (PGP), 216 Scheme: weitere Aspekte Scheme: Programm-Daten-Äquivalenz • Funktionen mit beliebiger Anzahl von Argumenten möglich (sog. Restparameter, der an Liste gebunden) • Beispiel cont.: (define compose2 (lambda (f g) (eval (list ’lambda ’(x) (list f (list g ’x))) (scheme-report-environment 5)))) • Beispiel: (define (avg . nums) (average nums)) 1 ]=> ((compose2 car cdr) ’(1 2 3)) • average erwartet Liste als Argument ;Value: 2 • Definition: (define (average nums)(/ (apply + nums) (length nums))) c Prof. Dr. D. Rösner; erstellt: 19. Juni 2007 Sommer 2007, Programmierparadigmen (PGP), 217 Scheme: Funktionen höherer Ordnung c Prof. Dr. D. Rösner; erstellt: 19. Juni 2007 Sommer 2007, Programmierparadigmen (PGP), 218 Scheme: Funktionen höherer Ordnung • z.B. Falten einer zweistelligen Funktion in eine Liste: • partielle Anwendungen sind bei Funktionen im Curry-Format möglich (define fold (lambda (f l i) (if (null? l) i ;; identity for f (f (car l) (fold f (cdr l) i))))) (define curry (lambda (f) (lambda (a) (lambda (b) (f a b))))) 1 ]=> (((curry +) 3) 4) ;Value: 7 (define curried-plus (curry +)) c Prof. Dr. D. Rösner; erstellt: 19. Juni 2007 Sommer 2007, Programmierparadigmen (PGP), 219 c Prof. Dr. D. Rösner; erstellt: 19. Juni 2007 Sommer 2007, Programmierparadigmen (PGP), 220