gpt4 book ai didi

lambda - 在Scheme中让-over-lambda?

转载 作者:行者123 更新时间:2023-12-02 06:32:00 27 4
gpt4 key购买 nike

在 Common Lisp 中,如果我希望两个函数共享状态,我将按如下方式执行 let over lambda:

(let ((state 1))
(defun inc-state ()
(incf state))
(defun print-state ()
(format t "~a~%" state))

这些函数不是 let 的本地函数 - 它们是全局函数,维护对共享状态变量的引用,该变量本身从外部不可见。例如,我可以在代码中的其他位置执行以下操作:

(print-state)       => 1
(inc-state) => 2
(print-state) => 2

然而,在Scheme中,这样的构造声明了本地函数,这些函数从外部是不可见的:

(let ((state 1))
(define (print-state)
(print state))

(print-state)) => 1

(print-state) => error, no such variable print-state

我认为实现这种功能的唯一方法(除了在模块内使用未导出的全局变量之外)是这样的:

(define print-state #f)
(define inc-state #f)

(let ((state 1))
(set! print-state (lambda () (print state)))
(set! inc-state (lambda () (inc! state))))

在Scheme中是否有一种方法可以编写let-over-lambda形式,而无需诉诸如此丑陋的解决方法?或者我需要编写一个宏来包装这种丑陋吗? (顺便说一句,我知道 letrec,但这不是这个问题的解决方案。)

顺便说一句,我正在使用 Chicken Scheme,但我的问题应该与所有计划相关。

最佳答案

不幸的是,顶级绑定(bind)只能成为顶级,并且过程中的define实际上只是letrec的语法糖。在“鸡计划”中,您有一个名为 define-values 的表单,您可以在其中执行以下操作:

(define-values (print-state inc-state)
(let ((state 1))
(values (lambda () (print state))
(lambda () (inc! state)))))

请注意,define-values 不是任何标准的一部分,尽管它似乎是常见的形式。不过,使用您用来实现它的方法来创建一个宏会很容易。对于替代解决方案,您可以返回一个调度程序,您可以调用该调度程序来访问过程:

(define dispatcher
(let ((state 1))
(lambda (msg)
(case msg
((print) (lambda () (print state)))
((inc!) (lambda () (inc! state)))))))

(define print-state (dispatcher 'print))
(define inc-state (dispatcher 'inc!))

实际上,您不需要创建全局变量,因为您可以直接调用返回:

((dispatcher 'inc!))
((dispatcher 'inc!))
((dispatcher 'print)) ; ==> prints 3

关于lambda - 在Scheme中让-over-lambda?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39066621/

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