Я хотел бы знать, почему наиболее распространенный код Lisp, который я вижу, имеет вещи как
(mapcar #'(lambda (x) (* x x)) '(1 2 3))
вместо просто
(mapcar (lambda (x) (* x x)) '(1 2 3))
,
который, кажется, работает также. Я начинаю изучать язык Common LISP и имею некоторые знания в Схеме, это заинтриговывает меня.
Править: Я знаю, что Вам нужен #' с именами функций, потому что они живут в другом пространстве имен, чем переменные. Мой вопрос примерно #' перед лямбдой, поскольку лямбда уже возвращает функциональный объект (я думаю). То, что # '-less работа лямбд из-за макрорасширения просто делает это более интригующим...
#'foo
- это сокращение для (function foo)
читателя.
В CL существует несколько различных пространств имен, #'foo
или (function foo)
вернут функциональное значение от foo
.
Возможно, вы захотите поискать "Lisp-1 vs. Lisp-2", проверить другие вопросы на Stackoverflow или прочитать старую статью Питмана и Габриэля, чтобы узнать больше о концепции множественных пространств имен (также называемых слотами или ячейками символов).
Причина, по которой в случае с лямбдой #'
может быть опущен в CL, заключается в том, что это макрос, который расширяется таким образом (взято из Hyperspec):
(lambda lambda-list [[declaration* | documentation]] form*)
== (function (lambda lambda-list [[declaration* | documentation]] form*))
== #'(lambda lambda-list [[declaration* | documentation]] form*)
#'
может все еще использоваться по историческим причинам (я думаю, что в Maclisp лямбды
не расширялись до формы функции), или потому что некоторые люди считают, что обозначение лямбд шарп-кавычками может сделать код более читабельным или связным. Возможно, есть какие-то особые случаи, в которых это имеет значение, но в целом, не имеет значения, какую форму вы выберете.
Думаю, вы можете думать об этом следующим образом: (function (lambda ...))
возвращает функцию, которую (lambda ...)
создает. Обратите внимание, что lambda
в CL Hyperspec имеет как макрос, так и запись символа. Из последнего:
Лямбда-выражение - это список, который можно использоваться вместо имени функции в определенных контекстах для обозначения функции непосредственно описывая ее поведение а не косвенно, ссылаясь на имя установленной функции.
Из документации по function
:
Если name является лямбда-выражением, то возвращается возвращается лексическое закрытие.
Я думаю, что разница также связана с вызовом лямбда-форм следующим образом: ((lambda ...) ...)
, где она рассматривается как форма, которую нужно оценить, против (funcall #'(lambda ...) ...)
. Если вы хотите почитать больше на эту тему, есть тема c.l.l об этом.
Некоторые цитаты из этой темы:
(лямбда (x) ...
сама по себе является просто некоторой структура списка без кавычек. Это ее появление в качестве аргумента в специальной формы ФУНКЦИИ(функция (лямбда (x) ...
приводит к тому, что существование объекта функции
и:
Дело осложняется еще и тем, что макрос LAMBDA был довольно поздним добавлением в ANSI Common Lisp, поэтому все действительно старые парни (т.е. такие как я) изучали свой лисп, когда вам нужно было добавлять #' к лямбда-выражению в функциях отображения. В противном случае несуществующая лямбда-функция была бы вызвана.
Добавление макроса изменило это, но некоторые из нас слишком закостенели в своих взглядах, чтобы чтобы захотеть меняться.