在一定时间后调试封闭变量的程序化方法

时间:2012-07-25 20:11:38

标签: debugging timeout scheme

像无限循环这样的长期函数:

> (define appendInf
      (lambda (lst)
        (appendInf (cons 1 lst)))

在Chez Scheme中,make-engine可以在ticks之后停止:

> (define eng
    (make-engine 
      (lambda ()
        (appendInf '()))))

当然,在lst的范围内,我在以下情况下会遇到错误:

> (eng 50
        list
        (lambda (new-eng)
          (set! eng new-eng)
          (length lst)))
Exception: variable lst is not bound

如果我想在达到时间限制时在appendInf中获取值'lst',我使用set!:

> (define lst '())
> (define appendInf
      (lambda (ls)
        (set! lst (cons 1 ls))
        (appendInf lst)))

现在我可以得到:

> (eng 50
       list
       (lambda (new-eng)
         (set! eng new-eng)
         (length lst)))
8

因此,对于我想要跟踪的函数中的每个变量,需要添加一个全局变量,并通过添加(set!...)再进行一次变换。

  1. 这是处理任何封闭变量的正确方法吗?
  2. 如果是1,那么在Scheme中有更好的方法来实现这个目标吗?
  3. 是否有任何编程语言可以更容易 实现这种调试?

1 个答案:

答案 0 :(得分:0)

好。我正在使用球拍,它有一个非常好的调试器,标准r6rs和非标准球拍。

;; macro to do the heavy work
(define-syntax recdb
  (syntax-rules ()
    ((_ thunk fun a1 ...)
     (let ((orig-fun fun)(ethunk thunk))
       (fluid-let ((fun (lambda args 
                          (if (ethunk)
                              (apply orig-fun args) ;; set breakpoint on this
                              (apply orig-fun args)))))
         (fun a1 ...))))))

;; a time-thunk generator
(define (period-sec sec)
  (let ((time-done (+ sec (current-seconds))))
    (lambda ()
      (if (< time-done (current-seconds))
          (begin 
            (set! time-done (+ sec (current-seconds)))
            #t)
          #f))))

;; a round-thunk generator
(define (rounds n)
  (let ((rounds-to-go n))
    (lambda ()
      (if (zero? rounds-to-go)
          (begin
            (set! rounds-to-go (- n 1))
            #t)
          (begin
            (set! rounds-to-go (- rounds-to-go 1))
            #f)))))

;; my never ending procedure
(define (always n)
  (always (+ n 1)))

;; one of the ones below to implement 
(recdb (rounds 10) always 0))
(recdb (period-sec 1) always 0)

;; functions with auxillary procedures need to have their gut changed for it to work
(define (fib n)
  (define (fib-aux n a b)
    (if (= n 0)
        a
        (fib-aux (- n 1) b (+ a b))))
  (recdb (period-sec 2) fib-aux n 0 1))

 ;; trying it
 (fib 200000)

现在。只需运行调试器并设置断点(在宏中右键单击表达式并选择“此时暂停”),在代码中指示它,您可以每隔x秒或x次检查变量。

快乐的调试:)