Compiler construction 方案运行时符号解引用

Compiler construction 方案运行时符号解引用,compiler-construction,scheme,Compiler Construction,Scheme,在Scheme中是否存在需要能够在运行时解引用符号的情况(如果需要的话,使用R7RS小符号)?我正在研究编写一个编译器,如果不需要运行时符号解引用,那么我将在编译时进行,因为这更容易,而且可能更有效 举个例子: (define (fac n) (if (> n 1) (* n (f (- n 1))) 1)) ; When I compile this, I know from the last line what fac is and can compile t

在Scheme中是否存在需要能够在运行时解引用符号的情况(如果需要的话,使用R7RS小符号)?我正在研究编写一个编译器,如果不需要运行时符号解引用,那么我将在编译时进行,因为这更容易,而且可能更有效

举个例子:

(define (fac n) 
  (if (> n 1) 
    (* n (f (- n 1)))
    1))

; When I compile this, I know from the last line what fac is and can compile this as a direct call to my compiled function, fac.
(fac 5)
考虑这一点:

(define (fac n) 
  (if (> n 1) 
    (* n (fac (- n 1)))
    1))

(fac 5) ;-> 120

(define fac2 fac)
(set! fac (lambda a 10))

(fac2 5) ;-> 50
所有变量都是可变的,每次运行函数时,函数体内对名称
fac
的引用都会继续从全局范围中查找定义,这意味着如果函数包含对全局变量的引用,则函数的行为随时都会发生变化,即使它的主体代码没有改变

如果您希望能够将事情优化到直接调用静态目标,则需要确保它们只在已知的封闭范围内搜索(不导出任何可能修改该变量本身的过程)。e、 g:

fac
的定义在
letrec
建立的范围内进行正文搜索,您可以静态地证明它从未被修改过,因此可以编译为一个简单的静态调用


您可以在相同的
let
块内编写多个函数的定义(取决于彼此和全局顶级的其他名称),以提供一个封闭的上下文,让它们在内部使用更高效的查找。这可能不是问题,因为他打算像斯大林(virgin Scheme,load,execute,exit)那样编译。我花了一段时间才发现问题。这是一个问题。那么运行时符号管理是必要的吗?在这一点上,编译不是几乎毫无意义吗?如果对变量的每个引用都必须经过运行时库,那么编译比解释有什么好处吗?@Tyler变量管理是必要的。。。你可能想在q中澄清一下。正是您所说的“符号”管理(Scheme不像某些Lisp那样具有动态符号查找)。以上内容只会影响顶层的可变变量,以及编译器无法证明它们从未被修改过的其他上下文中的可变变量——任何可以在局部范围或模块中永久捕获的内容都会提供大量优化机会。正确捕获算术运算符通常可以让一个好的编译器生成非常快的代码。
(define fac 
    (letrec ((fac (lambda (n)    
                     (if (> n 1) (* n (fac (- n 1))) 1) )))
      fac) )

(fac 5) ;-> 120
(define fac2 fac)
(set! fac (lambda a 10))                                   
(fac2 5) ;-> 120