首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >let在尾递归中是作为goto指令工作的吗?

let在尾递归中是作为goto指令工作的吗?
EN

Stack Overflow用户
提问于 2014-11-03 08:12:43
回答 2查看 85关注 0票数 0

我在Scheme中找到了二进制搜索的以下实现:

代码语言:javascript
复制
(define (binary-search value vector)
  (let helper ((low 0)
               (high (- (vector-length vector) 1)))
    (if (< high low)
        #f
        (let ((middle (quotient (+ low high) 2)))
          (cond ((> (vector-ref vector middle) value)
                 (helper low (- middle 1)))
                ((< (vector-ref vector middle) value)
                 (helper (+ middle 1) high))
                (else middle))))))

根据它在注释中的说明,上面的函数使用尾递归来调用help函数。我想知道这是否像GOTO指令一样工作,因为我没有看到对二进制搜索函数的适当的“递归”调用。

在这种情况下,可以说它像goto指令一样工作?

EN

回答 2

Stack Overflow用户

发布于 2014-11-03 08:18:51

您看到的内容称为命名let。(如果你感兴趣,我写了一个blog post about how named let works。)您拥有的代码与以下代码完全相同:

代码语言:javascript
复制
(define (binary-search value vector)
  (define (helper low high)
    (if (< high low)
        #f
        (let ((middle (quotient (+ low high) 2)))
          (cond ((> (vector-ref vector middle) value)
                 (helper low (- middle 1)))
                ((< (vector-ref vector middle) value)
                 (helper (+ middle 1) high))
                (else middle)))))
  (helper 0 (- (vector-length vector) 1)))

换句话说,它是尾递归,在helper上,而不是在binary-search上。但是尾部递归正在发生。

有些人认为尾递归类似于goto,但我不认为这是一个有帮助的比较。两者之间唯一的共同点是,您可以使用尾递归实现循环,就像您可以使用goto一样。但相似之处到此为止:尾递归是一种特殊的递归(用尾部调用替换当前调用帧),但它仍然是递归;goto跳到代码中的任意点,但它是与递归无关的完全命令式操作。

票数 2
EN

Stack Overflow用户

发布于 2014-11-03 08:29:53

let只是lambdas的语法糖。举个例子:

代码语言:javascript
复制
(let ((i 2)
      (j 5)
  (* i j))

等同于

代码语言:javascript
复制
((lambda (i j) (* i j)) 2 5)

代码中的let称为命名let,因为您为它提供了标签。所以基本上,你伪装的lambda与一个名字绑定在一起。从这个意义上说,它是一个goto。但是,您需要在let的作用域中才能“跳转”到它。该函数是尾递归的,因为您没有延迟任何计算。在任何时间点,您只需要i和j的当前值即可继续进行计算。

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

https://stackoverflow.com/questions/26706041

复制
相关文章

相似问题

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