Как сделать определения во время расширения макроса Clojure - PullRequest
2 голосов
/ 13 января 2012

Мне кажется, я понимаю, что во время расширения макроса у макроса нет доступа к вещам, к которым имеет доступ функция, потому что расширение происходит до времени компиляции.

Но у меня возникают проблемы с пониманием того, каквыполнять проверки во время расширения макроса.

Например:

(defn gen-class [cl-nam]
    (fn [cmd & args]
        (condp = cmd
            :name (name cl-nam))))

(defmacro defnclass [cl-nam]
    `(def ~cl-nam (gen-class '~cl-nam)))

Я хотел бы проверить, что cl-nam не является последовательностью.Я хотел бы использовать счетчик и узнать, что его длина равна> 1.

Я понимаю, что могу заключить в кавычки println в следующем макросе, чтобы получить сообщение о времени расширения.

(defmacro defnclass_info [cl-nam]
    `(do
        ~(println cl-nam)
        (def ~cl-nam (gen-class '~cl-nam))))

Но я не уверен, как проверить, что было передано для cl-nam.

Я читаю много описаний макросов Clojure из нескольких книг, и я в замешательстве.Спасибо.

1 Ответ

5 голосов
/ 13 января 2012

Макрос - это на самом деле просто функция.

(defmacro defnclass-info
  [cl-name]
  (when (seq? cl-name)
    (throw (Exception. "cl-name must not be a sequence")))
  `(def ~cl-name (gen-class '~cl-name)))

Редактировать: Можно также переключать поведение и рекурсивно вызывать макрос снова для всего списка.Что вы делаете, зависит от ваших требований.

(defmacro defnclass-info
  [cl-name]
  (if (seq? cl-name)
    `(do ~@(for [cn cl-name] `(defnclass-info ~cn)))
    `(def ~cl-name (gen-class '~cl-name))))

Расширение макроса - это то, что возвращает «функция».Таким образом, вы имеете полную гибкость в отношении того, что вы делаете с аргументами макроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...