Как использовать разрешенную переменную в clojure [duplicate]

В основном в Mysql, эти типы идентификаторов используются в запросах `, ", ' и ().

  1. " или ' используйте для включения строки как значения "26-01-2014 00:00:00" или '26-01-2014 00:00:00'. Этот идентификатор используется только для строковой неагрегатной функции, такой как now() or sum ,max и т. Д.
  2. ` использовать для включения таблицы таблицы или таблицы, например. выберите column_name из table_name, где id = '2'
  3. () используются только для того, чтобы просто заключить части запроса, например. выберите column_name из table_name где (id = '2' и gender = 'male') или name = 'rakesh'.
36
задан Roly 10 February 2014 в 12:38
поделиться

3 ответа

Есть символ +, о котором вы можете говорить, цитируя его:

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>

(Знак @ является только сокращением для deref.) Конечно, обычный способ добраться до функции - не цитировать символ:

user=> +
#<core$_PLUS_ clojure.core$_PLUS_@55a7b0bf>

Обратите внимание, что лексические привязки являются другим механизмом, и они могут теневые Vars, но вы можете обойти их, обратившись к Var явно:

user=> (let [+ -] [(+ 1 2) (@#'+ 1 2)])
[-1 3]

В этом последнем примере deref может даже быть left:

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
59
ответ дан Jouni K. Seppänen 1 September 2018 в 08:22
поделиться

Этот ответ не сильно отличается от других, он просто не предполагает, что вы изначально хотите изучить несколько новых функций и понятий, чтобы понять, что происходит:

  1. + это символ, расположенный в clojure.core, который по умолчанию доступен для вашего кода.
  2. Когда вы используете в своем коде без каких-либо очень продвинутых намерений, например, цитируя его или обнаруживая его класс, clojure будет искать Вар, на который он указывает.
  3. Если этот Var является функцией, когда + используется в позиции заголовка списка, clojure попытается вызвать эту функцию (NullPointerException, если этот Var не указал на функцию). Если в качестве аргумента используется другая функция, эта функция может сделать то же самое, чтобы вызвать ее. Вот как работает вызов функции.

дополнительные комментарии для округления:

Большинство или все языки используют таблицы символов. Будучи несколько динамичным языком, Clojure использует этот дополнительный слой косвенности (функция Symbol → Var →, а не только функция Symbol →), так что динамическое переписывание, какая функция привязана к тому или иному символу, является более выполнимой и элегантной, и это иногда источник любопытства для начинающих.

Поскольку другие ответы несколько чрезмерно подчеркнуты, вы можете в противном случае выполнить причудливый материал , как и цитату ('+), чтобы избежать его оценки, или даже проверить его с помощью class и / или resolve, как будто вы заинтересованы в том, чтобы проверить, что это (class), или какое пространство имён находится (resolve). Вы также можете вытолкнуть в пункте var, через пункты var или #'. Обычно вы делаете эти причудливые вещи, если пишете макросы или если вы очень экспериментально настроены, особенно при работе в repl; в зависимости от того, в каком стиле вы пишете свои макросы, вы можете на самом деле довольно много цитировать в них.

и причудливая иллюстрация для экстра-исследовательского человека:

Будучи несколько гибким языком, clojure предоставляет api для использования функции Symbol → Var → самостоятельно. Обычно вы никогда не делали этого только для использования функции, потому что, очевидно, это было бы скучно и избыточно, но оно может быть использовано здесь для иллюстрации процесса:

(deref (resolve '+))

А именно, первый символ разрешенному его Вар, тогда вещь, на которую указывает Вар, прибывает. Это просто иллюстрирует двухэтапный процесс для получения функции (функция «Символ → Вар →)), которая происходит за кулисами. Надеюсь, вы избежали чтения этой дополнительной части.


TL; DR

ответ на исходный вопрос просто: Да.

3
ответ дан matanster 1 September 2018 в 08:22
поделиться

См. документацию для пространств имен :

Пространства имен - это отображения из простых (неквалифицированных) символов в Vars и / или классы. Vars может быть интернирован в пространстве имен, используя def или любой из его вариантов, и в этом случае у них есть простой символ для имени и ссылки на их содержащее пространство имен, а пространство имен отображает этот символ в тот же var. Пространство имен также может содержать сопоставления из символов в vars, интернированные в других пространствах имен, с использованием ссылки или использования или из символов в объекты класса с помощью импорта.

Таким образом, в основном ваши шаги 1 и 2 унифицированы : пространства имен - это таблицы символов.

И в отношении шага 3: Мне нравится определение переменных, что они являются комбинациями имен значений. Символ - это имя переменной, и ее оценка приведет к его значению.

7
ответ дан Rörd 1 September 2018 в 08:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: