Programmierparadigmen - Einführung in Scheme

Werbung
Funktionales Programmieren: Scheme
Funktionales Programmieren: Scheme
Gliederung
Programmierparadigmen
1
Einführung in Scheme
D. Rösner
Institut für Wissens- und Sprachverarbeitung
Fakultät für Informatik
Otto-von-Guericke Universität Magdeburg
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
c
Sommer 2013, 17. Juni 2013, 2011
- 13 D.Rösner
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
1
D. Rösner PGP 2013 . . .
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Funktionales Programmieren: Scheme
Historie
2
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Historie
unterschiedliche Ausrichtungen:
Fortran: numerische Berechnungen
Frage: Welches sind die zwei ältesten und (in
modernisierter Form) immer noch benutzten
Programmiersprachen?
Lisp: Symbolverarbeitung
Symbolverarbeitung?
Beispiele:
...
...
symbolisches Rechnen (z.B. Differentiation, Integration)
logisches Schliessen
Analyse und Synthese chemischer Formeln
Verarbeitung natürlicher Sprache
Repräsentation von Wissen (z.B. semantische Netze)
...
Frage: Wann wurden diese Sprachen entwickelt?
...
D. Rösner PGP 2013 . . .
4
D. Rösner PGP 2013 . . .
5
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Funktionales Programmieren: Scheme
Symbolverarbeitung mit Lisp
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Scheme als funktionale Sprache:
Sprachmittel für Symbolverarbeitung in Lisp
Diskussion von Scheme im Vergleich mit Haskell
Atome als elementare Bausteine
zusammengesetzte Strukturen auf der Basis
verschachtelter Listen
Beispiel: mögliche Darstellung eines Syntaxbaums
(S (NP (DET Der) (N Mann))
(VP (V fragt)
(PP (P nach)
(NP (DET dem) (N Weg)
(PP (P zum)
(NP (N Bahnhof)))))))
m.a.W. Gemeinsamkeiten und Unterschiede
Haskell als ‘Blaupause’ für funktionale Sprachen
Grundlegendes:
Interpreter
Definition von Assoziationen zwischen Namen und Werten
mit define
(define <name> <wert>)
Scheme ist ein Dialekt von Lisp
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
D. Rösner PGP 2013 . . .
6
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Funktionales Programmieren: Scheme
Scheme als funktionale Sprache:
7
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Scheme: Anonyme Funktionen
wichtig: Funktionen sind Objekte erster Ordnung
eine Interaktion:
Syntax:
(lambda <parameterliste> <koerper>)
überall dort verwendbar, wo auch mit Symbol auf Funktion
verwiesen werden kann
1 ]=> (define pi 3.1415)
;Value: pi
1 ]=> pi
;Value: 3.1415
1 ]=> ((lambda (n) (* n n)) 3)
1 ]=> (define quadriere
(lambda (zahl) (* zahl zahl)))
;Value: quadriere
;Value: 9
1 ]=> (quadriere pi)
;Value: 9.86902225
D. Rösner PGP 2013 . . .
8
D. Rösner PGP 2013 . . .
9
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Funktionales Programmieren: Scheme
Scheme: Anonyme Funktionen
Scheme: Übersicht
vordefinierte Datentypen
alternative Syntax für benannte Funktionen
Zahlen: ganze, rationale, Fliesskomma, ...
Strings: z.B. "ein String"
Zeichen: z.B. #\a #\Z #\* #\space
boolesche Werte: #t, #f
...
(define (<name> <par-1> ... <par-n>) <koerper>)
statt
(define <name>
(lambda (<par-1> ... <par-n>) <koerper>))
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
10
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
Scheme: Übersicht
11
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Scheme vs. Haskell
Syntax:
wichtigster aggregierter Datentyp: Liste
in Scheme: Klammerung innerhalb geschachtelter
Ausdrücke
in Haskell: Vorrangregeln, Layoutregel
Konstruktor: cons
Selektoren: car, cdr
Prädikate: list?, null?
Typisierung?
wichtige Kontrollstrukturen:
in Scheme: keine Typisierung;
in Haskell: strenge Typisierung
if
cond
Striktheit?
Scheme: strikt
Haskell: non-strikt
Funktionen zur Konversion zwischen verschiedenen Typen, z.B.
rein funktional (pur)?
number->string
string->list
...
D. Rösner PGP 2013 . . .
Scheme: nicht pur, Seiteneffekte möglich z.B. mit set!
Haskell: pur
12
D. Rösner PGP 2013 . . .
14
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Funktionales Programmieren: Scheme
Scheme vs. Haskell
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Striktheit vs. Non-Striktheit
Eine (seiteneffekt-freie) Funktion heisst strikt, wenn
gefordert wird, dass alle ihre Argumente definiert sind und
so die Evaluationsordnung das Ergebnis nicht verändert.
in Scheme: keine Typisierung
Typüberprüfung durch vor- oder eigendefinierte
Typprädikate
Beispiele:
Eine Funktion heisst non-strikt, wenn für sie die Forderung
nach Striktheit nicht erhoben wird.
Eine Sprache heisst strikt, wenn gefordert wird, dass alle
ihre Funktionen strikt.
number?
list?
string?
...
Eine Sprache heisst non-strikt, wenn sie die Definition
non-strikter Funktionen zulässt.
s.a. [Sco00], Ch. 11.2.2.
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
15
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
Scheme vs. Haskell
16
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Scheme: weitere Aspekte
Art der Auswertung?
Funktionen mit beliebiger Anzahl von Argumenten möglich
(sog. Restparameter, der an Liste gebunden)
Beispiel:
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
s.a. [Sco00], Ch. 11.2.2.
(define (avg . nums) (average nums))
average erwartet Liste als Argument
Definition:
in Scheme nicht vordefiniert vorhanden sind u.a.
(define (average nums)
(/ (apply + nums) (length nums)))
Listenkomprehensionen und
Fallunterscheidung durch Pattern Matching
D. Rösner PGP 2013 . . .
17
D. Rösner PGP 2013 . . .
18
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Funktionales Programmieren: Scheme
Scheme: Funktionen höherer Ordnung
Scheme: Funktionen höherer Ordnung
map . . . Anwenden einer Funktion auf die Elemente einer
Liste und Rückgabe der Liste der Ergebnisse
z.B. Falten einer zweistelligen Funktion in eine Liste:
> (define (map f l) (if (null? l) ’()
(cons (f (car l)) (map f (cdr l)))))
(define fold
(lambda (f l i)
(if (null? l) i ;; identity for f
(f (car l) (fold f (cdr l) i)))))
> (map (lambda (x) (* x x)) ’(2 3 4 5))
(4 9 16 25)
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
20
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
Scheme: Funktionen höherer Ordnung
21
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Scheme vs. Haskell:
partielle Anwendungen sind bei Funktionen im
Curry-Format möglich
Sichtbarkeit von Definitionen
die Definitionen auf dem Toplevel von Scheme sind ‘global’
sichtbar
wechselseitige Bezugnahme in rekursiven Definitionen ist
möglich
Beispiel:
1 ]=> (define (isOdd n)
(if (<= n 0) () (isEven (- n 1))))
(define curry
(lambda (f) (lambda (a) (lambda (b) (f a b)))))
1 ]=> (((curry +) 3) 4)
;Value: 7
;Value: isodd
...
(define curried-plus (curry +))
D. Rösner PGP 2013 . . .
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
22
D. Rösner PGP 2013 . . .
24
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Funktionales Programmieren: Scheme
Scheme vs. Haskell: Sichtbarkeit von Definitionen
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Lokale Definitionen
Beispiel cont.:
1 ]=> (define (isEven n)
(if (< n 0) ()
(if (= n 0) #t (isOdd (- n 1)))))
Motivation:
Vermeiden wiederholter Berechnungen
klarer strukturierter Code
Beispiel:
eine Funktion addPairwise’, die korrespondierende
Elemente zweier Zahlenlisten addiert und – falls eine Liste
keine Elemente mehr hat – den aktuellen Rest der anderen
an die Liste der Paarsummen anhängt
;Value: iseven
1 ]=> (isEven 5)
;Value: ()
1 ]=> (isOdd 5)
;Value: #t
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
25
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
Scheme: lokale Bindungen mit let und let*
26
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Scheme: lokale Bindungen mit let und let*
Syntax:
Beispiel: addPairwiseRest als Äquivalent zu
addPairwise’
(let ((var1 val1)
(var2 val2)
... (varN valN))
<body>)
(define (addPairwiseRest list1 list2)
(let ((front (addPairwise list1 list2))
(minLength (min (length list1)(length list2))))
(let ((rear (append (drop minLength list1)
(drop minLength list2))))
(append front rear))))
Semantik:
bei der Auswertung von <body> sind die in var1, var2,
..., varN gebundenen Werte val1, val2, ...,
valN verfügbar
D. Rösner PGP 2013 . . .
27
D. Rösner PGP 2013 . . .
28
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Funktionales Programmieren: Scheme
Scheme: lokale Bindungen mit let und let*
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Scheme: lokale Bindungen mit let und let*
Beachte: bei let erfolgt die Auswertung und Bindung in
den einzelnen (var1 val1) (var2 val2) ...
(varN valN) parallel
daher folgendes falsch:
let* ist wie let, nur erfolgt Auswertung und Bindung in
den einzelnen (var1 val1) (var2 val2) ...
(varN valN) sequentiell
(define (addPairwiseRest list1 list2)
(let ((front (addPairwise list1 list2))
(minLength (min (length list1)(length list2)))
(rear (append (drop minLength list1)
(drop minLength list2))))
(append front rear)))
m.a.W. für die Ausdrücke vali (für 2 <= i <= n) stehen
die Bindungen var1, var2, ..., var(i-1) zur
Verfügung
1 ]=> (addPairwiseRest ’(4 7 1 1 ) ’(8 15))
;Unbound variable: minlength
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
29
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
Scheme: lokale Bindungen mit let und let*
30
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Beispiel cont.
Hilfsfunktionen a la Haskell:
(define (addPairwise list1 list2)
(if (or (null? list1)(null? list2))
()
(cons (+ (car list1)(car list2))
(addPairwise (cdr list1)(cdr list2)))))
Beispiel für let*:
(define (addPairwiseRest list1 list2)
(let* ((front (addPairwise list1 list2))
(minLength (min (length list1)(length list2)))
(rear (append (drop minLength list1)
(drop minLength list2))))
(append front rear)))
(define (take n list)
(if (= n 0) ()
(cons (car list) (take (- n 1) (cdr list)))))
1 ]=> (addPairwiseRest ’(4 7 1 1 ) ’(8 15))
;Value 12: (12 22 1 1)
D. Rösner PGP 2013 . . .
(define (drop n list)
(if (= n 0) list
(drop (- n 1) (cdr list))))
31
D. Rösner PGP 2013 . . .
32
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Funktionales Programmieren: Scheme
Scheme: Berechnung Quadratwurzel mit
Newton-Verfahren
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Blockstruktur:
(define (sqrt x)
(define (good-enough? guess x)
(< (abs (- (square guess) x)) .001))
(define (improve guess x)
(average guess (/ x guess)))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(define (sqrt x)
(sqrt-iter 1 x))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(define (good-enough? guess x)
(< (abs (- (square guess) x)) .001))
(sqrt-iter 1 x)
)
(define (improve guess x)
(average guess (/ x guess)))
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
34
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
Interne Definitionen
35
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
lexikalischer Skopus:
Ausnutzen, daß x in sqrt gebunden (lexikalischer Skopus):
(define (sqrt x)
(define (good-enough? guess)
(< (abs (- (square guess) x)) .001))
(define (improve guess)
(average guess (/ x guess)))
(define (sqrt-iter guess)
(if (good-enough? guess)
guess
(sqrt-iter (improve guess))))
freie Variable in einer Prozedur verweisen auf Variable in
umfassenden Prozeduren
m.a.W.: Werte freier Variable werden in der Umgebung
gesucht, in der die Prozedur definiert wurde
(sqrt-iter 1))
D. Rösner PGP 2013 . . .
36
D. Rösner PGP 2013 . . .
37
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Funktionales Programmieren: Scheme
Symbolisches Differenzieren
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Symbolisches Differenzieren
zentrale Funktion: deriv (s.a. [AGJ96])
(define (deriv exp var)
(cond ((constant? exp) 0)
((variable? exp)
(if (same-variable? exp var) 1 0))
((sum? exp)
(make-sum (deriv (addend exp) var)
(deriv (augend exp) var)))
((product? exp)
(make-sum
(make-product
(multiplier exp)
(deriv (multiplicand exp) var))
(make-product
(deriv (multiplier exp) var)
D. Rösner PGP 2013 . . .
39
(multiplicand exp))))))
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Darstellung von Summen (s.a. [AGJ96])
(define (make-sum a1 a2) (list ’+ a1 a2))
(define (sum? x)
(if (not (atom? x)) (eq? (car x) ’+) nil))
(define (addend s) (cadr s))
(define (augend s) (caddr s))
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
Symbolisches Differenzieren
40
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Symbolisches Differenzieren
Darstellung von Produkten (s.a. [AGJ96])
allgemein: Darstellung von Datenstrukturen
(define (make-product m1 m2) (list ’* m1 m2))
Konstruktoren
Prädikate
Selektoren
(define (product? x)
(if (not (atom? x)) (eq? (car x) ’*) nil))
s.a. [AGJ96]
(define (multiplier p) (cadr p))
(define (multiplicand p) (caddr p))
D. Rösner PGP 2013 . . .
41
D. Rösner PGP 2013 . . .
42
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Symbolisches Differenzieren
Symbolisches Differenzieren
Hilfsfunktionen (s.a. [AGJ96])
Hilfsfunktionen (s.a. [AGJ96])
(define (constant? x) (number? x))
(define (atom? x)
(or (number? x)
(string? x)
(symbol? x)
(null? x)
(eq? x #t)))
(define (variable? x) (symbol? x))
(define (same-variable? v1 v2)
(and (variable? v1) (variable? v2) (eq? v1 v2)))
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
43
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
Symbolisches Differenzieren
44
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Symbolisches Differenzieren
Beispiele (s.a. [AGJ96])
verbesserte Konstruktor-Funktionen (s.a. [AGJ96])
Welcome to DrRacket, version 5.3.4 [3m].
Language: R5RS [custom]; memory limit: 128 MB.
> (deriv ’(+ x 3) ’x)
(define (make-sum a1 a2)
(cond ((and (number? a1) (number? a2))
(+ a1 a2))
((number? a1)
(if (= a1 0) a2 (list ’+ a1 a2)))
((number? a2)
(if (= a2 0) a1 (list ’+ a1 a2)))
(else (list ’+ a1 a2))))
(+ 1 0)
> (deriv ’(* x y) ’y)
(+ (* x 1) (* 0 y))
> (deriv ’(* (* x y) (+ x 3)) ’x)
(+ (* (* x y) (+ 1 0))
(* (+ (* x 0) (* 1 y)) (+ x 3)))
Welche Vereinfachungen von Termen?
D. Rösner PGP 2013 . . .
45
D. Rösner PGP 2013 . . .
46
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Funktionales Programmieren: Scheme
Symbolisches Differenzieren
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Symbolisches Differenzieren
verbesserte Konstruktor-Funktionen (s.a. [AGJ96])
Anwendung verbesserter Konstruktor-Funktion make-sum
(s.a. [AGJ96])
(define (make-product m1 m2)
(cond ((and (number? m1) (number? m2))
(* m1 m2))
((number? m1)
(cond ((= m1 0) 0)
((= m1 1) m2)
(else (list ’* m1 m2))))
((number? m2)
(cond ((= m2 0) 0)
((= m2 1) m1)
(else (list ’* m1 m2))))
(else (list ’* m1 m2))))
> (deriv ’(+ x 3) ’x)
1
> (deriv ’(* (* x y) (+ x 3)) ’x)
(+ (* (* x y) 1)
(* (+ (* x 0) (* 1 y)) (+ x 3)))
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
47
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
D. Rösner PGP 2013 . . .
Funktionales Programmieren: Scheme
Symbolisches Differenzieren
48
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Scheme: Programm-Daten-Äquivalenz
Anwendung verbesserter Konstruktor-Funktion
make-product (s.a. [AGJ96])
statt
Programme haben die Form von Listen
Scheme (und Lisp) sind homoikonisch, d.h.
selbstrepräsentierend
Programme können mit allen Listenfunktionen bearbeitet
werden
Beispiel:
> (deriv ’(* (* x y) (+ x 3)) ’x)
(+ (* (* x y) 1)
(* (+ (* x 0) (* 1 y)) (+ x 3)))
(define compose
(lambda (f g)
(lambda (x) (f (g x)))))
jetzt
> (deriv ’(* (* x y) (+ x 3)) ’x)
(+ (* x y) (* y (+ x 3)))
D. Rösner PGP 2013 . . .
1 ]=> ((compose car cdr) ’(1 2 3))
;Value: 2
49
D. Rösner PGP 2013 . . .
51
Funktionales Programmieren: Scheme
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
Funktionales Programmieren: Scheme
Scheme: Programm-Daten-Äquivalenz
Literatur: I
Beispiel cont.:
Harold Abelson, G.J.Sussman, and J.Sussman.
Structure and Interpretation of Computer Programs.
MIT Press, Cambridge, MA, USA, 1996.
2nd edition; Bem.: dt. Übersetzung existiert, aber engl.
Original ist mehr zu empfehlen – DR.
(define compose2
(lambda (f g)
(eval (list ’lambda ’(x) (list f (list g ’x)))
(scheme-report-environment 5))))
Michael Lee Scott.
Programming Language Pragmatics.
Academic Press, San Diego, CA, USA, 2000.
ISBN 1-55860-578-9.
1 ]=> ((compose2 car cdr) ’(1 2 3))
;Value: 2
D. Rösner PGP 2013 . . .
Einführung
Scheme vs. Haskell
Funktionen höherer Ordnung
Skopus
Beispiel: Newton-Verfahren
Beispiel: Symbolisches Differenzieren
Programm-Daten-Äquivalenz
52
D. Rösner PGP 2013 . . .
53
Herunterladen