如何测试动态范围是否在lisp中正确实现?

如何测试动态范围是否在lisp中正确实现?,lisp,dynamic-scope,Lisp,Dynamic Scope,我有。默认情况下,它有词法范围,但我刚刚添加了动态范围作为选项。如何测试我是否正确地实现了这一点: 此代码打印20和30: (define (foo x) (* x y)) (define y 1) (let ((y 2)) (print (foo 10)) (let ((y 3)) (print (foo 10)))) 所以y值是动态的,因为它在函数foo中发生了变化。我还需要做些什么来使lisp成为动态的还是这样 let和函数调用是唯一可以观察动态范围的地方吗

我有。默认情况下,它有词法范围,但我刚刚添加了动态范围作为选项。如何测试我是否正确地实现了这一点:

此代码打印20和30:

(define (foo x) (* x y))

(define y 1)

(let ((y 2))
   (print (foo 10))
   (let ((y 3))
       (print (foo 10))))
所以y值是动态的,因为它在函数foo中发生了变化。我还需要做些什么来使lisp成为动态的还是这样

let和函数调用是唯一可以观察动态范围的地方吗

我还需要做些什么来使lisp动态化,还是就是这样

事实上,
foo
看到了由
y
设置的绑定,这是一个重要的测试用例,它让我们相信动态范围正在进行

另一个重要的测试是显示动态绑定不是由词法闭包捕获的

假设我们绑定
y
,然后调用一个类似于
foo
的函数,该函数不只是基于
y
打印一个计算,而是捕获一个词法闭包,其主体就是这样做的。然后在绑定
y
的范围之外,我们调用返回的闭包。该闭包不能再看到我们绑定的
y
值。引用
y
的闭包主体必须始终在当前动态环境中看到
y
的值

您可能会认为这是理所当然的,但您会惊讶地发现,在一些动态范围的实现中很容易出错。如果您有某种用于实现动态范围的动态环境指针,并且该指针不知何故被卷入了词汇闭包oops中,那么现在就有了捕获动态环境的闭包。(当然,这可能是一个特性:“动态闭包”)。动态变量的“调用函数查看父绑定”方面在动态闭包下运行良好;这是一个独立的问题

作为旁注,如果您的
(define y 1)
正在创建一个动态变量,那么词法变量是如何定义的?如果您想在同一方言中同时支持动态范围和词法范围,那么必须有一种方法来指定哪些符号将遵循动态绑定,哪些符号将保留词法范围

也就是说,因为您支持动态范围“作为一个选项”,所以您需要有一种方法使其与默认的词法范围选项共存,并对此进行测试(您没有破坏词法范围)

Common Lisp通过将实际符号标记为特殊符号来实现这一点,这是通过
defvar
defparameter
完成的


在Scheme中,
(define…
表单不会做任何这样的事情,如果你让它这么做,你就破坏了语言;如果您想在保持与Scheme兼容的同时拥有类似CL的动态变量,您需要一些类似
(定义动态y…
)的其他形式,它将标记符号
y
,用于动态绑定。

@coredump如果变量未绑定,则从执行的范围中获取。这是动态范围,所以我认为它只适用于函数和let。我想问的是,如果是这样的话,或者我还需要做些什么来让lisp变得动态?“lisp是一个使用s表达式的语言家族”——s表达式对于更广泛的lisp家族中的一种语言来说既不是必要的,也不是充分的。请参阅Logo、RLISP、Dylan和其他。Scheme和一些Lisp可能在不同方面有所不同:例如,变量和函数是否在不同的名称空间中。例如,Common Lisp支持变量的动态绑定,但不支持函数的动态绑定。函数调用<代码>((lambda(y)(print(foo 10)))2,但这与let.相同。您可能还希望检查以下内容(假设
y
不是全局
2
((let((y2))(lambda()y)))
,它不应返回
2
。如果您有异常或其他非本地控制传输,您希望检查绑定在它们存在的情况下是否正常工作。我的动态作用域选项不是像CL中那样按变量,而是按解释器,因此我可以从单个库中创建动态语言或词汇语言。对于动态语言,我创建两个作用域动态和词法。
具有词法作用域,但函数调用具有未绑定变量的动态绑定。