Ответ 1
(defmacro defn-with-str [string args & body]
`(defn ~(symbol string) ~args [email protected]))
(defn-with-str "print-string" [k] (println k))
(print-string "lol")
Я хотел бы сделать это (в REPL или в любом месте)
(defn (symbol "print-string") [k] (println k))
а затем можно сделать
(print-string "lol")
Или, если есть какой-либо другой способ создать defn из пользовательских строк в макросах, можете ли вы подтолкнуть меня в правильном направлении?
(defmacro defn-with-str [string args & body]
`(defn ~(symbol string) ~args [email protected]))
(defn-with-str "print-string" [k] (println k))
(print-string "lol")
dnolen solution работает в момент макрорасширения, Брайан Карпер во время чтения. Теперь, здесь один для времени выполнения:
(intern *ns* (symbol "a") (fn [k] (println k)))
Мне нравится dnolen answer better, но вы тоже можете это сделать:
(defn #=(symbol "print-string") [k] (println k))
#=()
оценивается во время чтения. Я не знаю, насколько стабильной является функция Clojure, я бы не стал полагаться на нее, чтобы она не изменилась в будущем. Макросы - это то, как я это сделаю.
FYI - dnolen ответ будет работать только для буквенных строк, а не для строк в переменных def'd или let'd.
(defmacro defn-with-str [string args и body] `(defn ~ (символьная строка) ~ args ~ @body))
(def hisym "привет" ) (defn-with-str hisym [] (println "hi" ))
Теперь у вас есть функция, называемая "hisym"
(hi) → java.lang.Exception: невозможно разрешить символ: привет в этом контексте (NO_SOURCE_FILE: 6) (hisym) → печатает "привет"
Чтобы избежать этого, eval строку имени функции в макросе
(defmacro defn-with-str [string args & body]
`(defn ~(symbol (eval string)) ~args [email protected]))