2009-12-03 14 views
5

Supongamos que tengo esta maravillosa función fooel retorno de una función lambda en clisp, luego evaluarla

[92]> (defun foo() (lambda() 42)) 
FOO 
[93]> (foo) 
#<FUNCTION :LAMBDA NIL 42> 
[94]> 

Ahora, supongamos que quiero en realidad uso foo y volver 42.

¿cómo lo hago ¿ese? Estuve buscando en google y parece que no puedo encontrar la sintaxis correcta.

Respuesta

11

desea que la función FUNCALL:

* (defun foo() (lambda() 42)) 
FOO 
* (funcall (foo)) 
42 
2

Su función devuelve un foofunction. Use la función funcall para aplicar una función a argumentos, incluso si el conjunto de argumentos está vacío.

Aquí se puede ver que foo devuelve un valor de tipo function:

CL-USER> (let ((f (foo))) 
      (type-of f)) 
FUNCTION 
CL-USER> (let ((f (foo))) 
      (funcall f)) 
42 
CL-USER> (type-of (foo)) 
FUNCTION 
CL-USER> (funcall (foo)) 
42 
2

Otra opción además funcall es aplicar:

(apply (foo) nil)

funcall es la forma idiomática aquí, pero' Necesitará SOLICITAR cuando tenga una lista de parámetros.

6

Las condiciones relevantes aquí son "Lisp-1" y "Lisp-2".

Su intento de llamada funcionaría en un Lisp-1 como, por ejemplo, Scheme o Clojure. Common Lisp es un Lisp-2 sin embargo, lo que aproximadamente significa que los nombres de variables y funciones están separados.

Por lo tanto, con el fin de llamar a la función unida a una variable que sea necesario utilizar las formas especiales funcall o apply como otros han señalado o establecer el valor de la función del símbolo foo en lugar del valor de la variable.

El ex básicamente toma el valor de la variable del símbolo, asume/comprueba que el valor es una función y luego llama a la función (con cualquier argumento que pasó a funcall/apply.

Usted realmente no quiere hacer esto último ya que es bastante tonto, pero en todos los casos muy especializados, pero por el bien completitud esto es más o menos la forma en que lo harías:

CL-USER> (setf (symbol-function 'foo) (lambda() 42)) 
#<FUNCTION (LAMBDA()) {C43DCFD}> 
CL-USER> (foo) 
42 

también debería desee ver en las formas especiales labels y flet (que se usan comúnmente) - allí en realidad do utilice los últimos métodos (estos formularios crean un enlace de función temporal para símbolos).

Así que el problema no sería el siguiente aspecto:

(flet ((foo() 
     42)) 
    (foo)) 

decir aquí que ates temporalmente la función valor del símbolo foo a la función que devuelve 42. Dentro de ese contexto temporal a continuación, puede llamar como (foo) funciones globales regulares.

+0

¡Esa es una gran respuesta! –

Cuestiones relacionadas