В моем предыдущем вопросе, на который @sds ответил очень хорошо,
Как обернуть и выполнить s-выражение для lisp другим s-выражением?
Мы подошли к теме динамических и статических макросов.
Статическое решение моей with-open-files
макропроблемы @sds было:
(defmacro with-open-files ((streams file-names &rest options &key &allow-other-keys) &body body)
(if (and streams file-names)
`(with-open-file (,(pop streams) ,(pop file-names) ,@options)
(with-open-files (,streams ,file-names ,@options)
,@body))
`(progn ,@body)))
И его динамическое решение:
(defmacro with-open-files-d ((streams file-names &rest options &key &allow-other-keys) &body body)
(let ((sv (gensym "STREAMS-"))
(ab (gensym "ABORT-"))
(op (gensym "OPTIONS-")))
`(let ((,sv ,streams)
(,ab t)
(,op (list ,@options)))
(progv ,sv (mapcar (lambda (fn) (apply #'open fn op)) ,file-names)
(unwind-protect (multiple-value-prog1 (progn ,@body) (setq ,ab nil))
(dolist (s ,sv)
(when s
(close s :abort ,ab))))))))
Мой вопрос: запрещает ли использование макроса в макросе быть динамическим? (Полагаю, да ... поскольку вызов макроса в определении макроса должен выполняться перед компиляцией, не так ли? Или нет?).
А когда использовать статическое или динамическое макрорешение? - Конечно, если данные известны только во время выполнения, нужен динамический макрос, не так ли?
Каковы лучшие практики?