В LISP возможно ли получить доступ к форме функции? - PullRequest
5 голосов
/ 01 мая 2011

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

(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?

Ответы [ 3 ]

8 голосов
/ 01 мая 2011

Вы можете попробовать 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, поэтому вы, вероятно, будете испытывать худшую производительность.

2 голосов
/ 01 мая 2011

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

0 голосов
/ 03 мая 2011

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

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

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

...