Клоун
| клоун | ||
|---|---|---|
|
| ||
| Разработчики) | ||
|
Ричард Хики https://clojure.org/ | ||
| Главная Информация | ||
| Общие расширения | clj, cljs, cljc, edn и cljr | |
| Парадигма | Функциональный , Мультипарадигмальный язык программирования | |
| Появился в | 2007 г. | |
| Разработано | Рич Хики | |
| Последняя стабильная версия | (2022-03-22) | |
| система типов | динамичный , сильный | |
| Реализации | JVM , CLR , JavaScript | |
| под влиянием | Lisp , ML , Haskell , Erlang Prolog | |
| Операционная система | Мультиплатформа | |
| Лицензия | Публичная лицензия Eclipse | |
Clojure — диалект языка программирования общего назначения Lisp . Особое внимание уделяется функциональной парадигме с целью (помимо прочего) устранения сложности, связанной с параллельным программированием . Clojure можно запускать поверх виртуальной машины Java и виртуальной машины платформы .NET , а также компилировать в JavaScript .
Принципы
Рич Хикки описывает разработку Clojure как поиск языка, который он не смог найти: рабочий лисп по умолчанию, построенный поверх надежной среды, а не собственной платформы, и с учетом параллельного программирования . [ 1 ]
Точно так же объектная ориентация отвергается в принципе, предлагая подход, при котором программы выражаются как применение функций к данным, а не как взаимодействие между изменяемыми сущностями, которые смешивают представление данных и поведение. С другой стороны, такие функции, как создание экземпляров, полиморфизм и интерфейсы, фактически являются частью языка.
Синтаксис
Как и остальная часть семейства Lisp, синтаксис Clojure построен на символических выражениях, которые перед компиляцией преобразуются в структуры данных программой чтения . Выражения характеризуются тем, что они разделены круглыми скобками и их префиксной нотацией, с помощью которой первый член каждого списка вызывается как функция, а остальные члены передаются в качестве аргументов.
Эта особенность, странная для тех, кто привык к наиболее популярным языкам, основанным на синтаксисе языка программирования C, лежит в основе его гибкости. Структуры данных, такие как карты , наборы и векторы , имеют буквальное выражение; они не требуют никакого преобразования при включении в синтаксическое дерево, сгенерированное компилятором. Clojure — это Lisp-1 , и он специально не предназначен для совместимости с другими lisps .
Макрос
Макрос — это фрагмент кода, который принимает другие выражения в качестве аргументов, не оценивая их, преобразуя их перед их вычислением. Это допускает появление «программ, создающих программы»: дополнения к языку — структуры управления потоком — или создание предметно-ориентированного языка . Возможности, в принципе недостижимые в других языковых семьях, не прибегая к разработке компилятора .
Система макросов Clojure очень похожа на Common Lisp , за исключением того, что версия обратной кавычки в Clojure (называемая «синтаксической кавычкой») определяет символы пространством имен, к которому они принадлежат. Это помогает предотвратить непреднамеренный захват, поскольку привязки с уточнением имени запрещены. Можно принудительно раскрыть макрос, который их захватывает, но это должно быть сделано явным образом. Clojure также запрещает повторное связывание глобальных имен в других пространствах имен, которые были импортированы в текущее.
Еще одна особенность синтаксической кавычки заключается в том, что она позволяет использовать систему шаблонов , в которой вы можете указать, какие члены списка должны оцениваться с помощью операторов раскатки (~) и раскавычивания-слияния (~@), что приводит к более кратким макросам и управляемый.
Особенности языка
- Динамическая разработка с оценочной консолью ( REPL: read eval print loop ).
- Представление функций в виде значений, а также предпочтение рекурсии и использование функций более высокого порядка по сравнению с итерацией на основе побочных эффектов .
- Числа произвольной точности и буквальное представление дробей, генерируемых при нецелочисленных делениях.
- Последовательности с ленивым вычислением (элементы последовательности не вычисляются до тех пор, пока они не потребуются, что позволяет представлять потенциально бесконечные множества).
- Интегрированная система постоянных и неизменяемых структур данных.
- Контроль состояния (набор значений, которые сущность может приобрести с течением времени) в ситуациях параллелизма через транзакционные системы, агентов и через локальные привязки .
- Взаимодействие с java : благодаря компиляции в байт - код JVM приложения, написанные на Clojure, могут быть легко интегрированы в серверы приложений или другие среды Java с небольшой дополнительной сложностью. Все возможные интерфейсы на уровне класса, структуры данных и параллелизма реализованы по умолчанию, чтобы свести к минимуму усилия, необходимые для достижения этой переносимости.
Примеры
Привет мир . Обратите внимание, что из-за природы REPL команда печати не требуется .
"Привет, мир!"
Генератор уникальных и последовательных номеров, поддерживающий одновременные вызовы:
( let [i ( atom 0 ) ]
( defn generate-unique-id
"Возвращает другой числовой идентификатор для каждого вызова."
[]
( swap! i inc )))
Анонимный подкласс java.io.Writer, который никуда не записывает, и макрос, который использует его, чтобы заглушить все выражения, оцениваемые с его помощью.
( def bit-bucket-writer
( proxy [java.io.Writer] []
( write [buf] nil )
( close [] nil )
( flush [] nil )))
( defmacro noprint
"Вычисляет данное выражение со всеми отпечатками *out* muted."
[& forms]
` ( binding [*out* bit-bucket-writer]
~@forms ))
( noprint
( println "Здравствуйте, никто!" ))
В этом примере десять потоков управляют общей структурой данных, которая состоит из ста векторов, содержащих десять последовательных начальных уникальных номеров. Каждый поток выбирает две случайные позиции в двух случайных векторах и меняет их местами. Все изменения векторов выполняются внутри транзакций с использованием системы транзакционной памяти программного обеспечения Clojure . Вот почему даже после тысячи итераций ни одно число не потеряется.
( defn run [nvecs nitems nthreads niters]
( let [vec-refs ( vec ( map ( comp ref vec )
( partition nitems ( range ( * nvecs nitems )))))
swap #( let [v1 ( rand-int nvecs )
v2 ( rand-int nvecs )
i1 ( rand-int nvecs )
i2 ( rand-int nitems ) ]
( dosync
( let [temp ( nth @ ( vec-refs v1 ) i1 ) ]
( alter ( vec-refs v1 ) assoc i1 ( nth @ ( vec-refs v2 ) i2 ))
( alter ( vec-refs v2 ) assoc i2 temp ))))
report #( do
( prn ( map deref vec-refs ))
( println "Distinct:"
( count ( отличный ( применить concat ( map deref vec-refs )))))) ]
( отчет )
( dorun ( применить pcalls ( повторить nthreads #( dotimes [_ niters] ( swap )))))
( отчет )))
( прогон 100 10 10 100000 )
Вывод предыдущего примера:
( [0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17 18 19] ...
[990 991 992 993 994 995 996 997 998 999] )
Отличительные: 1000
( [382 318 466 963 619 22 21 273 45 596] [808 639 804 471 394 904 952 75 289 778] ...
[484 216 622 139 651 592 379 228 242 355] 00
Различие: 00
Библиография
- Хэллоуэй, Стюарт (28 мая 2009 г.), Programming Clojure (1-е издание), Pragmatic Bookshelf , стр. 304 , ISBN 1934356336 .
- ВандерХарт, Люк (31 декабря 2009 г.), Практический Clojure (1-е издание), Apress , с. 350, ISBN 1430272317 , заархивировано из оригинала 17 сентября 2010 г. , получено 10 февраля 2010 г.
- Ратор, Амит (декабрь 2009 г.), Clojure в действии (1-е издание), Мэннинг , с. 475, ISBN 9781935182597 .
- Фогус, Майкл; Хаузер, Крис (январь 2010 г.), The Joy of Clojure (1-е издание), Manning , p. 300, ISBN 9781935182641 .
Внешние ссылки
- Главная страница Clojure
- Репозиторий кода Clojure на GitHub
- Обзор Clojure
- видеоуроки
- clojuredocs.org — документация и примеры от сообщества
- clojure-doc.org — управляемый сообществом сайт документации по языку программирования Clojure.
Ссылки
- ^ «Основные принципы» . Рич Хики (на английском языке) . Проверено 17 октября 2008 г., здесь нет парадигмы .