Цель моего вопроса не в том, чтобы развязать пламенную войну, а в том, чтобы определить, при каких обстоятельствах каждый язык является «лучшим инструментом для работы».
Я прочитал несколько книг по Clojure ( Programming Clojure , Practical Clojure , The Joy of Clojure и Manning Early Access edition Clojure in Action ), и я считаю, что это фантастический язык. В настоящее время я читаю Let Over Lambda, который в основном имеет дело с макросами Common Lisp, и это тоже очень интересный язык.
Я не эксперт по Лисп (скорее новичок), но это семейство языков очаровывает меня, как и функциональное программирование в целом.
Преимущества Clojure (и недостатки «других»):
Работает на JVM.
JVM - это очень стабильная, высокопроизводительная языковая среда, которая вполне соответствует мечте Sun: «Напиши один раз, запусти [почти] где угодно». Я могу написать код на своем Macbook Pro, скомпилировать его в исполняемый файл JAR, а затем запустить его в Linux и Microsoft Windows с небольшим дополнительным тестированием.
(Hotspot и др.) JVM поддерживает высококачественную сборку мусора и очень производительную своевременную компиляцию и оптимизацию. Если всего несколько лет назад я написал все, что должно было работать быстро, на C, теперь я без колебаний делаю это на Java.
Стандартная, простая, многопоточная модель. Есть ли в Common Lisp стандартный пакет многопоточности?
Перерывы однообразия всех этих скобок с
[]
,{}
и#{}
, хотя эксперты Common Lisp, вероятно , сказать мне , что с чтением макросами, вы можете добавить их к CL.
Недостатки Clojure :
- Работает на JVM.
- Никакой хвостовой рекурсии или продолжений. Поддерживает ли Common Lisp продолжения? Я считаю, что схема требует поддержки обоих.
Преимущества других (в частности Common Lisp) (и недостатки Clojure):
Макросы считывателя, определяемые пользователем.
Другие преимущества?
Мысли? Другие отличия?
Ответы:
Мой личный список причин, по которым я предпочитаю Clojure другим Лиспам (ps Я по-прежнему считаю, что все Лиспы великолепны!):
Работает на JVM - следовательно, получает автоматический доступ к фантастической инженерии в самой JVM (расширенные алгоритмы сборки мусора, оптимизация HotSpot JIT и т. Д.)
Очень хорошая совместимость с Java - обеспечивает совместимость с огромным набором библиотек в экосистеме языка Java / JVM. Я использовал Clojure в качестве «связующего» языка для соединения различных библиотек Java с хорошим эффектом. Поскольку я также занимаюсь разработкой большого количества Java-кода, для меня полезно, что Clojure хорошо интегрируется с инструментами Java (например, я использую Maven, Eclipse с плагином Counterclockwise для моей разработки Clojure)
Хороший синтаксис для векторов
[1 2 3]
, карт{:bob 10, :jane 15}
и множеств#{"a" "b" "c"}
- я считаю эти инструменты довольно важными для современного программирования (конечно, помимо списков!)Мне лично нравится использование квадратных скобок для привязки форм: например
(defn foo [a b] (+ a b))
- я думаю, что это делает код более понятным для чтения.Упор на ленивое функциональное программирование с постоянными неизменяемыми структурами данных - в частности, вся базовая библиотека Clojure предназначена для поддержки этого по умолчанию.
Отличная реализация STM для многоядерного параллелизма. Я считаю, что у Clojure лучшая история параллелизма среди всех языков на данный момент (см. Это видео, чтобы узнать больше, написанное самим Ричем Хики )
Это Lisp-1 (например, Scheme), который я лично предпочитаю (я думаю, что на функциональном языке имеет смысл хранить функции и данные в одном пространстве имен)
источник
Имейте в виду, что Clojure - это язык и реализация (обычно на JVM). Common Lisp - это язык с более чем десятью различными реализациями. Итак, мы имеем здесь несоответствие категорий. Например, вы можете сравнить Clojure с SBCL.
В общем-то:
версия Common Lisp работает на JVM: ABCL
большинство других реализаций Common Lisp не
большинство реализаций CL имеют возможности многозадачности, библиотека предоставляет общий интерфейс
Common Lisp имеет синтаксис для массивов. Синтаксис для других типов данных может быть написан пользователем и предоставляется различными библиотеками.
Common Lisp не поддерживает ни оптимизацию хвостового вызова, ни продолжения. Реализации обеспечивают совокупную стоимость владения, а библиотеки обеспечивают некоторую форму продолжения.
источник
Важное различие между Clojure и Common Lisp заключается в том, что Clojure более предписывает функциональное программирование. Философия, идиомы Clojure и, в некоторой степени, язык / библиотеки настоятельно поощряют, а иногда и настаивают на том, чтобы вы программировали функционально (без побочных эффектов, без изменяемого состояния).
Common Lisp определенно поддерживает функциональное программирование, но также допускает изменяемое состояние и императивное программирование.
Конечно, у функционального программирования есть ряд преимуществ в области параллелизма и других аспектах. Но при прочих равных хорошо иметь выбор, какой подход вы хотите использовать для каждой ситуации. Clojure не запрещает полностью императивное программирование, но он менее приспособлен к этому стилю, чем Common Lisp.
источник
Вот хорошее видео со сравнением Scheme (в основном Racket) и Clojure .
Честно говоря, в Racket есть синтаксический сахар (дополнительный материал для чтения) для типов данных (#hash, #, квадратные скобки и т. Д.)
Кроме того, единственный способ сделать правильный хвостовой вызов Clojure - использовать
recur
, это обратная сторона компиляции в JVM.источник
trampoline
для хвостовых криков.