Как написано в другом посте, я пишу компилятор Shen в Clojure.
Для этого мне нужен макрос / функция, которая получает символ в качестве параметра, и если функция Shen связана с ним, она возвращает функцию, а если символ определен как макрос Clojure, она должна возвращать макрос, поэтому ((function or) true false)
должно выдавать то же самое результат как (or true false)
.
Мой макрос в настоящее время выглядит так:
(defmacro kl/function [x]
(cl/let [fn (symbol (cl/str (name x) "__fnPoF__"))]
(if (function? fn) `(eval ~fn) `(quote ~x))))
Постфикс "__fnPoF__" присутствует из-за двойного пространства имен в Shen. (Значение и функция могут быть назначены одному и тому же символу.)
Моя проблема сейчас в том, что ((function or) true false)
оценивается как ложное, потому что оно оценивается как ('or true false)
, но если я пропущу "цитату" (x
вместо `(quote ~x)
, я получу следующее исключение:
kl=> (function *)
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'kl/*, compiling:(NO_SOURCE_PATH:8)
У кого-нибудь есть идеи, как решить эту проблему?