2010-02-28 3 views
9

Я читал, что большинство языков становятся все более и более похожими на lisp, применяя функции, которые Lisp имел в течение длительного времени. Мне было интересно, каковы черты, старые или новые, которых нет у lisp? По lisp я имею в виду наиболее распространенные диалекты, такие как Common Lisp и Scheme.Какие функции не хватает?

+1

Спрос на торговлю? Пакс утки для обложки :-) – paxdiablo

ответ

7
  • Pass по ссылке (C++/C#)
  • Строка интерполяции (Perl/Ruby) (хотя особенность CL21)
  • Хороший синтаксис инфикс (хотя это не ясно, что это стоит) (Python)
  • монадические «итерации» построить который может быть перегружен для других целей (Haskell/C#/F #/Scala)
  • статической типизации (хотя это не ясно, что это стоит) (много языков)
  • типа (не по крайней мере в стандарте) (C AML и многие другие) (хотя CL делает некоторый тип логического вывода, в отличие от Python)
  • Абстрактные типы данных (Haskell/F #/Caml)
  • соответсвующей Pattern (Haskell/F #/Caml/Scala/другие) (в CL, там является ЛИЭС как optima)
  • Отката (хотя это не ясно, что это стоит) (Пролог)
  • одноранговой полиморфизм (см ответа Эндрю Майерса)
  • неизменных структур данных (много языков) (доступны через библиотеки, например Fsets
  • ленивый eval туации (Haskell) (доступны через библиотеки, как clazy или cl21 module)

(Пожалуйста, добавьте к этому списку, я пометил это сообщество вики.)

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

Конечно, некоторые реализации упаковывают основной Lisp с кучей этих функций в виде библиотек. По крайней мере, для схемы PLT Scheme предоставляет все перечисленные выше функции *, в основном в виде библиотек. Я не знаю эквивалента для Common Lisp, но может быть и один.

* Может быть, не инфиксный синтаксис? Я не уверен, я никогда не искал этого.

+4

Я уверен, что видел общие библиотеки Lisp для не менее 3 из них. :-) – Ken

+2

Это вводит в заблуждение, потому что «стандарты» здесь мало что означают ... Чтобы сделать это правильно, следует пояснить, что самым большим преимуществом lisp (и схемы) является его способность изменять и адаптироваться - и получить много этих особенностей. Например, PLT Scheme является диалектом lisp/schem и имеет каждую из этих функций. –

+0

@ Ken: Да, я реализовал большое количество этих вещей плохо, сам. Являются ли они особенностью языка? Нет. Это библиотеки. @Eli: Я попытаюсь найти способ прояснить это - это хороший момент, потому что вопрос OP ошибочен. –

-1

Достойный синтаксис. (Кто-то должен был сказать это.) Это может быть простой/форма/homoiconic/макро состоянии/и т.д., но как человек, я просто ненавижу, глядя на него :)

+2

Была попытка так называемых «М-выражений», но она просто так и не попалась. И, конечно же, есть Дилан. –

+9

Любой, кто потратил более 10 минут на работу с Lisp, научился игнорировать синтаксис. Точно так же, как с любым другим языком, программированием или иным способом. – jrockway

+5

Если «непристойный синтаксис» был ценой, которую мне пришлось заплатить, чтобы написать 1/10-й код, я бы согласился заплатить это. Но, возможно, я изучил Лиспа, когда был слишком молод, потому что я никогда не понимал, почему я должен ненавидеть его. Сначала вы помещаете первый символ перед словом 'defun' вместо него и используйте() вместо {}, и в остальном он почти такой же, как и большинство других языков. Я не понимаю, почему это связывает людей в узлах. – Ken

-3

Это отсутствует большой IDE

+12

Ух, Emacs? CL + Emacs удаляет Java + Eclipse из воды. – jrockway

+1

Emacs + SLIME чувствует себя чудом от POV развития C-стиля. Тем не менее, Emacs может использовать достойный текстовый редактор. : p – guns

+0

@jrockway Серьезно? Редактор кода! = IDE –

1
  • Это может быть сложнее, чем на более популярных языках, чтобы найти хорошие библиотеки.
  • Это не чисто функциональный, как Haskell
+1

Возможно, чисто функциональные языки не обладают функцией изменчивости. Я не вижу, как вы добавили функцию lisp, чтобы сделать ее чисто функциональной; вам придется удалять вещи вместо этого. –

+0

Если чисто функциональный - это то, что вам нравится, взгляните на Clojure, самого важного нового члена семьи Lisp. –

10

Этот вопрос был задан миллион раз, но здесь идет. Common Lisp был создан в то время, когда людей считали дешевыми, а машины считались дорогими. Common Lisp облегчил людям жизнь за счет усложнения работы компьютеров. Машины Lisp были дорогими; ПК с DOS были дешевыми. Это было плохо для его популярности; лучше заставить еще нескольких людей совершать ошибки с менее выразительными языками, чем покупать лучший компьютер.

Перемотка вперед 30 лет, и оказывается, что это не так. Люди очень, очень дорогие (и в очень короткие сроки, попробуйте нанять программиста), а компьютеры очень и очень дешевы. Дешевле, чем грязь. То, что сегодня нужно миру, именно то, что предложил Common Lisp; если бы Лисп был изобретен сейчас, он стал бы очень популярен. Так как это 30-летняя (плюс!) Технология, тем не менее, никто не думал смотреть на нее, а вместо этого создал свои собственные языки с похожими понятиями. Это те, которые вы используете сегодня. (Java + сбор мусора является одним из самых больших инноваций. В течение многих лет GC смотрелся на «слишком медленном», но, конечно, небольшое исследование, а сейчас быстрее, чем управление собственной памятью. тоже ... Как изменилось время ...)

+3

Одна коррекция: Lisp (немного больше) 50 лет. –

+2

Вот почему я сказал «Common Lisp», который действительно узнаваем только в середине 80-х. (Lisp machine lisp, maclisp, elisp и т. Д.) – jrockway

+3

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

2

Это в ответ на обсуждение в комментариях в ответ Натана Сандерса. Это немного для комментария, поэтому я добавляю его здесь. Надеюсь, это не противоречит этикете Stackoverflow.

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

;This is unnecessary and created implicitly if not defined. 
;It can be explicitly provided to define an interface. 
(defgeneric what-am-i? (thing)) 

;Provide implementation that works for any type. 
(defmethod what-am-i? (thing) 
    (format t "My value is ~a~%" thing)) 

;Specialize on thing being an integer. 
(defmethod what-am-i? ((thing integer)) 
    (format t "I am an integer!~%") 
    (call-next-method)) 

;Specialize on thing being a string. 
(defmethod what-am-i? ((thing string)) 
    (format t "I am a string!~%") 
    (call-next-method)) 


CL-USER> (what-am-i? 25) 
I am an integer! 
My value is 25 
NIL 
CL-USER> (what-am-i? "Andrew") 
I am a string! 
My value is Andrew 
NIL 
+0

Одно из отличий, IIRC, заключается в том, что в сценарии типа C++ в режиме ad-hoc используются типы времени компиляции для диспетчеризации, а общие функции CLOS-типа используют типы времени выполнения для диспетчеризации. Конечно, я не могу придумать, каким образом общие функции хуже, но я не уверен, что скажу, что CL имеет ad-hoc-полиморфизм. (Я могу сказать, что «у него есть общие функции, которые лучше * чем ad-hoc-полиморфизм».) – Ken

+0

Вы правы относительно времени компиляции и диспетчеризации времени выполнения. Вчера вечером я понял, что ложась спать, это тоже не полный аддитивный полиморфизм. Для ad-hoc-полиморфизма вам также должно быть позволено изменять количество аргументов, а не только их типы. Так что в C++ у вас может быть одна перегрузка без аргументов, а другая - на 2, я не уверен, как это сделать в CL. Я думаю, что было бы возможно, но большая работа по деструктуризации аргументов. – asm

+0

У C++ определенно есть диспетчеризация времени выполнения. Без этого он не был бы объектно-ориентированным языком в каком-либо значимом смысле. Перегрузки C++, которые вы обсуждаете, - это что-то еще. Ищите «переопределение», а не «перегрузку». –

1
  • цельнозерновой программы преобразований. (Это было бы так же, как макросы, но для всего. Вы могли бы использовать его для реализации декларативных языковых функций.) Эквивалентно, возможность писать надстройки компилятору. (По крайней мере, схема отсутствует. CL может не быть.)
  • Встроенный помощник по теоретике/проверщик проверки для подтверждения утверждений о вашей программе.

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

+1

Lisp macros действительно ДОПОЛНИТЕЛЬНЫЕ дополнения к компилятору; они являются истинными языковыми расширениями. Я не совсем уверен, что еще вы просите. –

3

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

  • Некоторые функции для работы с базовой ОС, такие как вызов других программ или обработка аргументов командной строки. Каждая реализация CL, которую я использовал, имеет нечто подобное, и все они довольно похожи.

  • Базовые макросы или специальные формы для BACKQUOTE, UNQUOTE и UNQUOTE-SPLICING.

  • Протокол метаобъекта для CLOS.

  • Протокол для пользовательских LOOP статей. Есть и другие способы: LOOP может быть усилен, что, вероятно, не будет слишком болезненным, как, например, клаузулы для привязки нескольких значений или итерации по общей последовательности (вместо того, чтобы требовать разные предложения для LIST s и VECTOR s).

  • Средство системы определения, которое интегрируется с PROVIDE и REQUIRE, в то время как undeprecating PROVIDE и REQUIRE.

  • Лучшее и расширяемое средство для потока, позволяющее пользователям определять свои собственные классы потоков. Это может быть немного больнее, потому что есть два конкурирующих предложения, потоки Grey и «простые потоки», оба из которых реализованы некоторыми реализациями CL.

  • Лучшая поддержка для «сред», как описано в CLTL2.

  • Заявление для объединения хвостовых вызовов и описания ситуаций, когда вызовы, которые выглядят как хвостовые вызовы не являются (из-за UNWIND-PROTECT форм, DYNAMIC-EXTENT деклараций, специальных привязки переменных, и др с.).

  • Неопределенный REMOVE-IF-NOT и друзья. Устраните аргумент ключевого слова :TEST-NOT и SET.

  • Слабые ссылки и слабые хеш-таблицы.

  • Проводимые пользователем хэш-таблицы.

  • PARSE-FLOAT. В настоящее время, если вы хотите превратить строку в число с плавающей запятой, вам нужно либо использовать READ (что может делать все, что вам не нужно), либо перевернуть собственную функцию синтаксического анализа. Это глупо.

Вот еще несколько амбициозных функций, которые, как я думаю, будут полезными.

  • Протокол для определения классов последовательностей, которые будут работать со стандартными функциями общих последовательностей (например, MAP, REMOVE и друзья). Добавление неизменяемых строк и совпадений вместе с их изменчивыми родственниками тоже может быть приятным.

  • Предоставить более богатый набор ассоциативных массивов/"карт" типов данных. Сейчас у нас есть специальные вещи, построенные из conses (alists и plists) и хеш-таблиц, но без сбалансированных бинарных деревьев. Предоставьте общие функции последовательности для работы с ними.

  • Fix DEFCONSTANT поэтому он делает что-то менее бесполезное.

  • Улучшенный контроль читателя. Это очень мощный инструмент, но его нужно использовать очень осторожно, чтобы не делать что-то вроде интернирования новых символов. Кроме того, было бы неплохо, если бы были лучшие способы управления readtables и пользовательскими синтаксисами чтения.

  • Читаемый синтаксис «необработанных строк», аналогичный тому, что предлагает Python.

  • Еще несколько вариантов для CLOS-классов и слотов, что позволяет повысить эффективность и повысить производительность. Некоторые примеры - это «первичные» классы (где у вас может быть только один «первичный класс» в списке суперклассов класса), «запечатанные» общие функции (поэтому вы не можете добавлять к ним больше методов, позволяя компилятору сделать много больше предположений о них) и слоты, которые гарантированно связаны.

  • Поддержка резьбы. Большинство реализаций либо поддерживают SMP сейчас, либо будут поддерживать его в ближайшем будущем.

  • Устранить больше поведения пути. Существует много неудобных несовместимостей между реализациями, например, непроницаемость CLISP для сигнализации об ошибке при использовании PROBE-FILE в каталоге или даже в том, что нет стандартной функции, которая сообщает вам, является ли путь именем имени каталога или нет.

  • Поддержка сетевых сокетов.

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

+1

МНОГИЕ вещей, которые вы упомянули здесь, доступны в библиотеках настолько хорошо зарекомендовавших себя, чтобы быть такой же «частью языка», как и стандартные библиотеки Java. bordeaux-threads, usocket и cffi - некоторые из них. Там есть хорошая дискуссия о будущем Лиспа на

0

Вы задаете вопрос о ronge. Язык с большинством функций не лучший. Язык нуждается в цели.

Мы могли бы добавить все это и многое другое

* Pass-by-reference (C++/C#) 
* String interpolation (Perl/Ruby) 
* Nice infix syntax (though it's not clear that it's worth it) (Python) 
* Monadic 'iteration' construct which can be overloaded for other uses (Haskell/C#/F#/Scala) 
* Static typing (though it's not clear that it's worth it) (many languages) 
* Type inference (not in the standard at least) (Caml and many others) 
* Abstract Data Types (Haskell/F#/Caml) 
* Pattern matching (Haskell/F#/Caml/Scala/others) 
* Backtracking (though it's not clear that it's worth it) (Prolog) 
* ad-hoc polymorphism (see Andrew Myers' answer) 
* immutable data structures (many languages) 
* lazy evaluation (Haskell) 

но что бы сделать хороший язык. Язык не работает, если вы используете вызов по ссылке.

Если вы посмотрите на новый список Clojure. Некоторые из них реализованы, но другие, что CL нет, и что делает хороший язык.

Clojure, например, добавили несколько:

одноранговой полиморфизм ленив оценки неизменные структуры данных Тип вывода (большинство динамических языков есть компиляторы, которые делают это)

Мой Ответ:

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

Его LISP можно добавить с помощью libs.