Так что я подумал, что одним из преимуществ lisp (среди других языков) является его способность реализовывать фабрики функций (принимать функции в качестве аргументов; возвращать новые функции). Я хочу использовать эту возможность, чтобы внести небольшие изменения в функцию и сохранить ее как новую функцию, чтобы в случае внесения изменений в исходную функцию они также отражались в новой функции, на которой она основана. Примечание: я не тот, кто пишет оригинальную функцию, поэтому я не могу обязательно инкапсулировать общие части в отдельную функцию, которая будет вызываться обеими, что в противном случае было бы очевидным ответом.
Пример игрушки в emacs lisp (возможно, не самый идеальный, поскольку это lisp-2):
У меня есть функция, foo
, которая мне предоставлена:
(defun foo (x y)
(+ x y)))
Я хочу, чтобы моя новая функция включала оператор, который позволяет мне изменять значение переменной, если выполняется определенное условие. Например:
(defun newfoo (x y)
(if (condition-met-p x)
(setq x (transform x)))
(+ x y))
Пожалуйста, не обращайте внимания на то, что я мог бы использовать defadvice
в этом конкретном примере, так как меня больше интересует общая задача модификации функций, где defadvice
может не применяться. Я считаю, что могу изменить тело с помощью этой формы:
(setq conditional-transformation
'(if (condition-met x) (setq x (transform x))))
(setq newbody (append conditional-transformation
(nth 2 (symbol-function 'foo)))))
Мои вопросы конкретно о том, как
- создать копию от
foo
до newfoo
и заменить тело значением
newbody
определено выше. (Я
заглянул в fset
, setf
и
function
но, возможно, не используя
их правильно.)
- возможно, обернуть это в функцию
называется
makenewfoo()
или что-то
так, чтобы я мог ссылаться
makenewfoo(foo)
и позвольте этому
создать newfoo()
.
И, в более общем смысле,
- что-то вроде этого обычно
сделано или есть более идиоматический
способ изменить функции?
- это очень простой случай, но
есть более общий способ, чем
указание номера элемента списка
nth
для модификации. За
Например, фактическая функция
более сложный, так есть ли способ
рекурсивно искать вниз по этому
дерево s-выражения и тест для
конкретный синтаксис и вставить это
conditional-transformation
выражение до или после него
(возможно, используя equal
), так что это
менее чувствительны к изменениям, внесенным в
оригинальная функция?