Есть символ +, о котором вы можете поговорить, цитируя его:
user=> '+
+
user=> (class '+)
clojure.lang.Symbol
user=> (resolve '+)
#'clojure.core/+
Таким образом, он разрешается до # '+, который является Var:
user=> (class #'+)
clojure.lang.Var
Var ссылается на объект функции:
user=> (deref #'+)
#<core$_PLUS_ clojure.core$_PLUS_@55a7b0bf>
user=> @#'+
#<core$_PLUS_ clojure.core$_PLUS_@55a7b0bf>
(Знак @ - это просто сокращение для разыменования.) Конечно, обычный способ добраться до функции - не заключать в кавычки символ:
user=> +
#<core$_PLUS_ clojure.core$_PLUS_@55a7b0bf>
Обратите внимание, что лексические привязки - это другой механизм, и они могут скрывать Vars, но вы можете обойти их, явно ссылаясь на Var:
user=> (let [+ -] [(+ 1 2) (@#'+ 1 2)])
[-1 3]
В последнем примере дереф можно даже опустить:
user=> (let [+ -] [(+ 1 2) (#'+ 1 2)])
[-1 3]
Это потому, что Var реализует IFn (интерфейс для функций Clojure), вызывая deref для себя, передавая результат в IFn и делегируя вызов функции этому.
Механизм видимости, используемый при определении частных функций с помощью defn, основан на метаданных символа. Вы можете обойти это, обращаясь непосредственно к Var, как указано выше:
user=> (ns foo)
nil
foo=> (defn- private-function [] :secret)
#'foo/private-function
foo=> (in-ns 'user)
#<Namespace user>
user=> (foo/private-function)
java.lang.IllegalStateException: var: #'foo/private-function is not public (NO_SOURCE_FILE:36)
user=> (#'foo/private-function)
:secret