A good way to explore in detail what a Scheme procedure does is to set
a trap on it and then single step through what it does. To do this,
make and install a <procedure-trap> with the debug-trap
behaviour from (ice-9 debugging ice-9-debugger-extensions).
The following sample session illustrates this. It assumes that the
file matrix.scm defines a procedure mkmatrix, which is
the one we want to explore, and another procedure do-main which
calls mkmatrix.
$ /usr/bin/guile -q
guile> (use-modules (ice-9 debugger)
(ice-9 debugging ice-9-debugger-extensions)
(ice-9 debugging traps))
guile> (load "matrix.scm")
guile> (install-trap (make <procedure-trap>
#:procedure mkmatrix
#:behaviour debug-trap))
guile> (do-main 4)
This is the Guile debugger -- for help, type `help'.
There are 3 frames on the stack.
Frame 2 at matrix.scm:8:3
[mkmatrix]
debug> next
Frame 3 at matrix.scm:4:3
(let ((x 1)) (quote this-is-a-matric))
debug> info frame
Stack frame: 3
This frame is an evaluation.
The expression being evaluated is:
matrix.scm:4:3:
(let ((x 1)) (quote this-is-a-matric))
debug> next
Frame 3 at matrix.scm:5:21
(quote this-is-a-matric)
debug> bt
In unknown file:
?: 0* [primitive-eval (do-main 4)]
In standard input:
4: 1* [do-main 4]
In matrix.scm:
8: 2 [mkmatrix]
...
5: 3 (quote this-is-a-matric)
debug> quit
this-is-a-matric
guile>
Or you can use Guile's Emacs interface (GDS), by using the module
(ice-9 gds-client) instead of (ice-9 debugger) and
(ice-9 debugging ice-9-debugger-extensions), and changing
debug-trap to gds-debug-trap. Then the stack and
corresponding source locations are displayed in Emacs instead of on
the Guile command line.