quicklisp - ¿Por qué defun no es lo mismo que(setq<name><lambda>)?
common-lisp sbcl (2)
Common Lisp tiene diferentes espacios de nombres para funciones y valores.
Usted define funciones en el espacio de nombres de funciones con DEFUN
, FLET
, LABELS
y algunos otros.
Si desea obtener un objeto de función como un valor, use FUNCTION
.
(defun foo (x) (1+ x))
(function foo) -> #<the function foo>
o más corto:
#''foo -> #<the function foo>
Si quieres llamar a una función, entonces escribes (foo 100)
.
Si desea llamar a la función como un valor, debe usar FUNCALL
o APPLY
:
(funcall #''foo 1)
Puedes pasar las funciones y llamarlas:
(defun bar (f arg)
(funcall f arg arg))
(bar #''+ 2) -> 4
En el caso de DEFUN:
No es (setf (symbol-value ''FOO) (lambda ...))
.
Es más parecido a (setf (symbol-function ''foo) (lambda ...))
.
Tenga en cuenta que los dos espacios de nombres le permiten escribir:
(defun foo (list)
(list list))
(foo ''(1 2 3)) -> ((1 2 3))
No hay conflicto entre la función integrada LIST
y la variable LIST
. Como tenemos dos espacios de nombres diferentes, podemos usar el mismo nombre para dos propósitos diferentes.
Tenga en cuenta también que en el caso de las funciones locales no hay ningún símbolo involucrado. Los espacios de nombres no están necesariamente vinculados a los símbolos. Por lo tanto, para las variables locales no es posible buscar una función a través de un nombre de símbolo.
Estoy confundido acerca de cómo funciona la macro defun, porque
(defun x () "hello")
creará la función x, pero el símbolo x seguirá sin estar vinculado.
Si uniré algo de lambda a x, entonces x tendrá un valor, pero el intérprete no lo tratará como una función en esta forma:
(x)
Creo que está relacionado con el hecho de que defun debería definir la función en un entorno global, pero no estoy seguro de qué significa exactamente. ¿Por qué no puedo ocultarlo en el entorno actual?
¿Hay alguna forma de forzar que el intérprete trate el símbolo como una función si algún lambda estaba vinculado a él? Por ejemplo:
(setq y (lambda () "I want to be a named function"))
(y)
PS: Estoy usando SBCL.
Common Lisp tiene varias ranuras para cada símbolo, incluida una ranura de valor y una ranura de función. Cuando se utiliza la sintaxis (x)
, lisp común busca la función de enlace de ranura de x
. Si desea llamar a la vinculación de valores, utilice funcall
o apply
.