использование символьной функции clojure для косвенного вызова функции - PullRequest
26 голосов
/ 09 сентября 2011

Ниже я ожидаю, что я смогу вызывать свою функцию в квадрате косвенно через функцию символа, но она не работает. Что я тут не так делаю:

user=> (defn squared [x] (* x x))
#'user/squared
user=> (squared 2)
4
user=> ((symbol "squared") 2)
nil
user=> ((symbol "user" "squared") 2)
nil
user=> 

1 Ответ

38 голосов
/ 09 сентября 2011

Сам символ не содержит вашу функцию, а имя, которое он называет, делает.

Это говорит: «возьмите содержимое (@ = deref) переменной (resolve), названной символом (symbol), имя которого "squared", и примените его (как функцию) к аргумент 2:

(@(resolve (symbol "squared")) 2)

Здесь написано "возьми вар, названный символом и т. Д.":

((resolve (symbol "squared")) 2)

Оба будут работать, поскольку Vars, когда его просят действовать как функцию, откладывают функции, хранящиеся в них. (Если вы попытаетесь использовать Var как функцию, когда она не связана с функцией, появится ошибка.)

Здесь написано «возьмите символ с именем "squared" и примените его в качестве функции к аргументу 2» - обратите внимание, что сам символ используется в качестве функции:

((symbol "squared") 2)

Теперь символы могут использоваться как функции (они реализуют интерфейс clojure.lang.IFn), но способ, которым они действуют при использовании таким образом, заключается в том, что они ищут себя в своем аргументе, то есть обрабатывают свой аргумент как карту и выполняют поиск внутри него:

('foo {'foo 2})
; is equivalent to
(get {'foo 2} 'foo)

Если аргумент, переданный символу, не имеет смысла для поиска, возвращается nil.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...