Подтвердить что ты не робот

Генерация кода Clojure с макросом, содержащим подсказки типа

Я пытаюсь сгенерировать некоторый код Clojure с подсказками типа, однако подсказки типа кажутся исчезающими всякий раз, когда я создаю какой-то код (они также не функционируют при компиляции кода).

например.

`(let [^BufferedImage b (create-buffered-image)] 
   (.getRGB b 0 0))

=> (clojure.core/let [user/b (user/create-buffered-image)] (.getRGB user/b 0 0))

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

Какой правильный способ создать правильные подсказки типа в сгенерированном коде?

4b9b3361

Ответ 1

На этот вопрос есть два ответа. Чтобы ответить на ваш конкретный вопрос: в самом коде, который вы только что опубликовали, ничего не случилось: он работает нормально. (set! *print-meta* true) и повторите попытку, и вы увидите аннотацию метаданных. Обычно это не печатает.

Но, в общем, это неправильный способ сделать что-то из макроса, и у вас скоро появятся проблемы. Помните, что вы не хотите метаданных в формах, которые оценивает макрос, вам нужны метаданные в тех формах, которые генерирует макрос. Таким образом, более точное решение заключается в использовании with-meta для символов или форм, к которым вы хотите присоединить метаданные, или, если они являются предоставленными пользователем формами, вы обычно должны использовать vary-meta, чтобы вы не отбрасывали метаданные, которые они добавили явно. Например,

(defmacro with-image [name & body]
  (let [tagged-name (vary-meta name assoc :tag `BufferedImage)
    `(let [~tagged-name (create-buffered-image)
       [email protected])))

(with-image i (.getRGB i 0 0))