Search code examples
debugginglispschememit-scheme

With MIT-Scheme, is there a way to inspect a compound-procedure object?


Using MIT-Scheme 9.x, is there a way using the debugger or some other tool to inspect an anonymous compound-procedure (created by returning a lambda function), e.g. to find out exactly what code at what line it comes from?

For example, I'm currently doing something like:

(foo 2 3)

And I see an error message like:

;The procedure #[compound-procedure 65] has been called with 2 arguments; it requires exactly 0 arguments.

...where foo is doing some further dispatch (foo is not the problem here, it lies deeper). In this example, I'd really want to know the internals of #[compound-procedure 65] as it's obviously not what I expected. Does a Lisp/Scheme wizard out there know a way to get those details? Thanks.


Solution

  • There are some interesting debugging tools described on this page: Debugging Aids.

    From the short experiment I tried, I think you can use the pp function to inspect the source of a compound procedure object:

    1 ]=> (define (sum-squares x y) (+ (* x x) (* y y)))
    
    ;Value: sum-squares
    
    1 ]=> (sum-squares 3)
    
    ;The procedure #[compound-procedure 13 sum-squares]
    ;has been called with 1 argument
    ;it requires exactly 2 arguments.
    ;To continue, call RESTART with an option number:
    ; (RESTART 1) => Return to read-eval-print level 1.
    
    2 error> (pp #[compound-procedure 13 sum-squares])
    (named-lambda (sum-squares x y)
      (+ (* x x) (* y y)))
    ;Unspecified return value
    
    2 error> 
    

    It appears that you can even get the source of lambda functions and compiled functions:

    1 ]=> (define (make-acc-gen n) (lambda (i) (set! n (+ n i)) n))
    
    ;Value: make-acc-gen
    
    1 ]=> (pp (make-acc-gen 0))
    (lambda (i)
      (set! n (+ n i))
      n)
    ;Unspecified return value
    
    1 ]=> display
    
    ;Value 15: #[compiled-procedure 15 ("output" #x16) #x1a #x101b23bd2]
    
    1 ]=> (pp  #[compiled-procedure 15 ("output" #x16) #x1a #x101b23bd2])
    (named-lambda (display object #!optional port environment)
      (let ((port (optional-output-port port 'display)))
        (unparse-object/top-level object port #f environment)
        ((%record-ref (%record-ref port 1) 14) port)))
    ;Unspecified return value
    
    1 ]=> 
    

    There's some other interesting reflection tools on the linked page. MIT Scheme also has a bunch of stuff for messing with environments as first class objects which can be useful for certain debugging tasks. Hope that helps!