Перенос кода Common Lisp на Clojure

Насколько практично переносить приложение Common Lisp на Clojure? Чтобы быть более конкретным, какие функции существуют в Common Lisp, которых нет в Clojure, и которые должны быть переписаны?


person Paul    schedule 27.02.2009    source источник


Ответы (4)


На clojure.org есть список различий между Clojure и другими Lisps. Еще кое-что, что я заметил с помощью Clojure:

  • Идиоматический Clojure в значительной степени опирается на неизменяемые структуры данных. Везде, где вы видите SETF в CL, возможно, придется изменить в Clojure, чтобы воспользоваться всеми преимуществами. (У вас всегда есть возможность использовать изменяемые структуры данных Java в Clojure, но большинство людей этого не делают.)

  • Мультиметоды Clojure похожи на CL (возможно, более мощные, потому что вы можете отправлять сообщения не только о типе), но полноценный CLOS недоступен в Clojure. Clojure вместо этого использует struct, который представляет собой просто причудливую хэш-карту. Конечно, также доступна система Java ООП. Некоторые люди работают над переносом CLOS на Clojure, но я не уверен, насколько далеко продвинулись эти усилия на данный момент.

  • Макросы Clojure работают немного иначе, чем макросы CL, когда дело касается разрешения символов / пространств имен. Я не уверен, что понимаю достаточно хорошо, чтобы прояснить различия. Тем не менее, в Clojure вам не нужно так много возиться с генсимами, что приятно.

  • Clojure не имеет такой системы условий, как CL. У вас есть только Java _3 _ / _ 4 _ / _ 5_ для обработки исключений.

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

  • Clojure не имеет нескольких возвращаемых значений. Деструктуризация в Clojure очень удобна (поддерживает списки, векторы, хэш-карты, наборы и т. Д.) И по умолчанию встроена в большее количество мест, чем CL, так что это меньшая проблема, чем могла бы быть.

В зависимости от приложения и того, как оно написано, портирование с CL на Clojure может быть практичным и простым, или может оказаться более практичным переписать его с нуля более функциональным, поточно-ориентированным способом, чтобы лучше соответствовать стилю Clojure. .

person Brian Carper    schedule 27.02.2009
comment
Также Clojure - это Lisp 1 (с пространствами имен), тогда как CL - это Lisp 2. Это очень важное различие, которое сильно влияет на макросы и, в меньшей степени, на объявления переменных и функций. - person dsm; 13.03.2009
comment
Макросы Clojure ближе к CL, чем к Scheme. Макросы Clojure не являются гигиеничными, но по умолчанию они значительно упрощают соблюдение гигиены. - person Brian Carper; 14.03.2009
comment
Мультиметоды CLOS могут отправляться по типу или идентификатору. На что еще может распространяться Clojure? - person Anonymous Coward; 21.03.2009
comment
Он может отправить что угодно. Вы предоставляете свою собственную произвольную функцию диспетчеризации. - person Brian Carper; 21.03.2009
comment
Существует пользовательская библиотека contrib, называемая набором ошибок, которая реализует большую часть обработки условий / перезапуска CLOS. - person David Plumpton; 17.07.2009
comment
@BrianCarper In, CL Универсальная функция и ее методы определения не являются мультиплексором, который выбирает, какой метод вызывать. Он составляет функцию (эффективный метод) из всех применимых методов def. Существует 8 встроенных стратегий «смешивания», и при необходимости можно определить свою собственную. ИМХО то мощнее не меньше. Хотя комбинация методов по умолчанию в целом достаточно хороша. Я полагаю, что мультиметоды Clojure достаточно хороши и для обычного случая. Также общие функции отправляются по классам, а не по типам. - person PuercoPop; 17.12.2015

У меня нет конкретного ответа, но я бы порекомендовал эти ресурсы:

person zweiterlinde    schedule 27.02.2009
comment
Я не верю, что это работа Питера Зайбеля. Стюарт Хэллоуэй портировал с CL на Clojure. - person Brian Carper; 27.02.2009
comment
Спасибо, Брайан. Фиксированный. Я только что купил препринт Стюарта, так что, возможно, он меня простит :) - person zweiterlinde; 28.02.2009

Существует несколько способов перехода с CL на Clojure (блог, другой блог, Обсуждение на HN).

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

person Brian Gianforcaro    schedule 27.02.2009
comment
Вот почему вы вместо этого используете рекурсию. - person Benjamin Confino; 27.02.2009
comment
а также батуты. Однако был достигнут некоторый прогресс в внедрении TCO в JVM через проект OpenJDK. - person dnolen; 28.02.2009
comment
Многие CL тоже этого не делают (это не обязательно), и я не знаю ни одной программы (мер), которая от этого зависит. например, SBCL / CMUCL не работает, если вы не используете оптимизацию динамического пространства. - person Ken; 01.03.2009
comment
Не невозможно иметь TCO в JVM. см. это обсуждение. stackoverflow.com/questions/1168059/ - person unj2; 24.07.2009
comment
Верно, что многие CL также не выполняют оптимизацию хвостовых вызовов, но это меньшая проблема для Common Lisp, поскольку он имеет более императивный характер, чем Clojure. - person mshroyer; 10.10.2010
comment
ссылки на два сообщения в блоге больше недействительны. Тема на HN все еще существует. - person masukomi; 22.12.2013

Для идиоматического кода CL это переписывание.

  • CL является обязательным, Clojure более чисто «функциональным».
  • CL является объектно-ориентированным (CLOS), Clojure - нет (использует объекты Java и имеет некоторые OO-механизмы)
  • Идентификаторы и синтаксис в основном разные.
  • Структуры данных разные.
  • CL в основном строгий (не ленивый), Clojure использует ленивые вычисления.

Даже перенос необходимой инфраструктуры (CLOS, обработка ошибок, потоки) на Clojure имеет мало смысла, поскольку Clojure - это действительно другой язык с другим стилем программирования.

Если кто-то не хочет переписывать код, существует, например, ABCL, который является общим Лисп для JVM.

person Rainer Joswig    schedule 27.11.2010