程序代写代做代考 ;;;; Uebungen zu Makros

;;;; 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 ) speziell behandelt und als
;;; 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 (rest 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?