оценить список в давности на clojure - PullRequest
4 голосов
/ 29 декабря 2011

Моя проблема в следующем, я пытаюсь оценить список с некоторыми переменными, используя let для присвоения значений этим переменным

, если я делаю (def a (list * 'x 'y)) и (let [x 3 y 3] (eval a)) У меня есть CompilerException java.lang.RuntimeException: Невозможно разрешить символ: x в этом контексте, компилируя: (NO_SOURCE_PATH: 6)

, но если я запускаю (def x 4) (def y 4) и (eval a), у меня есть 16, в любом случае, если я запускаю снова (let [x 3 y 3] (eval a))снова у меня есть 16,

существует метод для правильного связывания x и y и проверки списка?

ty!

Ответы [ 3 ]

5 голосов
/ 29 декабря 2011

let определяет лексически привязанные привязки, которые недоступны из тела функции eval. Это ничем не отличается от любой другой функции. Однако привязки, созданные с помощью def, доступны, потому что они являются глобальными пространствами имен. Все функции имеют доступ к глобальным переменным пространства имен, если они общедоступны.

3 голосов
/ 29 декабря 2011
(def ^:dynamic x 4) (def ^:dynamic y 4)
user=> (binding [x 3 y 3] (eval a))
9
user=> (eval a)
16
2 голосов
/ 29 декабря 2011

Ну, вы также можете eval выражение let, посмотрите, если это то, что вам нужно:

(eval '(let [x 3 y 3] (* x y)))

РЕДАКТИРОВАТЬ:

Согласно комментариям, это будет работать для вашего случая:

(def a (list (list * 'x 'y)))
(eval (concat '(let [x 3 y 3]) a))

Еще лучше, используйте квазицитирование:

(def a (list * 'x 'y))
(eval `(let ~'[x 3 y 3] ~a))
...