it-swarm.com.ru

Clojure против других Lisps

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

Я прочитал несколько книг по Clojure ( Программирование Clojure , Практическое Clojure , Радость Clojure , и издание Manning Early Access Clojure in Action ) и я думаю, что это фантастический язык. В настоящее время я читаю Let Over Lambda , который в основном имеет дело с макросами Common LISP, и это тоже очень интересный язык.

Я не эксперт по LISP (скорее новичок), но это семейство языков очаровывает меня, как и функциональное программирование в целом.

Преимущества Clojure (и недостатки "других"):

  • Работает на JVM.

    • JVM - это очень стабильная, высокопроизводительная языковая среда, которая вполне соответствует мечте Sun "Пиши один раз, беги [почти] где угодно". Я могу написать код на своем Macbook Pro, скомпилировать его в исполняемый файл JAR, а затем запустить его в Linux и Microsoft Windows с небольшим дополнительным тестированием.

    • JVM (Hotspot и другие) поддерживает высококачественную сборку мусора и очень эффективную своевременную компиляцию и оптимизацию. Там, где всего несколько лет назад я писал все, что нужно было быстро запускать в C, сейчас я без колебаний делаю это в Java.

    • Стандартная, простая, многопоточная модель. Есть ли в Common LISP стандартный пакет многопоточности?

    • Разбивает монотонность всех этих скобок с помощью [], {} и #{}, хотя эксперты Common LISP, вероятно, скажут мне, что с помощью макросов читателя вы можете добавить их в CL.

Недостатки Clojure :

  • Работает на JVM.
    • Нет хвостовой рекурсии или продолжений. Поддерживает ли Common LISP продолжение? Схема требует поддержки обоих, я считаю.

Преимущества других (в частности Common LISP) (и недостатки Clojure):

  • Пользовательские макросы читателя.

  • Другие преимущества?

Мысли? Другие отличия?

85
Ralph

Мой личный список причин, по которым я предпочел Clojure другим Лиспам (с. Я все еще думаю, что все Лиспы великолепны!)

  • Работает на JVM - следовательно, получает автоматический доступ к фантастическим разработкам в самой JVM (усовершенствованные алгоритмы сборки мусора, оптимизация JIT HotSpot и т.д.)

  • Очень хорошая совместимость Java - обеспечивает совместимость с огромным количеством библиотек в языковой экосистеме Java/JVM. Я использовал Clojure в качестве "связующего" языка для соединения различных библиотек Java с хорошим эффектом. Поскольку я также разрабатываю много кода Java, для меня полезно, чтобы Clojure хорошо интегрировался с инструментами Java (например, я использую плагин Maven, Eclipse с плагином против часовой стрелки для моей разработки Clojure)

  • Хороший синтаксис для векторов [1 2 3], карт {:bob 10, :jane 15} и наборов #{"a" "b" "c"} - я рассматриваю эти довольно важные инструменты для современного программирования (в дополнение к спискам, конечно!)

  • Мне лично нравится использовать квадратные скобки для обязательных форм: например, (defn foo [a b] (+ a b)) - Я думаю, это делает код немного понятнее для чтения.

  • Акцент на ленивое, функциональное программирование с постоянными неизменяемыми структурами данных - в частности, вся базовая библиотека Clojure предназначена для поддержки этого по умолчанию

  • Отличная реализация STM для многоядерного параллелизма. Я полагаю, что Clojure имеет лучшую историю параллелизма из всех языков на данный момент (см. Это видео для более детальной проработки самого Рича Хики )

  • Это LISP-1 (как Scheme), который я лично предпочитаю (я думаю, что в функциональном языке имеет смысл хранить функции и данные в одном и том же пространстве имен)

47
mikera

Важным отличием между Clojure и Common LISP является то, что Clojure больше предписывает функциональное программирование. Философия Clojure, идиомы и в некоторой степени язык/библиотеки настоятельно поощряют, а иногда и настаивают на том, чтобы вы программировали функциональным образом (без побочных эффектов, без изменяемого состояния).

Common LISP определенно поддерживает функциональное программирование, но также допускает изменяемое состояние и императивное программирование.

Конечно, есть ряд преимуществ для функционального программирования, в области параллелизма и других. Но при прочих равных условиях также хорошо иметь выбор, какой подход вы хотите использовать для каждой ситуации. Clojure не полностью запрещает императивное программирование, но он менее приспособлен к этому стилю, чем Common LISP.

24
Charlie Flowers

Помните, что Clojure - это язык и реализация (обычно в JVM). Common LISP - это язык с более чем десятью различными реализациями. Таким образом, у нас есть несоответствие категории прямо здесь. Например, вы можете сравнить Clojure с SBCL.

В общем-то:

  • версия Common LISP работает на JVM: ABCL

  • большинство других реализаций Common LISP не

  • большинство реализаций CL имеют многозадачные возможности, библиотека предоставляет общий интерфейс

  • Общий LISP имеет синтаксис для массивов. Синтаксис для других типов данных может быть написан пользователем и предоставлен различными библиотеками.

  • Common LISP не поддерживает ни оптимизацию хвостовых вызовов, ни продолжения. Реализации предоставляют TCO, а библиотеки предоставляют некоторую форму продолжений.

22
Rainer Joswig

Вот хорошее видео с сравнение Scheme (в основном Racket) и Clojure .

Справедливости ради, у Racket есть синтаксический сахар (дополнительные средства чтения) и для типов данных (#hash, #, квадратные скобки и т.д.)

Кроме того, единственный способ сделать правильный вызов Clojure - это использовать recur, что является недостатком компиляции в JVM.

Обратите внимание, что recur - это единственная конструкция, не использующая стек, в Clojure. Оптимизация хвостовых вызовов отсутствует, и использование самостоятельных вызовов для зацикливания неизвестных границ не рекомендуется. recur является функциональным, и его использование в хвостовой позиции проверяется компилятором. ( Специальные формы ).

10
Daniil