;;;; Uebungen zu Makros
;;; Aufgabe 1
;;; Erklären Sie den Unterschied zwischen
(+ 1 2)
;; und
‘(+ 1 2)
;;; sowie zwischen
‘(expt 2 3)
;; und
(list expt 2 3)
;;; Aufgabe 2
;;; Wie funktioniert das folgende Makro?
;;; Erklaeren Sie dies kurz anhand einiger Beispiele
;;;
;;; Hinweis: Benutzen Sie macroexpand, um das Makro zu verstehen!
(defmacro power (x n)
`(* ,@(loop repeat n collect x)))
;;; Warum ist dieses Makro keine gute Idee?
;;; Hinweis: Was passiert beim Aufruf
(let ((x 2)
(y 5))
(power x y))
;;; Aufgabe 3
;;; Schreiben Sie ein Makro zur Iteration ueber Listen
;;; mit folgender Syntax:
;; (for-each (
;;
;;; Hinweise:
;;; * Starten Sie mit einer Beispielexpansion
;;;
;;; (for-each (x (list 1 2 3))
;;; (print x))
;;;
;;; koennte etwa folgenden Code generieren
;;;
(let ((list-var-123 (list 1 2 3)))
(loop
(when (null list-var-123)
(return))
(let ((x (first list-var-123)))
(print x))
(setf list-var-123 (rest list-var-123))))
;;;
;;; * Schreiben Sie eine Funktion translate,
(defun translate (var list-expr &rest body)
;;
)
;;; die diese Uebersetzung * automatisch macht, d.h.
;;; (translate x (list 1 2 3) (print x))
;;; liefert den obigen code zurueck
;;;
;;; * Benutzen Sie translate, um das Makro for-each zu definieren
;;; Aufgabe 4
;;; Erweitern Sie das Makro aus Aufg. 3, so dass Listen-Ausdruecke der
;;; Form (range
;;; Integer-Intervalle interpretiert werden, z.B.
;;; (for-each (x (range 0 10))
;;; (print x))
;;;
;;; Achtung:
;;;
;;; * range ist damit ein Keyword des Makros und kommt in der
;;; Expansion nicht mehr vor!
;;;
;;; * Es soll keine Liste generiert werden, um das Intervall (zur
;;; Laufzeit) darzustellen!
;;; Aufgabe 5
;;; Definieren Sie eine alternative operationale Semantik, die List
;;; comprehensions in ein iteratives Programm {\”u}bersetzt.
;;; D.h. der Aufruf
;;; (list-comp (* n n)
;;; (<- n
;;; (evenp n))
;;; k{\”o}nnte etwa wie folgt {\”u}bersetzt werden
;;; (let ((result-123 ()))
;;; (do ((list-123
;;; ((null list-123))
;;; (let ((n (first list-123)))
;;; (when (evenp n)
;;; (push (* n n) result-123))))
;;; (reverse result-123))
;;;
;;; Hinweis: Ueberlegen Sie auch kompliziertere Beispiele. Wie saehe
;;; Ihre Uebersetzung aus, wenn mehrere Generator-Ausdruecke
;;; vorkommen?
;;;
;;; Implementieren Sie Ihre Uebersetzung als Common Lisp Makro.
;;; Aufgabe 6
;;; Finden Sie weitere Beispiele fuer DSLs in Common Lisp und
;;; erklaeren Sie kurz wozu diese dienen.
;;;
;;; Hinweis: Was ist z.B. mit dem loop Makro und CLOS, dem Common Lisp
;;; Object System?