在 Scheme 中访问调用堆栈深度 [英] Accessing call stack depth in Scheme

查看:32
本文介绍了在 Scheme 中访问调用堆栈深度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了演示尾递归的有效性,我想在Scheme中动态访问调用栈的深度.

In order to demonstrate the effectiveness of tail recursion, I would like a way to access the depth of the call stack dynamically in Scheme.

有没有办法做到这一点?如果没有,有没有办法在其他主要的函数式语言(OCaml、Haskell 等)中做到这一点?

Is there a way to do this? If not, is there a way to do this in other major functional languages (OCaml, Haskell, etc.)?

推荐答案

Racket 允许您在调用堆栈中存储值.您可以使用它来跟踪深度.这是我的做法:

Racket allows you to store values in the call stack. You can use this to keep track of the depth. Here is how I would do it:

#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 中增加.

The output shows that the depth doesn't increase in foo and that it does in bar.

这篇关于在 Scheme 中访问调用堆栈深度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆