gpt4 book ai didi

closures - 是否有一个 let/flet/标签之类的概念用于绑定(bind)闭包以避免 funcall?

转载 作者:行者123 更新时间:2023-12-01 11:22:54 24 4
gpt4 key购买 nike

一边检查let over lambda我碰巧遇到

(defmacro! dlambda (&rest ds)
`(lambda (&rest ,g!args)
(case (car ,g!args)
,@(mapcar
(lambda (d)
`(,(if (eq t (car d))
t
(list (car d)))
(apply (lambda ,@(cdr d))
,(if (eq t (car d))
g!args
`(cdr ,g!args)))))
ds))))

他们随后像这样调用:
(setf (symbol-function 'count-test)
(let ((count 0))
(dlambda
(:inc () (incf count))
(:dec () (decf count)))))

是否有像 flet/labels/let 我可以将结果闭包绑定(bind)到的构造,以避免以全局方式使用 funcall 或 setf 符号函数?所以我可以做类似的事情:
(with-closures ((counter (let ((count 0))
(dlambda
(:inc () (incf count))
(:dec () (decf count))))))
(counter :incf))

最佳答案

你可以写一个宏:

(defmacro as-functions ((&rest names) &body body)
(assert (every #'symbolp names) () "Names must be symbols")
(let ((args (copy-symbol :args)))
`(flet
,(mapcar (lambda (n) `(,n (&rest ,args) (apply ,n ,args))) names)
,@body)))

对于每个符号 snames ,将函数命名空间中的此符号绑定(bind)到变量命名空间中此符号当前绑定(bind)的函数。这可以隐藏任何已命名的函数 s在当前的词法范围内,但由于它是显式完成的,程序员不应该感到意外。
例如:
(let ((a (lambda (u) (+ 3 u)))
(b (lambda (u) (* 2 u))))
(as-functions (a b)
(a (b 3))))

...宏扩展为:
(LET ((A (LAMBDA (U) (+ 3 U))) (B (LAMBDA (U) (* 2 U))))
(FLET ((A (&REST #:ARGS)
(APPLY A #:ARGS))
(B (&REST #:ARGS)
(APPLY B #:ARGS)))
(A (B 3))))

...并评估为 9。

与绑定(bind)构造相反,这可以与函数参数一起使用:
(defun compose (f g)
(as-functions (f g)
(lambda (x) (f (g x)))))

也提供绑定(bind)

根据 jkiiski 的评论,这里是接受 (name fun) 的修改版本除了单个符号之外的绑定(bind)。这看起来像 FLET ,除了函数可以在运行时计算。
(defmacro as-functions ((&rest names) &body body)
(let ((args (copy-symbol :args)))
`(flet
,(mapcar
(lambda (name)
(etypecase name
(symbol `(,name (&rest ,args) (apply ,name ,args)))
(cons (destructuring-bind (name fun) name
`(,name (&rest ,args) (apply ,fun ,args))))))
names)
,@body)))

所以:
(defun thing (f g h)
(as-functions (f (k (compose g h)))
(f (k 3))))


编辑:我记得以前读过这样的宏,使用 MACROLET : 见 this reply来自 comp.lang.lisp 中 Erik Naggum 的 Re:为什么 Scheme 不是 Lisp?

关于closures - 是否有一个 let/flet/标签之类的概念用于绑定(bind)闭包以避免 funcall?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40245645/

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