2011-04-30 6 views
5

Supongamos que definen una función a nivel mundial:¿En LISP es posible acceder a la forma de una función?

(defun x (y) (1+ y)) ;; Edit: my first example was too complicated 

¿Es posible "forzar" la función de x en una lista como:

(x (y) (1+ y)) 

Gracias de antemano!

PS - El ejemplo de @ Danlei funciona en Clozure CL con una bandera especial, pero ¿alguien sabe cómo FUNCTION-LAMBDA-EXPRESSION para trabajar en SBCL?

+0

Tu definición es incorrecta: x es una función y no se puede usar con + – bandi

+0

bandi: 'x' es solo un símbolo. En ese contexto, se referiría a una variable. (Vea el ejemplo de Danlei a continuación.) – Ken

+0

Agregué una posible solución (no probada) para SBCL a mi respuesta. – danlei

Respuesta

8

Usted podría intentar FUNCTION-LAMBDA-EXPRESSION:

(function-lambda-expression #'foo) 

pero no es garantizado para trabajar ("... implementaciones son libres de volver` `nil, verdadera, nil '' en todos los casos ...").

Por ejemplo, en CCL:

CL-USER> (setq ccl:*save-definitions* t) 
T 
CL-USER> (defun x (x y) (+ x y)) 
X 
CL-USER> (function-lambda-expression #'x) 
(LAMBDA (X Y) (DECLARE (CCL::GLOBAL-FUNCTION-NAME X)) (BLOCK X (+ X Y))) 
NIL 
X 

En SBCL, puede intentar (setq sb-ext:*evaluator-mode* :interpret) (no probado). Tal vez haya otras maneras de lograr esto en SBCL (puede buscar un análogo de *save-definitions* o incluso probar diferentes configuraciones de OPTIMIZE), pero no las conozco. Tenga en cuenta que las funciones ingresadas en el REPL no se compilarán después de configurar *evaluator-mode* en :interpret, por lo que es probable que experimente un peor rendimiento.

+1

Encontré la razón por la que no pude hacer funcionar FUNCTION-LAMBDA-EXPRESSION en SBCL, aparentemente es un paso de optimización para no guardar una copia del sexp de una función si no está en línea Consulte https://bugs.launchpad.net/sbcl/+bug/560977 –

+0

@ ReubenPeter-Paul Como una breve actualización, se le preguntó recientemente a [una pregunta relacionada] (http://stackoverflow.com/q/18650988/1281433) , y parece que las versiones más recientes de SBCL (ver comentarios en [esta respuesta] (http://stackoverflow.com/a/18652612/1281433)) tienen un comportamiento diferente. –

2

En Common Lisp, se puede ser capaz de recuperar la definición de una función utilizando function-lambda-expression (ver el HyperSpec) o en algunas implementaciones uncompile-function.

0

Cuando yo era pasar tiempo en un proyecto para hacer la manipulación función significativa, era más fácil de hacer este tipo de cosas:

(defclass node() 
    (list-form 
    compiled-obj)) 

primer formulario de la lista que consiste en '(lambda foo (x) bar) se asignaría, luego compilaría Foo y lo asignaría a la ranura compiled-ojb.

Cuestiones relacionadas