Что делают символы Clojure при использовании в качестве функций?

При попытке решить проблему 4Clojure "" Универсальный вычислительный движок", включающий переоценку оценки, я случайно позвонил так:

(apply '/ '(16 8))

а не предполагаемый:

(apply / '(16 8))

У этого был запутанный побочный эффект возвращения 8, который заставлял меня думать, что я испортил свою математику.

Я позже понял свою ошибку после некоторой отладки - я не смог оценить символ /, прежде чем пытаться ее вызвать, и понял, что clojure.lang.Symbol должен реализовать clojure.lang.IFn. Но что делает эта реализация? Все, что я могу сделать, это вернуть nil с одним аргументом или вторым аргументом, если он указан.

Ответ 1

Символы видят себя на карте, как и ключевые слова. См. Реализация символа:

…
122 public Object invoke(Object obj) {
123         return RT.get(obj, this);
124 }
125
126 public Object invoke(Object obj, Object notFound) {
127         return RT.get(obj, this, notFound);
128 }
…

(RT clojure.lang.RT, который делает почти все. "RunTime"?)

В приведенном примере поиск не работает (поскольку 16 не является картой), и поэтому возвращается значение notFound (8).