gpt4 book ai didi

lisp - 如何使用函数(或闭包)对象设置局部函数定义?

转载 作者:太空宇宙 更新时间:2023-11-03 18:37:58 24 4
gpt4 key购买 nike

flet 的问题是其中绑定(bind)的函数必须内联定义。换句话说,没有办法做到这一点:

(new-flet ((a (lambda (f x)
(funcall f (* x 2))))
(b (function-generator)))
(a #'b 10))

我考虑过自己定义这样一个宏,但问题是 flet 似乎是设置局部函数值的唯一方式。 symbol-function 始终只获取全局定义,function 不能与 setf 一起使用。任何人都知道如何相当干净地完成这项工作(如果有的话)?

最佳答案

你可以轻松地搭建一个蹦床

(defun function-generator (x)
(lambda (y) (* x y)))

(let ((fg (function-generator 42)))
(flet ((a (f x) (funcall f (* x 2)))
(b (x) (funcall fg x)))
(a #'b 10)))

new-flet的宏实现是

(defmacro new-flet (bindings &body body)
(let ((let-bindings (list))
(flet-bindings (list))
(args (gensym)))
(dolist (binding bindings)
(let ((name (gensym)))
(push `(,name ,(second binding))
let-bindings)
(push `(,(first binding) (&rest ,args)
(apply ,name ,args))
flet-bindings)))
`(let ,(nreverse let-bindings)
(flet ,(nreverse flet-bindings)
,@body))))

在您的示例中扩展为

(macroexpand-1 '(new-flet ((a (lambda (f x) (funcall f (* x 2))))
(b (function-generator)))
(a #'b 10)))

==> (LET ((#:G605 (LAMBDA (F X)
(FUNCALL F (* X 2))))
(#:G606 (FUNCTION-GENERATOR)))
(FLET ((A (&REST #:G604)
(APPLY #:G605 #:G604))
(B (&REST #:G604)
(APPLY #:G606 #:G604)))
(A #'B 10)))

关于lisp - 如何使用函数(或闭包)对象设置局部函数定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18362073/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com