¿Hay alguna diferencia entre `# '(lambda ...` y `(lambda ...`? [Duplicar]

Dec 14 2020

En Practical Common Lisp hay un ejemplo de REMOVE-IF-NOTcon una lambda:

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

¿Es esto diferente de:

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

¿Es un (lambda..)valor coincidente con la forma de función cotizada #'(..)? En el REPL parece que sí, pero como soy nuevo en Lisp puedo pasar por alto algo (y seguramente me equivoqué en la verborrea, así que corrígeme en eso también).

Respuestas

4 tfb Dec 14 2020 at 19:03

Estas dos cosas son, como sospecha, lo mismo:

  • #'es una macro de lectura y #'xse lee como (function x). Entonces #'(lambda (...) ...)se lee como (function (lambda (...) ...)), donde functiones el operador especial en CL que dice que su argumento denota una función;
  • lambdase define como una macro: la expansión de (lambda (...) ...)es (function (lambda (...) ...): la forma idéntica a la anterior.

Esto significa que #'(lambda (...) ...), (lambda (...) ...)y (function (lambda (...) ...))todos son lo mismo en CL: todos denotan la función especificada por (lambda (...) ...)en el entorno léxico actual.

Hay dos razones por las que las personas aún pueden usar la #'(lambda (...) ...)versión:

  • consistencia: necesita, por ejemplo, #'foosi fooes una función, por lo que puede verse como más consistente usarla también para el lambdacaso;
  • no siempre fue el caso en CL que lambdatenía la definición de macro que tiene ahora, por lo que el código que se escribió entre la especificación CL original y el estándar ANSI, o que fue escrito por personas que recuerdan esos tiempos, puede usar el #'formulario.