Scheme 在递归调用方案期间,“let”创建的局部变量的状态是否发生变化?

Scheme 在递归调用方案期间,“let”创建的局部变量的状态是否发生变化?,scheme,Scheme,比如说, 我想检查元素是否在列表中。算法很简单,让我们用C语言来实现++ bool element_of( const std::vector<int>& lst, int elem ) { for( int i( 0 ), ie = lst.size(); i < ie; ++i ) if( elem == lst[i] ) return true; return false; } 谢谢,每个Let调用都会在

比如说,

我想检查元素是否在列表中。算法很简单,让我们用C语言来实现++

bool element_of( const std::vector<int>& lst, int elem ) {
    for( int i( 0 ), ie = lst.size(); i < ie; ++i ) 
        if( elem == lst[i] )
            return true;
    return false;
}

谢谢,

每个
Let
调用都会在
Let
主体正在评估的环境中创建一组新的变量。
Let
语法是使用传递给lambda的已求值参数求值的lambda的“语法糖”。比如说

(let ((a (func object))
      (b (func object2)))
     (cons a b))
和写作一样

((lambda (a b) (cons a b)) (func object) (func object2))
因此,您可以看到在
Let
语法中,首先计算参数,然后计算主体,并且在本地环境范围中使用
a
b
的定义。因此,如果递归调用
Let
,每次输入
Let
调用的主体时,都是在新环境中评估主体(因为主体位于新定义的lambda中),并且在本地
Let
范围中定义的参数的定义将不同(它们实际上是新的lambda设置的嵌套环境中的新变量,而不是简单的变量或被重新定义的变量,就像在C++循环中找到的那样)。

另一种说法是,变量是一个C++递归函数中的局部变量变量……对于每个函数的堆栈帧,局部范围的变量将有自己的定义,以及它们自己的内存位置…它们不是在循环中使用相同内存变量的循环变量。局部范围内的les

希望这有帮助


Jason

始终重新初始化变量;这很明显,因为您必须始终提供新的绑定值。例如

(let ((a 42))
  ...)
中,
a
始终以42开头。它不会“保留”以前调用的值


顺便说一下,我想你是想写
(或result(equal?elem x))
而不是
(if(eq?elem x)(或result#t)result)
:-)

<代码>(或结果(相等),代码> <代码>转换为以下C++代码:

return result || elem == x;

(当然,假设
=
操作符已被重载,以执行
equal?
所做的操作。)这样做的好处是,如果
结果已为真,则不会执行进一步的比较。

是的,您是对的。当试图转移我的C++想法时,我就被那个想法所困扰。谢谢,谢谢。所以我猜Scheme的局部变量机制和命令式语言完全一样。。。Scheme的环境模型是必要的,因为Scheme不是一种“纯”函数式语言,因为它允许变量的可变性。基本上,所有变量都是保存在“环境”中的符号,环境基本上是一个符号表。
(定义a b)
关键字将符号
a
添加到本地环境(符号表),并将其绑定到
b
的评估值。再次调用
a
上的
define
会将
a
重新绑定到其他对象,除非您在新环境中调用它,在这种情况下,它会将新的
a
添加到符号表中,屏蔽旧值的可用性。有关Scheme环境模型的更多信息,请查看以下链接:和此链接:
return result || elem == x;