根据我对尾递归的理解,以下函数不是尾递归函数。
(define (map f L)
(if (null? L)
'()
(cons (f (car L)) (map f (cdr L)))))
cons
必须等到(map f (cdr L))
返回才能完成其工作。这可以防止它被尾递归。
我是对的吗?
答案 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-rules
或call-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)))))