Gauche doesn’t have much support for debugging yet. The idea of good debugging interfaces are welcome.
For now, the author uses the classic ’debug print stub’ technique
when necessary. Gauche’s reader supports special syntaxes
beginning with #?
, to print the intermediate value.
The syntax #?=expr
shows expr itself before
evaluating it, and prints its result(s) after evaluation.
gosh> #?=(+ 2 3) #?="(stdin)":1:(+ 2 3) #?- 5 5 gosh> #?=(begin (print "foo") (values 'a 'b 'c)) #?="(stdin)":2:(begin (print "foo") (values 'a 'b 'c)) foo #?- a #?+ b #?+ c a b c
Note: If the debug stub is evaluated in a thread other than
the primordial thread (see gauche.threads
- Threads), the output
includes a number to distinguish which thread it is generated.
In the following example, #<thread ...>
and the prompt
is the output of REPL in the primordial thread,
but following #?=[1]...
and #?-[1]...
are
the debug output from the thread created by make-thread
.
The number is for debugging only—
they differ for each thread, but other than that there’s no meaning.
gosh> (use gauche.threads) gosh> (thread-start! (make-thread (^[] #?=(+ 2 3)))) #<thread #f (1) runnable 0xf51400> gosh> #?=[1]"(standard input)":1:(+ 2 3) #?-[1] 5
The syntax #?,(proc arg …)
is specifically
for procedure call; it prints the value of arguments right before
calling proc, and prints the result(s) of call afterwards.
gosh> (define (fact n) (if (zero? n) 1 (* n #?,(fact (- n 1))))) fact #?,"(standard input)":4:calling `fact' with args: #?,> 4 #?,"(standard input)":4:calling `fact' with args: #?,> 3 #?,"(standard input)":4:calling `fact' with args: #?,> 2 #?,"(standard input)":4:calling `fact' with args: #?,> 1 #?,"(standard input)":4:calling `fact' with args: #?,> 0 #?- 1 #?- 1 #?- 2 #?- 6 #?- 24 120
Internally, the syntax #?=x
and #?,x
are read
as (debug-print x)
and (debuf-funcall x)
,
respectively, and the macros debug-print
and debug-funcall
handles the actual printing. See Debugging aid, for more details.
The reasons of special syntax are: (1) It’s easy to insert the debug stub, for you don’t need to enclose the target expression by extra parenthesis, and (2) It’s easy to find and remove those stabs within the editor.
Simple debug stubs may produce too many output, and you may
want to limit them when certain conditions are met. A reader syntax
#??=test expr
and
#??,test procedure-call
works much like
#??=expr
and #?,procedure-call
, but
only when test yields true:
(define (fib n) (if (< n 2) 1 #??,(= n 5) (+ (fib (- n 1)) (fib (- n 2))))) gosh> (fib 7) #?,calling `+' with args: #?,> 5 #?,> 3 #?- 8 #?,calling `+' with args: #?,> 5 #?,> 3 #?- 8 21
Internally, #??=test expr
and
#??,test procedure-call
are expanded to
macro calls (debug-print-conditionally test expr)
and (debug-funcallt-conditionally test procedure-call)
.