Динамические макросы в Common-Lisp - когда и как использовать - PullRequest
0 голосов
/ 12 ноября 2018

В моем предыдущем вопросе, на который @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))))))))

Мой вопрос: запрещает ли использование макроса в макросе быть динамическим? (Полагаю, да ... поскольку вызов макроса в определении макроса должен выполняться перед компиляцией, не так ли? Или нет?).

А когда использовать статическое или динамическое макрорешение? - Конечно, если данные известны только во время выполнения, нужен динамический макрос, не так ли? Каковы лучшие практики?

1 Ответ

0 голосов
/ 12 ноября 2018

Вы меня неправильно поняли.

Когда я сказал «статический» против «динамический», я говорил о том, известны ли переменные , связанные макросом, во время компиляции («статический») илитолько во время выполнения («динамический»).

Вообще говоря, следует придерживаться «статического», потому что он создает более читаемый код.Единственная ситуация, когда требуется «динамический», - это создание DSL («предметно-ориентированный язык»).

Использование «макроса в макросе» является полностью ортогональным вопросом.Всегда можно сделать это (если все сделано правильно).

...