Scheme vs Common Lisp: Какие характеристики повлияли на ваш проект? [закрыто]

Нет недостатка в неопределенных вопросах «Scheme vs Common Lisp» как на StackOverflow, так и на этом сайте, поэтому я хочу сделать это еще более целенаправленным. Вопрос касается людей, которые закодированы на обоих языках:

Во время кодирования в Scheme, какие конкретные элементы вашего общего кодирования Lisp вы пропустили больше всего? Или, наоборот, при кодировании в Common Lisp, что вы пропустили от кодирования в Scheme?

Я не обязательно имею в виду только функции языка. Следующее - все, что нужно пропустить, в том, что касается вопроса:

  • Конкретные библиотеки.
  • Особенности среды разработки, такие как SLIME, DrRacket и т. д.
  • Особенности конкретных реализаций, таких как способность Gambit писать блоки кода C непосредственно в ваш источник Scheme.
  • И, конечно, особенности языка.

Примеры ответов, на которые я надеюсь:

  • «Я пытался реализовать X в Common Lisp, и если бы у меня были первоклассные продолжения Scheme, я бы полностью сделал Y, но вместо этого мне пришлось делать Z, что было больнее».
  • «Сценарий процесса сборки в моем проекте Scheme становился все более болезненным, поскольку мое исходное дерево росло, и я связывал все больше библиотек C. Для моего следующего проекта я вернулся к Common Lisp».
  • «У меня есть большая существующая кодовая база C ++, и для меня возможность встраивать вызовы C ++ непосредственно в моем коде Схемы Gambit полностью оправдывала недостатки, которые могут иметь Scheme против Common Lisp, даже если они не поддерживают поддержку SWIG».

Итак, я надеюсь на военные истории, а не на общие чувства, такие как «Схема - более простой язык» и т. д.

146 голосов | спросил SuperElectric 29 Jam1000000amSat, 29 Jan 2011 01:02:28 +030011 2011, 01:02:28

5 ответов


94

Моя степень бакалавра была в области когнитивной науки и искусственного интеллекта. От этого у меня было однокурсное вступление к Лиспу. Я думал, что язык интересный (как в «элегантном»), но на самом деле не очень много думал об этом, пока я не наткнулся на десятое правило Greenspun намного позже:

  

Любой достаточно сложный C или   Программа Fortran содержит специальную,   неформально, с ошибкой, медленным   реализация половины общего Lisp.

Точка Greenspun была (частично) состояла в том, что многие сложные программы имеют встроенные интерпретаторы. Вместо того, чтобы создавать переводчика на языке, он предположил, что имеет смысл использовать такой язык, как Lisp, который уже имеет встроенный интерпретатор (или компилятор).

В то время я работал над довольно большим приложением, которое выполняло пользовательские вычисления с использованием пользовательского интерпретатора для пользовательского языка. Я решил попробовать переписать его ядро ​​в Lisp как крупномасштабный эксперимент.

Прошло около шести недель. Исходный код был ~ 100 000 строк Delphi (вариант Pascal). В Lisp было сокращено до ~ 10 000 строк. Еще более удивительным было то, что двигатель Lisp был в 3-6 раз быстрее. И имейте в виду, что это была работа неофита Лиспа! Весь этот опыт был для меня совершенно очевидным; я впервые увидел возможность сочетания производительности и выразительности на одном языке.

Спустя некоторое время, когда я начал работать над веб-проектом, я прослушивал несколько языков. Я включил Lisp и Scheme в микс. В итоге я выбрал реализацию схемы - Chez Scheme . Я был очень доволен результатами.

Веб-проект представляет собой высокопроизводительный механизм выбора . Мы используем Scheme несколькими способами: от обработки данных до запросов к генерации страниц. Во многих местах мы фактически начали с другого языка, но в конечном итоге перешли на Схему по причинам, которые я опишу ниже.

Теперь я могу ответить на ваш вопрос (по крайней мере частично).

Во время прослушивания мы рассмотрели различные реализации Lisp и Scheme. На стороне Лиспа мы рассмотрели (я считаю) Allegro CL, CMUCL, SBCL и LispWorks. На стороне Схемы мы посмотрели (я полагаю) Биллоо, Цыпленок, Чез, Гамбит. (Выбор языка был давным-давно, поэтому я немного туман. Я могу выкопать некоторые заметки, если это важно.)

С самого начала мы искали a) собственные потоки и b) поддержку Linux, Mac и Windows. Эти два условия объединили всех, но (я думаю) Аллегро и Чеза - поэтому, чтобы продолжить оценку, нам пришлось ослабить требование многопоточности.

Мы собрали набор небольших программ и использовали их для оценки и тестирования. Это выявило ряд проблем. Например: в некоторых реализациях были дефекты, которые препятствовали выполнению некоторых тестов; некоторые реализации не могли компилировать код во время выполнения; некоторые реализации не могли легко интегрировать скомпилированный код во время выполнения с предварительно скомпилированным кодом; в некоторых реализациях были сборщики мусора, которые были явно лучше (или явно хуже), чем другие; и др.

Для наших нужд только три коммерческие реализации - Allegro, Chez и Lispworks - прошли наши первичные тесты. Из трех только Чез прошел все тесты с летающими красками. В то время я думаю, что у Lispworks не было собственных потоков на любой платформе (я думаю, что они делают сейчас), и я думаю, что у Allegro были только собственные потоки на некоторых платформах. Кроме того, у Allegro был «звонок нам», который мне очень не нравился. Я полагаю, что у Lispworks не было платы за запуск, а у Chez была простая (и очень разумная) компоновка (и она только началась, если вы использовали компилятор во время выполнения).

Произведя несколько значительных фрагментов кода как в Lisp, так и в Scheme, приведены некоторые сравнительные и контрастные точки:

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

  • Среда Lisp гораздо труднее изучить. Вам нужно гораздо больше времени, чтобы стать опытным; Common Lisp - это огромный язык - и до того, как вы дойдете до библиотек, которые добавляются в коммерческие реализации поверх него. (Сказав это, синтаксис Case Scheme гораздо более тонкий и сложный, чем любая вещь в Lisp.)

  • В средах Lisp может быть несколько сложнее создать двоичные файлы. Вам нужно «встряхнуть» свое изображение, чтобы удалить ненужные биты, и если вы не будете правильно выполнять свою программу во время этого процесса, вы можете ошибки времени выполнения позже. В отличие от этого, с Chez мы собираем файл верхнего уровня, который включает в себя все другие файлы, которые ему нужны, и мы закончили.

Я уже говорил, что в конечном итоге мы использовали Scheme в ряде мест, которые мы изначально не планировали. Зачем? Я могу думать о трех причинахголова.

Во-первых, мы научились доверять Chez (и его разработчику, Cadence). Мы много раз просили у инструмента, и он постоянно доставлялся. Например, у Чеза исторически было тривиально небольшое количество дефектов, и его менеджер памяти был очень и очень хорош.

Во-вторых, мы научились любить спектакль, который мы получили от Чеза. Мы использовали что-то, что было похоже на скриптовый язык, и мы получали от него скорость с собственным кодом. Для некоторых вещей это не имело значения - но это никогда не повредило, и иногда это помогало очень много.

В-третьих, мы научились любить схему абстракции, которая могла бы обеспечить. Между прочим, я имею в виду не макросы; Я имею в виду такие вещи, как закрытие, лямбда, хвост-звонки и т. Д. После того, как вы начинаете думать в этих терминах, другие языки кажутся довольно ограниченными путем сравнения.

Является ли схема совершенной? Нет; это компромисс. Во-первых, это позволяет отдельным разработчикам быть более эффективными - но разработчикам сложнее разбираться в коде друг друга, потому что в схеме отсутствуют указатели, которые большинство языков имеют (например, для циклов) (например, существует миллион способов сделать цикл for). Во-вторых, есть гораздо меньше пулов разработчиков, с которыми можно разговаривать, нанимать, брать и т. Д.

Подводя итог, думаю, я бы сказал: Lisp и Scheme предлагают некоторые возможности, которые широко не доступны нигде. Эта способность является компромиссом, поэтому лучше иметь то, что имеет смысл в вашем конкретном случае. В нашем случае определяющие факторы между тем, следует ли идти с Lisp или Scheme, в большей степени связаны с очень фундаментальными функциями (поддержка платформы, потоки платформы, компиляция во время выполнения, лицензирование во время выполнения), чем с языковыми или библиотечными функциями. Опять же, в нашем случае это тоже было компромиссным: с Chez мы получили основные функции, которые хотели, но мы потеряли обширные библиотеки, которые были в коммерческих средах Lisp.

Также, чтобы повторить: мы давно смотрели на различные Лиспы и Схемы; с тех пор все они развивались и улучшались.

ответил Michael Lenaghan 29 MaramTue, 29 Mar 2011 03:36:55 +04002011-03-29T03:36:55+04:0003 2011, 03:36:55
36

Мне обычно не нравится вставлять ссылку в качестве ответа, но я написал статью в блоге по этому поводу. Он не является исчерпывающим, но он получает некоторые из основных моментов.

http://symbo1ics.com/blog/?p=729

Изменить : Вот основные моменты:

  1. СУЩЕСТВУЮЩИЙ : обе лайсы появились после кучи других лиз. Схема взяла минимальный, аксиоматический маршрут. CL взял маршрут в стиле барокко.
  2. CASE . Обычно схема чувствительна к регистру. CL не является (хотя это может быть). Это иногда пропущено, но его практичность обсуждается (мной).
  3. НАЗВАНИЯ . Имена символов в CL много раз нечетны и запутываются. TERPRI, PROGN и т. д. Схема обычно имеет очень разумные имена. Это пропущено в CL.
  4. ФУНКЦИИ : CL имеет отдельное пространство имен функций. Это not пропущено на схеме. Наличие единого пространства имен обычно допускает очень чистое функциональное программирование, которое часто сложно или неудобно в CL. Но это происходит из-за стоимости - вам иногда приходится обфускации имен «list» на «lst» в Схеме.
  5. МАКРОС . Я пропускаю низкоуровневые грязные макросы в Схеме. Да, syntax-rules все в порядке и dandy, пока вы не захотите действительно взломать некоторые вещи. С другой стороны, гигиенические макросы иногда пропускаются в CL. Не имея стандартного способа сделать это, нужно повторно изобрести колесо.
  6. ПОРТАТИВНОСТЬ . Часто бывает, что CL более портативен, несмотря на стандартизацию обоих языков. CL больше, и поэтому есть более стандартные функции для использования без внешних библиотек. Это также означает, что более зависимые от реализации вещи могут выполняться портативно. Кроме того, Scheme имеет триллион реализаций, большинство из которых несколько несовместимы. Это делает CL очень желательным.
  7. БИБЛИОТЕКИ : очень связано с моей последней точкой. Схема имеет SRFI, но не получила всеобщего признания. Нет никакого портативного способа работы с библиотеками. CL, с другой стороны, имеет свои пути. И Quicklisp - это подарок от бога (Xach) - своего рода хранилище библиотек для использования.
  8. РЕАЛИЗАЦИИ : схема страдает от того, что имеет множество реализаций. Реальной канонической реализации нет. CL с другой стороны имеет некоторые очень хорошие высокопроизводительные или специфичные реализации (высокая производительность: SBCL, коммерческая: Allegro, встроенная: ECL, переносная: CLISP, Java: ABCL, ...).

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

[Я извиняюсь, если они слишком общие. Кажется, вы можете захотеть получить гораздо более конкретные детали. В этой статье есть некоторые особенности.]

ответил Quadrescence 20 MaramSun, 20 Mar 2011 04:10:16 +03002011-03-20T04:10:16+03:0004 2011, 04:10:16
25

Недавно я начал домашний проект, используя библиотеку с версией C и версией Java. Я хотел использовать Lisp для проекта, и я провел около месяца колебания между использованием Common Lisp, Scheme или Clojure. У меня есть опыт работы со всеми тремя, но только с игрушечными проектами. Я расскажу вам немного о своем опыте работы с каждым из них, прежде чем расскажу вам, какой из них я выбрал.

PLT Racket имеет отличную среду IDE, которая не только позволяет вам оценивать выражения из редактора, но также позволяет вводить скобки вместо parens, переключая их обратно на parens, где это необходимо. У Racket также есть большой набор библиотек с установкой и еще более доступный для загрузки. Визуальный отладчик также полезен.

В моей реализации Common Lisp (SBCL) нет IDE, но для реализации Emacs и SLIME обычно используется реализация CL с открытым кодом. Эта комбинация может быть очень эффективной. Наряду с возможностью оценки выражений при вводе их в исходный файл есть также REPL, который имеет все команды редактирования emacs, поэтому копирование кода может эффективно работать в обоих направлениях. Даже объекты, отображаемые в буфере REPL, могут быть скопированы и вставлены. Alt+( и Alt+) эффективны для работы с совпадающими скобками и отступом.

Все перечисленные выше функции Emacs также доступны для Clojure. Мой опыт редактирования с Clojure аналогичен опыту Lisp. Java interop работал отлично, и я хотел бы сделать проект Clojure, когда он созреет.

Мне удалось получить доступ к библиотеке, используя все три (Common Lisp, Racket и Clojure), но в итоге я выбрал Common Lisp для проекта. Решающим фактором было то, что FFI было намного проще использовать в Common Lisp. CFFI имеет очень хорошее руководство с примером кода и подробные объяснения каждого метода. Я смог обернуть 20 функций C во второй половине дня и не должен был касаться кода с тех пор.

Другим фактором было то, что я больше знаком с Common Lisp, чем с Clojure или R6RS Scheme. Я читал большинство практических общих книг Лиспа и Грэма, и мне нравится Hyperspec. Это еще не очень «лживый» код, но я уверен, что это изменится, когда я получу больше опыта.

ответил Larry Coleman 9 FebruaryEurope/MoscowbWed, 09 Feb 2011 01:29:38 +0300000000amWed, 09 Feb 2011 01:29:38 +030011 2011, 01:29:38
20

Я программирую как в CL, так и в Racket.

Я разрабатываю веб-сайт в Common Lisp, и я написал набор собственных программ для моего предыдущего работодателя в Racket.

Для внутреннего кода я выбрал Racket (затем известный как PLT Scheme), потому что работодатель был магазином Windows, и я не мог заставить их платить за LispWorks. Единственной хорошей версией CL для открытого кода для Windows была (и до сих пор) CCL, которая требует поддержки SSE в процессоре. Работодатель, будучи дешевым, использовал оборудование Stone Age. Даже если у работодателя действительно было достойное оборудование, единственной графической библиотекой последствий в Common Lisp является McCLIM, который работает только в Unix. У Racket есть хорошая библиотека графического интерфейса, которая работает как на Unix, так и на Windows, что очень важно для успеха моего проекта.

Я потратил более года, используя примитивный редактор DrRacket. EMACS не смог повернуть графическую версию Racket, известную как MrEd, в нижний-lisp в Windows. Я должен был обойтись без возможности оценить выражение в курсоре одним нажатием клавиши. Вместо этого мне пришлось вручную выбрать S-выражение, скопировать его, щелкнуть по окну REPL (потому что на нем нет нажатия клавиши), а затем вставьте S-выражение. Мне также пришлось обойтись без редактора, который мог бы показать мне ожидаемые аргументы функции или макроса, который я использовал. DrRacket не заменяет SLIME.

Работодатель использовал проприетарную базу данных со сложным XML-интерфейсом, который требовал загрузки излишней информации, которая могла бы отвечать на его версию запроса SELECT. Я решил использовать HTMLPrag как для испускания XML для этого API, так и для анализа ответов. Он отлично работал.

Мне пришлось изучить сложную «синтаксическую ситуацию» Racket, чтобы написать макрос, который позволил бы мне взаимодействовать с сложным XML-интерфейсом, введя формы, похожие на SQL. Эта часть была бы намного проще, если бы у меня был DEFMACRO. Тем не менее, конечный результат был все еще плавным, хотя для достижения этого потребовалось больше усилий.

Кроме того, мне пришлось обойтись без макроса LOOP Common Lisp. Ракетка начала предлагать альтернативу только после того, как я написал большую часть кода, а альтернатива все еще отстойна по сравнению с LOOP (хотя команда разработчиков Racket настаивает на том, что лучше - они просто ошибаются). Я закончил писать много названных форм LET, которые использовали «автомобиль» и «cdr» для перебора списков.

Говоря о машине и cdr, нет ничего более расстраивающего, чем интерпретация Scheme (car '()) как ошибка. Я воспользовался чувствительностью к регистру Racket и реализовал CAR и CDR, которые имеют семантику Common Lisp. Однако разделение '() и #f делает менее полезным возвращать' () в качестве значения по умолчанию.

Я также закончил повторное внедрение UNWIND-PROTECT и изобрел собственную систему перезагрузки, чтобы заполнить пробел, оставленный Racket. Сообщество Racket должно узнать, что перезагрузки очень полезны и легко реализуются.

Форма let-values ​​Racket была слишком многословной, поэтому я реализовал MULTIPLE-VALUE-BIND. Это было абсолютно необходимо, потому что Racket требует получить all значения, которые сгенерированы, независимо от того, используете вы их или нет.

Позже я попытался написать клиент eBay XML API в Common Lisp, но обнаружил, что у него нет ничего подобного HTMLPrag. HTMLPrag полезен. Я закончил этот проект в Racket. Я экспериментировал с инструментами Грамотного программирования Racket, но обнаружил, что я единственный программист на Земле, который считает, что правильно написанный грамотный код сложнее редактировать, чем обычный код, или неправильно написанный «чрезмерный комментарий» грамотный код.

Мой новый проект выполняется в Common Lisp, что было правильным выбором, потому что сообщество Racket просто не верит в параллелизм, который необходим для этого проекта. Единственное, что я думал, что я, возможно, пропустил от Ракетки, было продолжением. Тем не менее, я смог сделать то, что мне было нужно, используя перезагрузки, и, оглядываясь назад, возможно, мог бы сделать это с простым закрытием.

ответил Racketeer 2 J0000006Europe/Moscow 2011, 01:40:36
4

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

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

К счастью, существуют реализации схемы (например, Racket), которые не имеют этого ограничения.

ответил SK-logic 20 MarpmSun, 20 Mar 2011 15:43:31 +03002011-03-20T15:43:31+03:0003 2011, 15:43:31

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132