Подтвердить что ты не робот

Написание лямбда-выражений в общем lisp

В настоящее время я читаю ANSI Common Lisp от Paul Graham, и у меня есть вопрос о написании лямбда-выражений.

Нужно ли префикс лямбда-выражения с #'?. Если я напишу что-то подобное в REPL, он будет работать нормально

> ((lambda (x) (+ x 1)) 1)
  2

так будет это

> (mapcar (lambda (x) (+ x x)) '(1 2 3 4))
  (2 4 6 8)

Я понимаю, что #' обозначает функцию. Поэтому мой вопрос в том, что это какая-то конвенция или рекомендуемая практика? Может ли что-то пойти не так, если я не префикс lambdas с #', зависит ли это от реализации?

4b9b3361

Ответ 1

Выражение LAMBDA

(lambda ...) считается лямбда-выражением только в определенных местах, таких как форма function или как глава вызова функции. Лямбда-выражения не оцениваются.

(function              ; special operator FUNCTION
  (lambda () 'foobar)) ; <- this is a lambda expression


(                    ; a function call
 (lambda (foo) foo)  ; <- this is a lambda expression
 'bar                ; argument
)

Но здесь (lambda ...) - макроформа, а не лямбда-выражение:

(funcall             ; calling a function via funcall
 (lambda (foo) foo)  ; this is not a lambda expressions, but the macro lambda
                     ;  as all arguments to FUNCALL it will be
                         macro expanded and evaluated
                     ;  it expands to (function (lambda (foo) foo))
 'bar)               ; argument

Макрос LAMBDA

LAMBDA - это макрос. Он расширяет (lambda ...) до (function (lambda ...)), что эквивалентно #'(lambda ...)).

CL-USER > (macroexpand '(lambda (foo) foo))
(FUNCTION (LAMBDA (FOO) FOO))

Макрос экономит вам немного написание/чтение, что и все. В первой версии Common Lisp (CLtL1) не было макроса LAMBDA. Он был добавлен позже и теперь является частью ANSI Common Lisp,

Специальный оператор FUNCTION

FUNCTION является специальным оператором. Он ожидает имя функции или выражение лямбда. Таким образом, имя или выражение лямбда не оцениваются. Фактически лямбда-выражения не могут быть оценены вообще. Внутри function выражение лямбда не представляет собой макрокоманду и, следовательно, будет расширено не. Цель function - вернуть соответствующий объект функции, который обозначается именем или выражением лямбда. Он возвращает объект функции как значение. С помощью этого специального оператора можно получить доступ к объекту функции из глобальных функций и лексических функций.

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

Лямбда-выражения в позиции функции в форме функций

((lambda (foo) foo) 10) поддерживается встроенным синтаксисом для Common Lisp. См. Лямбда-формы.

Смешение

Это все логично, но сбивает с толку. Не беспокойтесь, что вы не одиноки, но на практике это неважно.