scheme-debugging.texi 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. @c -*-texinfo-*-
  2. @c This is part of the GNU Guile Reference Manual.
  3. @c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006, 2007
  4. @c Free Software Foundation, Inc.
  5. @c See the file guile.texi for copying conditions.
  6. @page
  7. @node Tracing
  8. @section Tracing
  9. The @code{(ice-9 debug)} module implements tracing of procedure
  10. applications. When a procedure is @dfn{traced}, it means that every
  11. call to that procedure is reported to the user during a program run.
  12. The idea is that you can mark a collection of procedures for tracing,
  13. and Guile will subsequently print out a line of the form
  14. @smalllisp
  15. | | [@var{procedure} @var{args} @dots{}]
  16. @end smalllisp
  17. whenever a marked procedure is about to be applied to its arguments.
  18. This can help a programmer determine whether a function is being called
  19. at the wrong time or with the wrong set of arguments.
  20. In addition, the indentation of the output is useful for demonstrating
  21. how the traced applications are or are not tail recursive with respect
  22. to each other. Thus, a trace of a non-tail recursive factorial
  23. implementation looks like this:
  24. @smalllisp
  25. [fact1 4]
  26. | [fact1 3]
  27. | | [fact1 2]
  28. | | | [fact1 1]
  29. | | | | [fact1 0]
  30. | | | | 1
  31. | | | 1
  32. | | 2
  33. | 6
  34. 24
  35. @end smalllisp
  36. While a typical tail recursive implementation would look more like this:
  37. @smalllisp
  38. [fact2 4]
  39. [facti 1 4]
  40. [facti 4 3]
  41. [facti 12 2]
  42. [facti 24 1]
  43. [facti 24 0]
  44. 24
  45. @end smalllisp
  46. @deffn {Scheme Procedure} trace procedure
  47. Enable tracing for @code{procedure}. While a program is being run,
  48. Guile will print a brief report at each call to a traced procedure,
  49. advising the user which procedure was called and the arguments that were
  50. passed to it.
  51. @end deffn
  52. @deffn {Scheme Procedure} untrace procedure
  53. Disable tracing for @code{procedure}.
  54. @end deffn
  55. Here is another example:
  56. @lisp
  57. (define (rev ls)
  58. (if (null? ls)
  59. '()
  60. (append (rev (cdr ls))
  61. (cons (car ls) '())))) @result{} rev
  62. (trace rev) @result{} (rev)
  63. (rev '(a b c d e))
  64. @result{} [rev (a b c d e)]
  65. | [rev (b c d e)]
  66. | | [rev (c d e)]
  67. | | | [rev (d e)]
  68. | | | | [rev (e)]
  69. | | | | | [rev ()]
  70. | | | | | ()
  71. | | | | (e)
  72. | | | (e d)
  73. | | (e d c)
  74. | (e d c b)
  75. (e d c b a)
  76. (e d c b a)
  77. @end lisp
  78. Note the way Guile indents the output, illustrating the depth of
  79. execution at each procedure call. This can be used to demonstrate, for
  80. example, that Guile implements self-tail-recursion properly:
  81. @lisp
  82. (define (rev ls sl)
  83. (if (null? ls)
  84. sl
  85. (rev (cdr ls)
  86. (cons (car ls) sl)))) @result{} rev
  87. (trace rev) @result{} (rev)
  88. (rev '(a b c d e) '())
  89. @result{} [rev (a b c d e) ()]
  90. [rev (b c d e) (a)]
  91. [rev (c d e) (b a)]
  92. [rev (d e) (c b a)]
  93. [rev (e) (d c b a)]
  94. [rev () (e d c b a)]
  95. (e d c b a)
  96. (e d c b a)
  97. @end lisp
  98. Since the tail call is effectively optimized to a @code{goto} statement,
  99. there is no need for Guile to create a new stack frame for each
  100. iteration. Tracing reveals this optimization in operation.
  101. @c Local Variables:
  102. @c TeX-master: "guile.texi"
  103. @c End: