Вопрос

Предположим, я определяю функцию во всем мире:

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

Можно ли «принуждать» функцию x в список, подобный:

(x (y) (1+ y))

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

PS-Пример Danlei работает в Clozure CL с специальным флагом, однако кто-нибудь знает, как заставить функциональную экспрессию-экспрессию для работы в SBCL?

Это было полезно?

Решение

Вы могли бы попробовать Функция-ламбда-экспрессия:

(function-lambda-expression #'foo)

Но это не гарантированно сработает («… реализации могут вернуть« ноль, правда, ноль »во всех случаях…»).

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

Другие советы

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

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

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

Сначала была бы назначена форма списка, состоящая из «(Lambda Foo (x) Bar), а затем я бы скомпилировал Foo и назначил его в слот скомпилированным ojb.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top