В чем разница между Лисп-1 и Лисп-2?
Я пытался понять разницу между Lisp-1 и Lisp-2 и как это связано с Clojure, но я все еще не понимаю должным образом. Кто-нибудь может просветить меня?
3 ответа
Согласно википедии:
Является ли отдельное пространство имен для функций преимуществом, является источником спора в сообществе Lisp. Это обычно упоминается как дебаты Lisp-1 против Lisp-2. Lisp-1 относится к модели Scheme, а Lisp-2 относится к модели Common Lisp.
В основном это вопрос о том, могут ли переменные и функции иметь одинаковые имена без конфликтов. Clojure - это Lisp-1, означающий, что он не позволяет использовать одно и то же имя для функции и переменной одновременно.
Вы можете прочитать эту статью Ричарда Габриэля. Это краткое изложение проблем, которые обсуждали сообщества Lisp в Lisp1 против Lisp2. В первых нескольких разделах он немного плотный и медленный, но к тому моменту, когда вы пройдете через раздел 5, его будет гораздо легче прочитать.
По сути, Lisp1 имеет единую среду, которая отображает символы на значения, и эти значения могут быть либо "обычными", либо функциями. Lisp2 имеет (как минимум) два пространства имен (символы имеют слот для своего значения функции и один для обычного значения). Таким образом, в Lisp2 вы можете иметь функцию с именем foo и значение с именем foo, тогда как в Lisp1 имя foo может ссылаться только на одно значение (функцию или другое).
Есть несколько компромиссов и различий во вкусе между ними, но прочитайте статью для деталей. В книге Кристиана Квиннека "Лисп в маленьких кусочках" также обсуждаются различия, сплетенные в тексте.
В Lisp-1 символ может иметь только одно значение. В Lisp-2 символ может иметь два значения: 1) значение, когда символ интерпретируется как функция, и 2) когда символ интерпретируется как значение.
В реализации на Lisp-1 структура, содержащая значение, связанное с символом, имеет только один слот для указателя на данные и тип. В Lisp-2 есть два указателя: один на значение функции, другой на значение переменной.
В Common Lisp, Lisp-2, вы можете вызвать (symbol-function 'a) (symbol-value 'a), чтобы получить функцию и значение отдельно. Если 'a определена как функция добавления и (setq a 3), то (aaa 1) вернет 7.
В Lisp 1 вы не могли бы этого сделать, потому что a может быть только одним, и контекст не меняет значения.
В Common Lisp #' — это сокращение от символ-функция. (setf (symbol-function 'a) #'+ ) установит a как сумму функции.
Если бы вы захотели, вы могли бы создать функцию a, которая бы присваивала a значение, последнее возвращенное при вызове a, возможно, если бы вычисление a было дорогостоящим.
В Lisp-2, если вы назначили функцию символу, то для вызова этой функции вы используете оператор funcall.