Recursion 乔尔·斯波尔斯基在变量悖论中的意思是什么;s值不改变且同时改变?

Recursion 乔尔·斯波尔斯基在变量悖论中的意思是什么;s值不改变且同时改变?,recursion,scheme,purely-functional,Recursion,Scheme,Purely Functional,我大约在8个月前读过这本书,从那时起我就把它作为我应该很快学会的东西的清单。我理解他所说的大部分内容 然而,有一部分我不太确定: 在一个纯函数程序中,变量的值永远不会改变,但它却一直在改变!悖论 我从中得到的(如果我错了,请原谅我)是他在谈论递归,但递归似乎是一个太简单的概念。以下是我的想法: (define (tail-rec n) (if (= n 1) (display "Done!") (begin (display n) (new

我大约在8个月前读过这本书,从那时起我就把它作为我应该很快学会的东西的清单。我理解他所说的大部分内容

然而,有一部分我不太确定:

在一个纯函数程序中,变量的值永远不会改变,但它却一直在改变!悖论

我从中得到的(如果我错了,请原谅我)是他在谈论递归,但递归似乎是一个太简单的概念。以下是我的想法:

(define (tail-rec n) 
  (if (= n 1) 
    (display "Done!") 
    (begin 
       (display n)
       (newline) 
       (tail-rec (- n 1)))))
尾部递归函数
tail rec
中的
n
值还没有改变。当您查看正在输出的内容时,您会发现它实际上发生了变化。另外,由于函数本身不改变状态
对于任何变量,它都意味着它是纯函数。

我说的对吗?

这就是Joel所说的吗?如果不是,请纠正我。

为了回答你的问题,Joel的文章确实是在这个上下文中提到递归

然而,您的代码实际上并不是纯功能性的,因为
display
newline
有副作用。所以我要开始一个切线,给你们一些纯函数递归代码的具体例子

考虑一个函数:

(define (gcd x y)
  (if (zero? y)
      x
      (gcd y (modulo x y))))
这里,每当
x
除以
y
的余数不为零时,它(tail-)会再次递归调用
gcd
,在这个新调用中,
x
y
的值是不同的。(特别是,
y
值在每次迭代中变得更小,最终导致基本情况,即
x
精确地除以
y
,即使
y
必须为1才能发生。)

下面是纯函数递归的另一个例子(不过这次也不是尾部递归),用于实现合并两个排序的数字列表的算法:

(define (merge lhs rhs)
  (cond ((null? lhs) rhs)
        ((null? rhs) lhs)
        ((< (car rhs) (car lhs))
         (cons (car rhs) (merge lhs (cdr rhs))))
        (else
         (cons (car lhs) (merge (cdr lhs) rhs)))))

这是一个典型的例子。每次列表中有2个或更多元素时,将列表分成左右两半,递归到每一半,然后将排序后的两半重新合并在一起。

Ah!得了吧,已经有两张反对票了?我不想在这里主观。我只是想要一个答案。如果要让我得到答案,我将删除对Java学校学生的引用。在本例中,n本身不是一个变量,它是函数的形式参数,并且绑定在它自己的范围内。每个调用都有自己不同的N,但这个N永远不会改变。当您解除此调用时,每个n都有其自己的值,该值永远不会更改,但可能与其他n的值不同。而jave,你通常会把它当作i=0的for循环,我怀疑你得到负数的原因是因为你的例子不是纯粹的函数。是的,纯函数不使用赋值,但它们也不会产生副作用,或者有状态或顺序的概念。begin也不是非功能性的,因为它依赖于时间和顺序的概念,而不是评估或函数。
begin
是一种“纯功能性代码味道”,在这种情况下,它很少在副作用上下文之外使用,但它本身并没有本质上的副作用。我从未理解
打印
显示
功能是如何不完全起作用的。这些功能正在改变什么状态?输入/输出缓冲区?@Segfault,无论是打印到终端还是与数据库交互,任何IO都是副作用。纯函数与世界其他部分的唯一交互是通过其参数和返回值。
(define (mergesort lst)
  (let ((len (length lst)))
    (if (< len 2)
        lst
        (let-values (((lhs rhs) (split-at lst (quotient len 2))))
          (merge (mergesort lhs) (mergesort rhs))))))