Кажется, мой ответ работает только в Clojure, а не в ClojureScript. См. другой ответ .
Я думаю, вы можете искать resolve
.
(defn my-simple-eval [expr]
; Cut the function symbol from the arguments
(let [[f & args] (edn/read-string expr)]
; Resolve f to a function then apply the supplied arguments to it
(apply (resolve f) args)))
(my-simple-eval "(+ 1 3)")
=> 4
Аргументы должны быть голыми, чтобы это работало. Если вы хотите разрешить подвыражения, вы можете сделать это рекурсивным:
(defn my-simple-eval-rec [expr]
(letfn [(rec [[f & args]]
(->> args
(map (fn [arg]
(if (list? arg)
(rec arg) ; Process the sub-expr
arg)))
(apply (resolve f))))]
(rec (edn/read-string expr))))
(my-simple-eval-rec "(+ 1 (+ 2 5))")
=> 8
Если этого недостаточно, я не знаю другого способа, кроме использования eval
:
(def a (edn/read-string "(+ 1 3)"))
(eval a)
=> 4
или, если данные доступны во время расширения макросов, вы можете просто обернуть вызов к read-string
, чтобы данные интерпретировались как обычно:
(defmacro my-read-string [expr]
(edn/read-string expr))
(my-read-string "(+ 1 3)")
=> 4