Hello
I want to be able to see the values which are visible by some closure (without having to enter the closure with the stepper and look at the ,e output, and I'd like to be able to do that also for compiled code (if compiled with the 'debug option)).
Since in Scheme (or functional languages in general), closures are a common alternative to structures for storing data, they should be as easily inspectable (for debugging purposes at least) as the latter.
Sometimes I'm using ##vector-ref for checking the contents of a closure data structure, but that's rather tedious, since the relationship between the variable name and the index in the structure isn't straight-forward. (See below for an example where I'm trying to get at the relevant information through manual inspection.)
I'm imagining something like:
(procedure-prettyprint/environment someclosure)
#<procedure #2 someclosure len: 5 data: #(0 0 0 0 0) pos: 0>
where len, data and pos are the bindings which are being stored along with the closure and maybe also those stored with their "parents" (if chaining of environments is being used; it seems that the gambit compiler is using boxing and stores away a copy of the reference to the box directly with the closure instead of chaining).
Would it be possible to display the above data from the currently available data structures? Do you imagine I could implement it myself?
Thanks Christian.
(define showval (gensym))
(define (alternator len) (let* ((data (make-vector len)) (pos 0) (incpos! (lambda () (set! pos (let ((p (+ pos 1))) (if (>= p len) 0 p)))))) (lambda (#!optional v) (cond ((eq? v showval) (vector len data pos)) (v (incpos!) (vector-set! data pos v)) (else (incpos!) (vector-ref data pos))))))
When run in the interpreter:
(define a (alternator 5)) (##vector-length a)
4
(##vector-ref a 0)
#<procedure #2>
(pp #2)
#<procedure #2> -> must be compiled, thus (in this case) be some gambit internal
(##vector-ref a 1)
#(#(#(#(#(#(#(#f #<procedure #3 ##cprc-seq> #(#(#(#(#....endless
(##vector-ref a 2)
#<procedure #4 a>
(pp #4)
(lambda (#!optional v) (cond ((eq? v showval) (vector len data pos)) (v (incpos!) (vector-set! data pos v)) (else (incpos!) (vector-ref data pos))))
(##vector-ref a 3)
#(#(#(#(#f #<procedure #5 alternator> 5) #(0 0 0 0 0)) 0) #<procedure #6>)
(pp #5)
(lambda (len) (let ((data (make-vector len))) (let ((pos 0)) (let ((incpos! (lambda () (set! pos (let ((p (+ pos 1))) (if (>= p len) 0 p)))))) (lambda (#!optional v) (cond ((eq? v showval) (vector len data pos)) (v (incpos!) (vector-set! data pos v)) (else (incpos!) (vector-ref data pos))))))))
(pp #6)
(lambda () (set! pos (let ((p (+ pos 1))) (if (>= p len) 0 p))))
When compiled with 'debug:
(bruse exp-closuredisplay) (define a (alternator 5)) (##vector-length a)
4
(##vector-ref a 0)
#<procedure #2>
(pp #2)
(lambda (#!optional v) (cond ((eq? v showval) (vector len data pos)) (v (incpos!) (vector-set! data pos v)) (else (incpos!) (vector-ref data pos))))
(##vector-ref a 1)
#(0 0 0 0 0)
(##vector-ref a 2)
5
(##vector-ref a 3)
#&0