Por que usar #' com lambda?
Pergunta
Por que devo usar #' juntamente com lambda? Ele geralmente é escrito dessa maneira, então eu acho que é uma boa forma. Mas estas linhas parecem iguais para mim:
> (mapcar #'(lambda (x) (+ x 1)) '(1 2 3))
(2 3 4)
> (mapcar (lambda (x) (+ x 1)) '(1 2 3))
(2 3 4)
Qualquer um cuidado para iluminar um iniciante sobre a diferença?
Solução
#'
é uma abreviação para function
, que retorna um ponteiro para uma função (em vez da aplicar). lambda
retorna uma função, e é normal querer um ponteiro para essa função. Uma vez que este é tão comum, há também uma macro (no espaço variável) que faz isso por você, que é chamado lambda
também. Ambas as linhas de código são idênticas.
O que é melhor se resume ao Lisp-1 / Lisp-2 debate : em Common Lisp você pode fazer qualquer um, graças à macro. Como sempre, ser coerente.
Outras dicas
É diferente em vários dialetos Lisp. As seguintes utilizações Common Lisp:
Primeiro #' é uma curta notação para (função ...) . Assim, o seguinte são apenas textualmente diferente, mas Lisp Comum lê-los como a mesma:
#'(lambda (x) (* x 2))
e
(function (lambda (x) (* x 2)))
#' é um readmacro, e transforma quando o código Lisp é lida pelo sistema Lisp.
Se avalia Lisp
(function (lambda (x) (* x 2)))
sistema Lisp cria um objeto de função e função retorna-lo como seu valor .
Assim, sempre que você precisar de uma função como um valor, então você precisa escrevê-lo assim. Uma função como um valor é necessário, quando você quer passá-lo para outras funções como um argumento, quando você quiser devolvê-lo a partir de uma função ou quando você deseja armazená-lo em uma variável. Exemplos:
(map #'(lambda (x) (* x 2)) '(1 2 3))
(defun (y) #'(lambda (x) (* x y)))
(defparameter *twice-fn* #'(lambda (x) (* x 2)))
Agora, o que é (lambda (x) (* x 2))?
É duas coisas diferentes dependendo do contexto.
expressão Lambda
A expressão lambda pode ser usado em vez de um nome de função:
(function foo) and (function (lambda (x) (* x 2)))
e
(foo 17) and ((lambda (x) (* x 2)) 17)
Acima dois são legal sintaxe Common Lisp. Há uma expressão lambda pode ser usado diretamente.
Note que as duas formas seguintes são ilegal em Lisp comum:
(#'(lambda (x) (* x 2)) 17) ; illegal in Common Lisp
(function #'(lambda (x) (* x 2))) ; illegal in Common Lisp
Macro
Durante o processo de normalização Common Lisp um LAMBDA macro foi adicionado (não era parte da primeira descrição, CLtL1, de Common Lisp). Isso torna possível escrever código ligeiramente mais curto. Exemplo:
(lambda (x) (* x 2))
No caso acima LAMBDA é um macro. Durante a expansão macro será expandida para:
(function (lambda (x) (* x 2)))
Recorde que na forma de funções acima, o lambda interior faz parte de uma expressão lambda, indica a função e não irá ser expandido.
Então, agora os três exemplos de cima pode ser escrita como:
(map (lambda (x) (* x 2)) '(1 2 3))
(defun (y) (lambda (x) (* x y)))
(defparameter *twice-fn* (lambda (x) (* x 2)))
É ligeiramente mais curto, parece um pouco menos confuso e olha um pouco mais semelhante ao código Scheme. É apenas olhando um pouco melhor para os programadores usado para ler e escrever código Scheme.
Resumo
a) (function (lambda (x) (* x 2))) é o caminho 'true' para escrever código que retorna uma função como um valor.
b) # '(lambda (X) (* x 2)) é uma notação mais curto de cima
c) (lambda (x) (* x 2)) é ainda menor, mas usa a expansão macro para criar a forma de a).