首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scheme语言中的词法解释程序与动态解释程序

Scheme语言中的词法解释程序与动态解释程序
EN

Stack Overflow用户
提问于 2021-08-10 10:47:59
回答 3查看 70关注 0票数 2

我仍然不明白动态解释器和词法解释器有什么不同。

我正在研究scheme,我发现很难知道像这样一个简单的代码是如何动态和词汇地工作的。

代码语言:javascript
复制
(define mystery
  (let ((x 2018))
    (lambda (y)
      (let ((result (cons x y)))
         (set! x (+ x 1))
         result))))

有什么建议吗?

EN

回答 3

Stack Overflow用户

发布于 2021-08-10 11:20:27

词法绑定具有有限的可见性和无限的生命周期。所有函数都“记住”它们创建的环境--这类函数称为lexical closures

在您的示例中,这一部分:

代码语言:javascript
复制
(let ((x 2018))
    (lambda (y) (let ((result (cons x y)))
                  (set! x (+ x 1)) result))))

返回函数,记忆x= 2018的环境。该函数绑定到symbol mystery,当您调用它时,它会更改环境中x值。

代码语言:javascript
复制
> (mystery 1)
'(2018 . 1)
> (mystery 1)
'(2019 . 1)

在动态绑定方案(无限的可见性,有限的生命周期)中,函数不会记住它们创建的环境。因此,函数mystery不会记住x= 2018的环境,并且在计算(cons x y)时调用(mystery 1)会以错误结束,因为符号x没有值。

票数 1
EN

Stack Overflow用户

发布于 2021-08-13 11:45:50

让我们用你的代码编写一个程序:

代码语言:javascript
复制
;; a global binding
(define x 100)

;; your function
(define mystery
  (let ((x 2018))
    (lambda (y)
      (let ((result (cons x y)))
         (set! x (+ x 1))
         result))))

;; just to add newlines in prints
(define displayln
  (lambda (v) 
    (display v)
    (newline)))

;; a indirect call
(define local-test 
  (lambda (x)
    (displayln x)
    (displayln (mystery 'local))
    (displayln (mystery 'local))
    (displayln x)))

(define global-test
  (lambda ()
    (displayln x)
    (displayln (mystery 'global))
    (displayln (mystery 'global))
    (displayln x)))

;; program
(local-test 1)
(local-test 11)
(global-test 1)
(global-test 11)

正常方案的结果仅依赖于闭包,而不依赖于调用堆栈绑定变量:

代码语言:javascript
复制
1
(2018 local)
(2019 local)
1
11
(2020 local)
(2021 local)
11
1
(2022 global)
(2023 global)
1
11
(2024 global)
(2025 global)
11

来自动态“方案”的结果具有作为死代码的秘密。它不做任何事情,因为绑定没有与函数对象一起保存。因此,只有active let和calls中的变量匹配:

代码语言:javascript
复制
1
(1 local)
(2 local)
3
11
(11 local)
(12 local)
13
100
(100 global)
(101 global)
102
102
(102 global)
(103 global)
104
票数 0
EN

Stack Overflow用户

发布于 2021-08-24 14:54:36

代码语言:javascript
复制
(define mystery
  (let ((x 2018))
    (lambda (y)
      (let ((result (cons x y)))
         (set! x (+ x 1))
         result))))

这不是一个很好的例子来理解动态绑定和静态绑定之间的区别。这只是一个转折点。

其思想是,在静态绑定中,自由变量与静态作用域(编写时可见的词法代码)相关联,而在动态绑定中,它们与动态代码(存储在执行堆栈中的代码)相关联。

您的代码的计算结果是一个result,它是这个lambda表达式:

代码语言:javascript
复制
(lambda (y)
  (let ((result (cons x y)))
    (set! x (+ x 1))
    result))

在这个结果中,惟一的自由变量是X

将结果应用于Y的值时,X的值是多少

在静态作用域中,它将是2018年,在动态绑定中,X的值将存储在堆栈上--例如,

代码语言:javascript
复制
(define X 100)
(define F (result 200)))

将应用具有绑定X=100result (X将保留在堆栈上)。当然,X的值不是物理上保存在堆栈上的,只是指向它所在的环境帧的指针,或者如果在环境上执行了重新定位,则可能在值单元格中,等等。

为了理解你的误解,你可以上一个lambda微积分的课程。当然,我在这里所说的假设你使用通用的解释,许多其他解释可以与你的输入示例的语法相关联,等等。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68725395

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档