Значение # в clojure - PullRequest
       4

Значение # в clojure

2 голосов
/ 08 марта 2019

В clojure вы можете создавать анонимные функции, используя #

, например,

#(+ % 1) 

- это функция, которая принимает параметр и добавляет к нему 1.

Но мы также должны использовать # для регулярных выражений, например

(clojure.string/split "hi, buddy" #",")

Связаны ли эти два #?

Ответы [ 4 ]

7 голосов
/ 08 марта 2019

Существуют также наборы #{}, конструкторы полностью квалифицированных имен классов #my.klass_or_type_or_record[:a :b :c], моменты времени #inst "yyyy-mm-ddThh:mm:ss.fff+hh:mm" и некоторые другие .

Они связаны в том смысле, что в этих случаях # запускает последовательность, распознаваемую читателем clojure , который отправляет каждый такой экземпляр соответствующему читателю. руководство подробнее об этом.

Я думаю, что это соглашение существует, чтобы сократить количество различных синтаксисов до одного и тем самым упростить читателю.

3 голосов
/ 08 марта 2019

Эти два использования не имеют (прямой) связи.

В Clojure, когда вы видите символ #, это гигантский ключ, который вы "говорите" с Clojure Reader , а не с Clojure Составитель . Смотрите полную документацию по Reader здесь: https://clojure.org/reference/reader.

Reader отвечает за преобразование простого текста из исходного файла в набор структур данных. Например, сравнивая Clojure с Java, мы имеем

; Clojure          ; Java
"Hello"      =>    new String( "Hello" )

и

[ "Goodbye" "cruel" "world!" ]   ; Clojure vector of 3 strings

; Java ArrayList of 3 strings
var msg = new ArrayList<String>();
msg.add( "Goodbye" );
msg.add( "cruel" );
msg.add( "world!" );

Аналогичным образом, существуют ярлыки, которые Reader распознает даже в исходном коде Clojure (до того, как компилятор преобразует его в байт-код Java), просто чтобы сэкономить время при вводе текста. Эти «макросы чтения» преобразуются из исходного кода «краткой формы» в «стандартный Clojure» даже до запуска компилятора Clojure. Например:

@my-atom                       =>   (deref my-atom)    ; not using `#`
#'map                          =>   (var map)
#{ 1 2 3 }                     =>   (hash-set 1 2 3)
#_(launch-missiles 12.3 45.6)  =>   ``                 ; i.e. "nothing"
#(+ 1 %)                       =>   (fn [x] (+ 1 x))

и так далее. Как показывает оператор @ или deref, не во всех макросах Reader используется символ # (hash / pound / octothorpe). Обратите внимание, что даже в случае векторного литерала:

[ "Goodbye" "cruel" "world!" ]

Читатель создает результат, как если бы вы набрали:

(vector "Goodbye" "cruel" "world!" )
0 голосов
/ 10 марта 2019

Другие Лиспы имеют соответствующие программируемые читатели и, следовательно, читают макросы.У Clojure на самом деле нет программируемого считывателя - пользователи не могут легко добавлять новые макросы чтения - но система Clojure внутренне использует макросы чтения.Макрос # read - это макрос dispatch , символ, следующий за #, является ключом в следующей таблице макроса чтения.

Так что да, # действительно что-то значит;но он такой глубокий и отвратительный, что тебе не обязательно знать это.

0 голосов
/ 08 марта 2019

Эти два # связаны?

Нет, это не так.Буква # используется по-разному.Некоторые из них вы уже упомянули: это анонимная функция и шаблон регулярных выражений.Вот еще несколько случаев:

  • Добавление выражения к #_ просто стирает его из компилятора, так как оно никогда не записывалось.Например: #_(/ 0 0) будет игнорироваться на уровне читателя, поэтому исключение не появится.

  • Пометка примитивов для приведения их к сложным типам, например, #inst "2019-03-09" создаст экземплярjava.util.Date класса.Есть также #uuid и другие встроенные теги.Вы можете зарегистрировать свои собственные.

  • Пометка обычных карт для приведения их к типам карт, например, #project.models/User {:name "John" :age 42} создаст карту, объявленную как (defrecord User ...).

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