为了演示尾递归的有效性,我想要一种在Scheme中动态访问调用堆栈深度的方法。
有没有办法做到这一点?如果没有,有没有办法在其他主要函数语言(OCaml、Haskell 等)中做到这一点?
Racket 允许您在调用堆栈中存储值。
您可以使用它来跟踪深度。
我将这样做:
#lang racket
;;; This module holds the tools for keeping track of
;;; the current depth.
(module depth racket
(provide (rename-out [depth-app #%app])
current-depth)
(define (extract-current-continuation-marks key)
(continuation-mark-set->list (current-continuation-marks) key))
(define (current-depth)
(car (extract-current-continuation-marks 'depth)))
(define-syntax (depth-app stx)
(syntax-case stx ()
[(_depth-app proc args ...)
#'(let ([p (with-continuation-mark 'depth (+ (current-depth) 1)
proc)]
[as (with-continuation-mark 'depth (+ (current-depth) 1)
(list args ...))])
(apply p as))])))
;;; Importing the #%app from the depth module will override
;;; the standard application to use depth-app which keeps
;;; track of the depth.
(require 'depth)
(with-continuation-mark 'depth 0 ; set the initial depth to 0
(let ()
;;; Example: foo is tail recursive
(define (foo n)
(displayln (list 'foo n (current-depth)))
(if (< n 5)
(foo (+ n 1))
'done))
;;; bar is not tail recursive
(define (bar n)
(displayln (list 'bar n (current-depth)))
(if (< n 5)
(cons n (bar (+ n 1)))
'()))
;;; Call the examples
(foo 0)
(bar 0)))
输出是:
(foo 0 2)
(foo 1 2)
(foo 2 2)
(foo 3 2)
(foo 4 2)
(foo 5 2)
(bar 0 2)
(bar 1 3)
(bar 2 4)
(bar 3 5)
(bar 4 6)
(bar 5 7)
'(0 1 2 3 4)
输出显示深度没有增加foo
它确实在bar
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)