2

無限ループのような長時間機能:

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

Chez スキームでは、make-engine はティック後に停止することができます。

> (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. はいの場合、スキームでこれを達成するためのより良い方法はありますか?
  3. この種のデバッグをより簡単に実装できるプログラミング言語はありますか?
4

1 に答える 1

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 回ごとに変数を調べることができます。

ハッピーデバッグ:)

于 2013-03-04T18:53:56.553 に答える