Existe uma diferença entre `# '(lambda…` e `(lambda…`? [Duplicado]

Dec 14 2020

Em Practical Common Lisp há um exemplo de REMOVE-IF-NOTcom um lambda:

CL-USER> (remove-if-not #'(lambda (x) (evenp x)) '(1 2 3 4 5))
(2 4)

Isso é diferente de:

CL-USER> (remove-if-not (lambda (x) (evenp x)) '(1 2 3 4 5))
(2 4)

Um (lambda..)valor coincide com a forma da função entre aspas #'(..)? No REPL parece que sim, mas como sou novo no Lisp, posso deixar passar alguma coisa (e com certeza entendi o palavreado errado, então, por favor, corrija-me nisso também).

Respostas

4 tfb Dec 14 2020 at 19:03

Essas duas coisas são, como você suspeita, as mesmas:

  • #'é uma macro de leitura e #'xé lida como (function x). Então #'(lambda (...) ...)é lido como (function (lambda (...) ...)), onde functionestá o operador especial em CL que diz que seu argumento denota uma função;
  • lambdaé definido como uma macro: a expansão de (lambda (...) ...)é (function (lambda (...) ...): a forma idêntica à anterior.

Isso significa que #'(lambda (...) ...), (lambda (...) ...)e (function (lambda (...) ...))todos são a mesma coisa em CL: todos eles denotam a função especificada por (lambda (...) ...)no ambiente léxico atual.

Existem duas razões pelas quais as pessoas ainda podem usar a #'(lambda (...) ...)versão:

  • consistência - você precisa, por exemplo, #'foose foofor uma função, então pode ser visto como mais consistente usá-lo para o lambdacaso também;
  • nem sempre foi o caso em CL que lambdatinha a definição de macro que agora tem, então o código que foi escrito entre a especificação CL original e o padrão ANSI, ou que foi escrito por pessoas que se lembram daqueles tempos, pode usar o #'formulário.