这个尾巴是递归的吗?

时间:2014-03-14 15:48:57

标签: scheme tail-recursion

根据我对尾递归的理解,以下函数不是尾递归函数。

(define (map f L)
  (if (null? L)
    '()
    (cons (f (car L)) (map f (cdr L)))))

cons必须等到(map f (cdr L))返回才能完成其工作。这可以防止它被尾递归。

我是对的吗?

3 个答案:

答案 0 :(得分:5)

是!

对于Stack Exchange来说,答案显然不够长。

是的,顶上有樱桃!

答案 1 :(得分:4)

可以安全地假设它不是尾递归的,因为标准(RNRS,包括最新的R7RS)不需要tail recursion modulo cons优化。

那当然不会拒绝任何人在他们的Scheme实现中实际实现TRMCO,以便你的map的定义,几乎尾递归(除了那个 cons ),真的会变成尾递归。这样的实现可以通过将代码转换为类似下面的代码来实现:

#!r6rs
(import (except (rnrs) map)
        (rnrs mutable-pairs))

(define (map fun lst)
  (define result (cons 'head '()))
  (let loop ((tail result) (lst lst))
    (cond ((null? lst) (cdr result))
          (else (set-cdr! tail (cons (fun (car lst)) '()))
                (loop (cdr tail) (cdr lst))))))

转换非常简单,所以我真的不明白为什么Scheme实现不会在Prolog做的时候自动完成。它不像实现支持syntax-rulescall-with-current-continuation所需的那样复杂。

答案 2 :(得分:3)

是的,它不是尾递归的。

尾递归是指递归调用处于尾部位置。生成返回的调用应该是原始函数或相互尾递归函数,如此

(define (even? int)
  (if (= 0 int) #t (odd? (- int 1))))

(define (odd? int)
  (if (= 1 int) #t
      (if (= 0 int) 
          #f
          (even? (- int 1)))))