В LISP можно получить доступ к форме функции?

Предположим, я определяю функцию глобально:

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

Можно ли «принудить» функцию x к списку, например:

(x (y) (1+ y))

Заранее спасибо!

PS - пример @Danlei работает в Clozure CL со специальным флагом, однако кто-нибудь знает, как заставить FUNCTION-LAMBDA-EXPRESSION работать в SBCL?


person Reuben Peter-Paul    schedule 30.04.2011    source источник
comment
Ваше определение ошибочно: x — это функция, и ее нельзя использовать с +   -  person bandi    schedule 01.05.2011
comment
bandi: x это просто символ. В этом контексте будет ссылаться на переменную. (См. пример danlei ниже.)   -  person Ken    schedule 01.05.2011
comment
Я добавил в свой ответ возможное (непроверенное) решение для SBCL.   -  person danlei    schedule 01.05.2011
comment
FUNCTION-LAMBDA-EXPRESSION работает в CLISP "из коробки". Я понимаю, что некоторые спецификации в CL интерпретируются по-разному, и этот случай - один из них...   -  person Reuben Peter-Paul    schedule 01.05.2011
comment
Я нашел похожую тему здесь: lispforum.com/viewtopic.php?f=2&t =153   -  person Reuben Peter-Paul    schedule 01.05.2011


Ответы (3)


Вы можете попробовать FUNCTION-LAMBDA-EXPRESSION:

(function-lambda-expression #'foo)

Но не гарантируется, что это сработает ("... реализации могут возвращать "nil, true, nil" во всех случаях...").

Например, в 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

В SBCL вы можете попробовать (setq sb-ext:*evaluator-mode* :interpret) (не проверено). Может быть, есть другие способы добиться этого в SBCL (можно поискать аналог *save-definitions* или даже попробовать другие настройки OPTIMIZE), но я о них не знаю. Имейте в виду, что функции, введенные в REPL, не будут скомпилированы после установки *evaluator-mode* в :interpret, поэтому вы, вероятно, столкнетесь с более низкой производительностью.

person danlei    schedule 30.04.2011
comment
Я нашел причину, по которой я не мог заставить FUNCTION-LAMBDA-EXPRESSION работать в SBCL, по-видимому, это шаг оптимизации, чтобы не сохранять копию sexp функции, если она не встроена. См. bugs.launchpad.net/sbcl/+bug/560977. - person Reuben Peter-Paul; 01.05.2011
comment
@ReubenPeter-Paul В качестве краткого обновления недавно был задан связанный вопрос, и похоже, что более новые выпуски SBCL (см. комментарии к этому ответу) ведут себя по-разному. - person Joshua Taylor; 06.09.2013

В Common Lisp вы можете восстановить определение функции, используя function-lambda-expression (см. htm" rel="nofollow">HyperSpec) или в некоторых реализациях uncompile-function.

person Terje Norderhaug    schedule 30.04.2011

Когда я тратил время на проект, связанный со значительными манипуляциями с функциями, проще всего было сделать следующее:

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

Сначала будет назначена форма списка, состоящая из '(лямбда foo (x) bar), затем я скомпилирую Foo и назначу ее слоту скомпилированного ojb.

person Paul Nathan    schedule 03.05.2011