В Clojure против других шепелявит [закрыт]


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

Я прочитал несколько книг о Clojure (Программирование В Clojure,Практический Clojure,радость Clojure, и издание раннего доступа Мэннинга Clojure в действие), и я думаю, что это фантастический язык. Я сейчас читаю Пусть Лямбда который в основном имеет дело с макросами Common Lisp, и это тоже очень интересный язык.

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

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

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

    • JVM очень стабилизированный, высокопроизводительный язык окружающая среда, которая довольно хорошо соответствует мечте Солнца "написать один раз, запустить [почти] в любом месте". Я могу написать код на своем Macbook Pro, скомпилировать его в исполняемый файл JAR, а затем запустить его на Linux и Microsoft Windows с небольшим дополнительным тестированием.

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

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

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

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

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

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

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

  • другой преимущества?

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

4 78

4 ответа:

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

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

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

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

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

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

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

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

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

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

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

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

в целом:

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

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

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

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

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

вот хорошее видео с сравнение схемы (в основном ракетки) и Clojure.

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

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

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