Zürcher Fachhochschule
Programmiersprachen und -paradigmen (PSPP)
Lisp Teil 3 (fakultativ)Ergänzungen zu Common Lisp
Zürcher Fachhochschule
Status
• Dieser Teil enthält einige Ergänzungen zu Common Lisp
• Für PSPP ist dieser Teil nicht prüfungsrelevant
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 2
Zürcher Fachhochschule
Weniger funktionale Sprachelemente
• Einige Features von Common Lisp dienen eher der prozeduralen oder objektorientierten Programmierung
• Wie die meisten heutigen Programmiersprachen gehört Common Lisp zu den Multiparadigmensprachen
• Einige weitere Merkmale und Sprachelemente von Common Lisp, die wir in PSPP kaum benötigen werden, sind in diesem Foliensatz zusammengestellt
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 3
Zürcher Fachhochschule
Übersicht
• Variablenbindung
• Kontrollstrukturen
• Common Lisp Object System
• Sprache anpassen: Makros
• Speicherverwaltung und Compiler
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 4
Zürcher Fachhochschule
Werte an Symbole binden
• Bereits behandelt: set
• Varianten: setq, setf
• Mehr Infos in der Doku
• Bei funktionalem Programmierstil selten bis gar nicht benötigt
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 5
> (set 'figuren '(quadrat kreis dreieck))(QUADRAT KREIS DREIECK)> (setq figuren '(quadrat kreis dreieck))(QUADRAT KREIS DREIECK)> figuren(QUADRAT KREIS DREIECK)
Zürcher Fachhochschule
Variablenbindung: lexikalisch
• Lexikalischer Gültigkeitsbereich (lexical scoping):In der Funktion oder im let-Block, in dem die Variable definiert wird
• Ausserhalb von Funktionen: ebenfalls lexikalisch(so praktisch nie sinnvoll!)
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 6
> (set 'regular 5)5 > (defun check-regular () regular)CHECK-REGULAR > (check-regular)5 > (let ((regular 6)) (check-regular))5
Zürcher Fachhochschule
Variablenbindung: dynamisch
• Dynamischer Gültigkeitsbereich (dynamic scoping):In Common Lisp special variables genannt
• Global gültig, ausser wenn lokal überschrieben (shadowing)
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 7
> (defvar *special* 5)*SPECIAL*> (defun check-special () *special*)CHECK-SPECIAL> (check-special)5> (let ((*special* 6)) (check-special))6> (check-special)5
Zürcher Fachhochschule
Übersicht
• Variablenbindung
• Kontrollstrukturen
• Common Lisp Object System
• Sprache anpassen: Makros
• Speicherverwaltung und Compiler
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 8
Zürcher Fachhochschule
Schleifen
• Common Lisp kennt verschiedene Schleifentypen:do, dolist, dotimes, ...
• Schleifen sind prozedurale Sprachelemente und in der Regel mit Zuweisung von Werten oder Seiteneffekten verbunden
• Sie werden zum Beispiel eingesetzt, wenn die Performanz einer rekursiven Lösung nicht ausreicht
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 9
> (dotimes (n 20) (format t "*"))********************NIL
Zürcher Fachhochschule
Schleifen
• In einem früheren Beispiel wurde die Fakultätsfunktion mit rekursiven Funktionsaufrufen realisiert
• Iterative Version von fakultaet mit dem Makro dotimes:
> (defun fakultaet (n)(let ((f 1))
(dotimes (i n) (setq f (* f (+ i 1))))f))
FAKULTAET
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 10
Zürcher Fachhochschule
Schleifen
• dotimes, wenn eine Schleife n mal durchlaufen werden soll
• dolist, wenn eine Schleife für alle Elemente einer Liste durchlaufen werden soll:
• do ist ein mächtiges Makro zum Erzeugen von Schleifen, bei denen in jedem Schleifendurchlauf mehrere Variablen angepasst werden müssen
> (dolist (i '(23 76 22 88))(format t "- ~D -" i))
- 23 -- 76 -- 22 -- 88 -NIL
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 11
Zürcher Fachhochschule
Listen
• Listen können auch gemeinsame Teilstrukturen haben
• Der Rest der Liste, also (b c), ist beiden Strukturen gemeinsam
> (setq foo (list 'a 'b 'c))
(A B C)
> (setq bar (cons 'x (cdr foo)))
(X B C)
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 12
Zürcher Fachhochschule
Destruktive Operationen
• Verschiedene Listenoperationen sind destruktiv – sie verändern die als Parameter übergebenen Listen
• Beispiel: nconc ist die destruktive Variante von append
• Solche Funktionen sollten nur eingesetzt werden, wenn es absolut nötig ist (Speicherverbrauch, Performanz)
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 13
> (let ((a '(1 2 3)) (b '(10 11 12))) (nconc a b) a)(1 2 3 10 11 12)
> (let ((a '(1 2 3)) (b '(10 11 12))) (append a b) a)(1 2 3)
Zürcher Fachhochschule
append vs. nconc
• append verbindet Listen nicht-destruktiv: Listenstrukturen werden bei Bedarf werden kopiert
• nconc verbindet Listen destruktiv: Der letzte Zeiger der ersten Liste wird auf die zweite Liste umgebogen
• Die beiden Zeiger einer cons-Zelle können mit rplaca und rplacd auch direkt ersetzt werden
> a(1 2 3 4)
> b(11 12 13)
> (append a b)(1 2 3 4 11 12 13)
> (nconc a b)(1 2 3 4 11 12 13)
> a(1 2 3 4 11 12 13)
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 14
Zürcher Fachhochschule
Mapping Funktionen
• mapcar und maplist wurden bereits erwähnt
• mapc und mapl entsprechen mapcar und maplist, erzeugen aber keine Ausgabeliste
• mapcan und mapcon entsprechen mapcar und maplist, die Funktionsergebnisse werden aber mit nconc (destruktiv) verknüpft
> (mapc #'evenp '(1 2 3))
(1 2 3)
> (mapc #'princ '(1 2 3))
123
(1 2 3)
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 15
Zürcher Fachhochschule
Verzweigungen
• Makros when und unless, wenn nur einer der beiden Zweige benötigt wird:
(if <predicate> <then-part> <else-part> )(when <predicate> <then-part>+ )(unless <predicate> <else-part>+ )
• Zwei weitere Makros case und typecase wählen einen Zweig anhand von Listen möglicher Werte bzw. anhand des Argumenttyps aus
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 16
Zürcher Fachhochschule
Anweisungssequenzen
• prog1 und progn fassen mehrere Anweisungen zusammen
• prog1 gibt als Ergebnis den Wert des ersten Ausdrucks, progn des letzten Ausdrucks der Sequenz zurück
> (prog1 (setq obj-a 'wuerfel)(setq obj-b 'wuerfel)(setq obj-c 'kugel))
WUERFEL
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 17
Zürcher Fachhochschule
Übersicht
• Variablenbindung
• Kontrollstrukturen
• Common Lisp Object System
• Sprache anpassen: Makros
• Speicherverwaltung und Compiler
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 18
Zürcher Fachhochschule
Lisp objektorientiert...
• CLOS steht für Common Lisp Object System
• Es erlaubt objektorientierte Programmierung in Common Lisp
• Wichtigste Bestandteile: Klassen, Instanzen, generische Funktionen, Methoden
• Multiple Vererbung
• Meta-Object Protocol: Metaklassen, die Klassen von Klassen sind
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 19
Zürcher Fachhochschule
Lisp objektorientiert...
> (defclass 3d-point ()((x :reader get-x :writer set-x)(y :reader get-y :writer set-y)(z :reader get-z :writer set-z)))
#<STANDARD-CLASS 3D-POINT>
> (let ((a-point (make-instance '3d-point)))(set-z 3 a-point)(get-z a-point))
3
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 20
Zürcher Fachhochschule
Übersicht
• Variablenbindung
• Kontrollstrukturen
• Common Lisp Object System
• Sprache anpassen: Makros
• Speicherverwaltung und Compiler
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 21
Zürcher Fachhochschule
Makros
• Neben Funktionen gibt es in Lisp auch Makros
• Diese werden zuerst expandiert und dann ausgewertet
• Einführen eigener Sprachkonstrukte
• Sehr flexibel, aber eher für Fortgeschrittene
• Hier nicht weiter betrachtet...
(defmacro my-push (element stack)
`(setq ,stack (cons ,element ,stack)))
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 22
Zürcher Fachhochschule
Makros: Beispiel
• Makro defnet zum Anlegen von Augmented Transition Networks(aus: ATN-Interpreter, G. Burkert, 1993/1994)
• Anwendung in einem Text-Scanner:
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 23
(defnet sentence (sent)(optional*(either (seq (push word :do (push -current- sent))
(either(word "." :test (test-abbrev (car sent))
:do (setq sent (push (test-abbrev (car sent))(cdr sent))))
Zürcher Fachhochschule
Übersicht
• Variablenbindung
• Kontrollstrukturen
• Common Lisp Object System
• Sprache anpassen: Makros
• Speicherverwaltung und Compiler
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 24
Zürcher Fachhochschule
Dynamische Speicherverwaltung
• Man muss sich nicht um die Speicherverwaltung kümmern
• Der Garbage Collector gibt nicht mehr referenzierbareSpeicherzellen frei
(let ((x (list 1 2 3 4 5)))(print x))
• Nach dem Ausführen dieses Ausdrucks ist die Liste nicht mehr zugreifbar, ihr Speicherplatz kann also wieder freigegeben werden
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 25
Zürcher Fachhochschule
Compiler
• Mit Hilfe eines Compilers kann je nach Implementierung direkt Maschinencode oder ein Bytecode erzeugt werden
• Die Wirkungsweise ist stark von der jeweiligen Lisp-Implementierung abhängig
• Mit compile werden einzelne Ausdrücke übersetzt
• Mit compile-file werden ganze Dateien mit Lisp-Code übersetzt
> (defun add1 (n) (1+ n))ADD1> (compile 'add1)ADD1
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 26
Zürcher Fachhochschule
Disassembler
> (disassemble 'add1)
Disassembly of function ADD11 required argument0 optional argumentsNo rest parameterNo keyword parameters3 byte-code instructions:0 (LOAD&PUSH 1)1 (CALLS2 151) ; 1+3 (SKIP&RET 2)NIL
> (disassemble 'add1)
(TWNEI NARGS 4)(MFLR LOC-PC)(BLA .SPSAVECONTEXTVSP)(VPUSH ARG_Z)(LWZ NARGS 331 RNIL)(TWGTI NARGS 0)(LI ARG_Y '1)(LWZ ARG_Z 0 VSP)(BLA .SPRESTORECONTEXT)(MTLR LOC-PC)(BA .SPBUILTIN-PLUS)
(andere Plattform)
pspp • common lisp ergänzungen • gerrit burkert • 10/2019 • 27