diff --git a/doc/ref/ChangeLog b/doc/ref/ChangeLog index 7ed1eb778..2604a2607 100644 --- a/doc/ref/ChangeLog +++ b/doc/ref/ChangeLog @@ -1,3 +1,19 @@ +2006-08-01 Neil Jerram + + * scheme-debugging.texi (Debug Last Error, Interactive Debugger): + Moved/merged to scheme-using.texi, as REPL features. + (Examples): New. + (Intro to Breakpoints): New introductory text here. Removed all + subnodes except for Breakpoints Overview. + + * scheme-using.texi: New. + + * guile.texi (Programming in Scheme): Include new + scheme-using.texi file. + + * Makefile.am (guile_TEXINFOS): Include new scheme-using.texi + file. + 2006-06-16 Ludovic Courtès * api-utility.texi (Equality): Mentioned the behavior of `equal?' diff --git a/doc/ref/Makefile.am b/doc/ref/Makefile.am index 1e4f3cfee..76a66f0c9 100644 --- a/doc/ref/Makefile.am +++ b/doc/ref/Makefile.am @@ -56,6 +56,7 @@ guile_TEXINFOS = preface.texi \ gh.texi \ api-overview.texi \ scheme-debugging.texi \ + scheme-using.texi \ indices.texi \ script-getopt.texi \ data-rep.texi \ diff --git a/doc/ref/guile.texi b/doc/ref/guile.texi index 8a9fbdcf6..08e8b0755 100644 --- a/doc/ref/guile.texi +++ b/doc/ref/guile.texi @@ -137,7 +137,7 @@ x @comment The title is printed in a large font. @title Guile Reference Manual @subtitle Edition @value{MANUAL-EDITION}, for use with Guile @value{VERSION} -@c @subtitle $Id: guile.texi,v 1.44 2005-06-22 23:42:23 kryde Exp $ +@c @subtitle $Id: guile.texi,v 1.45 2006-08-01 21:33:17 ossau Exp $ @c See preface.texi for the list of authors @author The Guile Developers @@ -219,6 +219,8 @@ etc. that make up Guile's application programming interface (API), * Basic Ideas:: Basic ideas in Scheme. * Guile Scheme:: Guile's implementation of Scheme. * Guile Scripting:: How to write Guile scripts. +* Using Guile Interactively:: Guile's REPL features. +* Using Guile in Emacs:: Guile and Emacs. * Debugging Features:: Features for finding errors. * Further Reading:: Where to find out more about Scheme. @end menu @@ -226,6 +228,7 @@ etc. that make up Guile's application programming interface (API), @include scheme-ideas.texi @include scheme-intro.texi @include scheme-scripts.texi +@include scheme-using.texi @include scheme-debugging.texi @include scheme-reading.texi diff --git a/doc/ref/scheme-debugging.texi b/doc/ref/scheme-debugging.texi index 6168ac886..a9d1691d1 100644 --- a/doc/ref/scheme-debugging.texi +++ b/doc/ref/scheme-debugging.texi @@ -28,135 +28,196 @@ execution context at a breakpoint, or when the last error occurred. The details are more complex and more powerful @dots{} @menu -* Debug Last Error:: Debugging the most recent error. +* Examples:: * Intro to Breakpoints:: Setting and manipulating them. -* Interactive Debugger:: Using the interactive debugger. * Tracing:: Tracing program execution. @end menu -@node Debug Last Error -@subsection Debugging the Most Recent Error +@node Examples +@subsection Examples -When an error is signalled, Guile remembers the execution context where -the error occurred. By default, Guile then displays only the most -immediate information about where and why the error occurred, for -example: - -@lisp -(make-string (* 4 (+ 3 #\s)) #\space) -@print{} -standard input:2:19: In procedure + in expression (+ 3 #\s): -standard input:2:19: Wrong type argument: #\s -ABORT: (wrong-type-arg) - -Type "(backtrace)" to get more information or "(debug)" to enter the debugger. -@end lisp - -@noindent -However, as the message above says, you can obtain much more -information about the context of the error by typing -@code{(backtrace)} or @code{(debug)}. - -@code{(backtrace)} displays the Scheme call stack at the point where the -error occurred: - -@lisp -(backtrace) -@print{} -Backtrace: -In standard input: - 2: 0* [make-string ... - 2: 1* [* 4 ... - 2: 2* [+ 3 #\s] - -Type "(debug-enable 'backtrace)" if you would like a backtrace -automatically if an error occurs in the future. -@end lisp - -@noindent -In a more complex scenario than this one, this can be extremely useful -for understanding where and why the error occurred. For more on the -format of the displayed backtrace, see the subsection below. - -@code{(debug)} takes you into Guile's interactive debugger, which -provides commands that allow you to - -@itemize @bullet -@item -display the Scheme call stack at the point where the error occurred -(the @code{backtrace} command --- see @ref{Display Backtrace}) - -@item -move up and down the call stack, to see in detail the expression being -evaluated, or the procedure being applied, in each @dfn{frame} (the -@code{up}, @code{down}, @code{frame}, @code{position}, @code{info args} -and @code{info frame} commands --- see @ref{Frame Selection} and -@ref{Frame Information}) - -@item -examine the values of variables and expressions in the context of each -frame (the @code{evaluate} command --- see @ref{Frame Evaluation}). -@end itemize - -Use of the interactive debugger, including these commands, is described -in @ref{Interactive Debugger}. +Before we dive into the details and reference documentation of +guile-debugging's features, this chapter sets the scene by presenting a +few examples of what you can do with guile-debugging. @menu -* Backtrace Format:: How to interpret a backtrace. +* Single Stepping through a Procedure's Code:: +* Profiling or Tracing a Procedure's Code:: @end menu -@node Backtrace Format -@subsubsection How to Interpret a Backtrace +@node Single Stepping through a Procedure's Code +@subsubsection Single Stepping through a Procedure's Code + +A good way to explore in detail what a Scheme procedure does is to set a +breakpoint on it and then single step through what it does. To do this, +use the @code{break-in} procedure from the @code{(ice-9 debugging +breakpoints)} module with the @code{debug-trap} behaviour from +@code{(ice-9 debugging ice-9-debugger-extensions)}. The following +sample session illustrates this. It assumes that the file +@file{matrix.scm} defines a procedure @code{mkmatrix}, which is the one +we want to explore, and another procedure @code{do-main} which calls +@code{mkmatrix}. + +@lisp +$ /usr/bin/guile -q +guile> (use-modules (ice-9 debugger) + (ice-9 debugging ice-9-debugger-extensions) + (ice-9 debugging breakpoints)) +guile> (load "matrix.scm") +guile> (break-in 'mkmatrix #:behaviour debug-trap) +#< 808cb70> +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> +@end lisp + +Or you can use guile-debugging's Emacs interface (GDS), by using the +module @code{(ice-9 gds-client)} instead of @code{(ice-9 debugger)} and +@code{(ice-9 debugging ice-9-debugger-extensions)}, and changing +@code{debug-trap} to @code{gds-debug-trap}. Then the stack and +corresponding source locations are displayed in Emacs instead of on the +Guile command line. + + +@node Profiling or Tracing a Procedure's Code +@subsubsection Profiling or Tracing a Procedure's Code + +What if you wanted to get a trace of everything that the Guile evaluator +does within a given procedure, but without Guile stopping and waiting +for your input at every step? In this case you set a breakpoint on the +procedure using @code{break-in} (the same as in the previous example), +but use the @code{trace-trap} and @code{trace-until-exit} behaviours +provided by the @code{(ice-9 debugging trace)} module. + +@lisp +guile> (use-modules (ice-9 debugging breakpoints) (ice-9 debugging trace)) +guile> (load "matrix.scm") +guile> (break-in 'mkmatrix #:behaviour (list trace-trap trace-until-exit)) +#< 808b430> +guile> (do-main 4) +| 2: [mkmatrix] +| 3: [define (define yy 23) ((()) #)] +| 3: [define (define yy 23) ((()) #)] +| 3: =>(#@@define yy 23) +| 3: [let (let # #) (# #)] +| 3: [let (let # #) (# #)] +| 3: =>(#@@let* (x 1) #@@let (quote this-is-a-matric)) +| 2: (letrec ((yy 23)) (let ((x 1)) (quote this-is-a-matric))) +| 3: [let (let # #) (# # #)] +| 3: [let (let # #) (# # #)] +| 3: =>(#@@let* (x 1) #@@let (quote this-is-a-matric)) +| 2: (let ((x 1)) (quote this-is-a-matric)) +| 3: [quote (quote this-is-a-matric) ((x . 1) ((yy) 23) (()) ...)] +| 3: [quote (quote this-is-a-matric) ((x . 1) ((yy) 23) (()) ...)] +| 3: =>(#@@quote this-is-a-matric) +| 2: (quote this-is-a-matric) +| 2: =>this-is-a-matric +this-is-a-matric +guile> (do-main 4) +| 2: [mkmatrix] +| 2: (letrec ((yy 23)) (let ((x 1)) (quote this-is-a-matric))) +| 2: (let ((x 1)) (quote this-is-a-matric)) +| 2: (quote this-is-a-matric) +| 2: =>this-is-a-matric +this-is-a-matric +guile> +@end lisp + +This example shows the default configuration for how each line of trace +output is formatted, which is: + +@itemize +@item +the character @code{|}, a visual clue that the line is a line of trace +output, followed by + +@item +a number indicating the real evaluator stack depth (where ``real'' means +not counting tail-calls), followed by + +@item +a summary of the expression being evaluated (@code{(@dots{})}), the +procedure being called (@code{[@dots{}]}), or the value being returned +from an evaluation or procedure call (@code{=>@dots{}}). +@end itemize + +@noindent +You can customize @code{(ice-9 debugging trace)} to show different +information in each trace line using the @code{set-trace-layout} +procedure. The next example shows how to get the source location in +each trace line instead of the stack depth. + +@lisp +guile> (set-trace-layout "|~16@@a: ~a\n" trace/source trace/info) +guile> (do-main 4) +| matrix.scm:7:2: [mkmatrix] +| : (letrec ((yy 23)) (let ((x 1)) (quote this-is-a-matric))) +| matrix.scm:3:2: (let ((x 1)) (quote this-is-a-matric)) +| matrix.scm:4:20: (quote this-is-a-matric) +| matrix.scm:4:20: =>this-is-a-matric +this-is-a-matric +guile> +@end lisp + +(For anyone wondering why the first @code{(do-main 4)} call above +generates lots more trace lines than the subsequent calls: these +examples also demonstrate how the Guile evaluator ``memoizes'' code. +When Guile evaluates a source code expression for the first time, it +changes some parts of the expression so that they will be quicker to +evaluate when that expression is evaluated again; this is called +memoization. The trace output from the first @code{(do-main 4)} call +shows memoization steps, such as an internal define being transformed to +a letrec.) @node Intro to Breakpoints @subsection Intro to Breakpoints -If you are not already familiar with the concept of breakpoints, the -first subsection below explains how they work are why they are useful. +Sometimes a piece of Scheme code isn't working and you'd like to go +through it step by step. You can do this in Guile by setting a +breakpoint at the start of the relevant code, and then using the command +line or Emacs interface to step through it. -Broadly speaking, Guile's breakpoint support consists of +A breakpoint can be specified by procedure name or by location -- the +relevant code's file name, line number and column number. For details +please see the full documentation for @code{break-in} and +@code{break-at} in @ref{Intro to Breakpoints}. -@itemize @bullet -@item -type-specific features for @emph{creating} breakpoints of various types - -@item -relatively generic features for @emph{manipulating} the behaviour of -breakpoints once they've been created. -@end itemize - -Different breakpoint types are implemented as different classes in a -GOOPS hierarchy with common base class @code{}. The magic -of generic functions then allows most of the manipulation functions to -be generic by default but specializable (by breakpoint class) if the -need arises. - -Generic breakpoint support is provided by the @code{(ice-9 debugger -breakpoints)} module, so you will almost always need to use this module -in order to access the functionality described here: - -@smalllisp -(use-modules (ice-9 debugger breakpoints)) -@end smalllisp - -@noindent -You may like to add this to your @file{.guile} file. +When you set a breakpoint, you can specify any ``behaviour'' you like +for what should happen when the breakpoint is hit; a breakpoint +``behaviour'' is just a Scheme procedure with the right signature. @menu * Breakpoints Overview:: -* Source Breakpoints:: -* Procedural Breakpoints:: -* Setting Breakpoints:: -* break! trace! trace-subtree!:: -* Accessing Breakpoints:: -* Breakpoint Behaviours:: -* Enabling and Disabling:: -* Deleting Breakpoints:: -* Breakpoint Information:: -* Other Breakpoint Types:: @end menu @@ -187,8 +248,9 @@ available: @itemize @bullet @item -all the commands as described for last error debugging (@pxref{Debug -Last Error}), which allow you to explore the stack and so on +all the commands as described for last error debugging +(@pxref{Interactive Debugger}), which allow you to explore the stack and +so on @item additional commands for continuing program execution in various ways: @@ -200,607 +262,13 @@ Use of the interactive debugger is described in @ref{Interactive Debugger}. -@node Source Breakpoints -@subsubsection Source Breakpoints - -A source breakpoint is a breakpoint that triggers whenever program -execution hits a particular source location. A source breakpoint can be -conveniently set simply by evaluating code that has @code{##} inserted -into it at the position where you want the breakpoint to be. - -For example, to set a breakpoint immediately before evaluation of -@code{(= n 0)} in the following procedure definition, evaluate: - -@smalllisp -(define (fact1 n) - (if ##(= n 0) - 1 - (* n (fact1 (- n 1))))) -@print{} -Set breakpoint 1: standard input:4:9: (= n 0) -@end smalllisp - -@noindent -Note the message confirming that you have set a breakpoint. If you -don't see this, something isn't working. - -@code{##} is provided by the @code{(ice-9 debugger breakpoints source)} module, -so you must use this module before trying to set breakpoints in this -way: - -@smalllisp -(use-modules (ice-9 debugger breakpoints source)) -@end smalllisp - -@noindent -You may like to add this to your @file{.guile} file. - -The default behaviour for source breakpoints is @code{debug-here} -(@pxref{Breakpoint Behaviours}), which means to enter the command line -debugger when the breakpoint is hit. So, if you now use @code{fact1}, -that is what happens. - -@smalllisp -guile> (fact1 3) -Hit breakpoint 1: standard input:4:9: (= n 0) -Frame 3 at standard input:4:9 - (= n 0) -debug> -@end smalllisp - - -@node Procedural Breakpoints -@subsubsection Procedural Breakpoints - -A procedural breakpoint is a breakpoint that triggers whenever Guile is -about to apply a specified procedure to its (already evaluated) -arguments. To set a procedural breakpoint, call @code{break!} with the -target procedure as a single argument. For example: - -@smalllisp -(define (fact1 n) - (if (= n 0) - 1 - (* n (fact1 (- n 1))))) - -(break! fact1) -@print{} -Set breakpoint 1: [fact1] -@result{} -#< 808b0b0> -@end smalllisp - -Alternatives to @code{break!} are @code{trace!} and -@code{trace-subtree!}. The difference is that these three calls create -a breakpoint in the same place but with three different behaviours, -respectively @code{debug-here}, @code{trace-here} and -@code{trace-subtree}. Breakpoint behaviours are documented fully later -(@pxref{Breakpoint Behaviours}), but to give a quick taste, here's an -example of running code that includes a procedural breakpoint with the -@code{trace-here} behaviour. - -@smalllisp -(trace! fact1) -@print{} -Set breakpoint 1: [fact1] -@result{} -#< 808b0b0> - -(fact1 4) -@print{} -| [fact1 4] -| | [fact1 3] -| | | [fact1 2] -| | | | [fact1 1] -| | | | | [fact1 0] -| | | | | 1 -| | | | 2 -| | | 6 -| | 24 -| 24 -@result{} -24 -@end smalllisp - -To set and use procedural breakpoints, you will need to use the -@code{(ice-9 debugger breakpoints procedural)} module: - -@smalllisp -(use-modules (ice-9 debugger breakpoints procedural)) -@end smalllisp - -@noindent -You may like to add this to your @file{.guile} file. - - -@node Setting Breakpoints -@subsubsection Setting Breakpoints - -In general, that is. We've already seen how to set source and -procedural breakpoints conveniently in practice. This section explains -how those conveniences map onto a more general mechanism. - -The general mechanism for setting breakpoints is the generic function -@code{set-breakpoint!}. Different kinds of breakpoints define -subclasses of the class @code{} and provide their own -methods for @code{set-pbreakpoint!}. - -For example, @code{(ice-9 debugger breakpoints procedural)} implements -the @code{} subclass and provides a -@code{set-breakpoint!} method that takes a procedure argument: - -@smalllisp -(set-breakpoint! @var{behavior} fact1) -@print{} -Set breakpoint 1: [fact1] -@result{} -#< 808b0b0> -@end smalllisp - -A non-type-specific @code{set-breakpoint!} method is provided by the -generic module @code{(ice-9 debugger breakpoints)}. It allows you to -change the behaviour of an existing breakpoint that is identified by -its breakpoint number. - -@smalllisp -(set-breakpoint! @var{behavior} 1) -@end smalllisp - -@node break! trace! trace-subtree! -@subsubsection break! trace! trace-subtree! - -We have already talked above about the use of @code{break!}, -@code{trace!} and @code{trace-subtree!} for setting procedural -breakpoints. Now that @code{set-breakpoint!} has been introduced, we -can reveal that @code{break!}, @code{trace!} and @code{trace-subtree!} -are in fact just wrappers for @code{set-breakpoint!} that specify -particular breakpoint behaviours, respectively @code{debug-here}, -@code{trace-here} and @code{trace-subtree}. - -@smalllisp -(break! . @var{args}) - @equiv{} (set-breakpoint! debug-here . @var{args}) -(trace! . @var{args}) - @equiv{} (set-breakpoint! trace-here . @var{args}) -(trace-subtree! . @var{args}) - @equiv{} (set-breakpoint! trace-subtree . @var{args}) -@end smalllisp - -This means that these three procedures can be used to set the -corresponding behaviours for any type of breakpoint for which a -@code{set-breakpoint!} method exists, not just procedural ones. - - -@node Accessing Breakpoints -@subsubsection Accessing Breakpoints - -Information about the state and behaviour of a breakpoint is stored in -an instance of the appropriate breakpoint class. To access and change -that information, therefore, you need to get hold of the desired -breakpoint instance. - -The generic function @code{get-breakpoint} meets this need: For every -@code{set-breakpoint!} method there is a corresponding -@code{get-breakpoint} method. Note especially the useful -type-independent case: - -@smalllisp -(get-breakpoint 1) -@result{} -#< 808b0b0> -@end smalllisp - - -@node Breakpoint Behaviours -@subsubsection Breakpoint Behaviours - -A breakpoint's @dfn{behaviour} determines what happens when that -breakpoint is hit. Several kinds of behaviour are generally useful. - -@table @code -@item debug-here -Enter the command line debugger. This gives the opportunity to explore -the stack, evaluate expressions in any of the pending stack frames, -change breakpoint properties or set new breakpoints, and continue -program execution when you are done. - -@item trace-here -Trace the current stack frame. For expressions being evaluated, this -shows the expression. For procedure applications, it shows the -procedure name and its arguments @emph{post-evaluation}. For both -expressions and applications, the indentation of the tracing indicates -whether the traced items are mutually tail recursive. - -@item trace-subtree -Trace the current stack frame, and enable tracing for all future -evaluations and applications until the current stack frame is exited. -@code{trace-subtree} is a great preliminary exploration tool when all -you know is that there is a bug ``somewhere in XXX or in something that -XXX calls''. - -@item (at-exit @var{thunk}) -Don't do anything now, but arrange for @var{thunk} to be executed when -the current stack frame is exited. For example, the operation that most -debugging tools call ``finish'' is @code{(at-exit debug-here)}. - -@item (at-next @var{count} @var{thunk}) -@dots{} arrange for @var{thunk} to be executed when beginning the -@var{count}th next evaluation or application with source location in the -current file. - -@item (at-entry @var{count} @var{thunk}) -@dots{} arrange for @var{thunk} to be executed when beginning the -@var{count}th next evaluation (regardless of source location). - -@item (at-apply @var{count} @var{thunk}) -@dots{} arrange for @var{thunk} to be executed just before performing -the @var{count}th next application (regardless of source location). - -@item (at-step @var{count} @var{thunk}) -Synthesis of @code{at-entry} and @code{at-apply}; counts both -evaluations and applications. -@end table - -Every breakpoint instance has a slot in which its behaviour is stored. -If you have a breakpoint instance in hand, you can change its behaviour -using the @code{bp-behaviour} accessor. - -An @dfn{accessor} supports the setting of a property like this: - -@smalllisp -(set! (bp-behaviour @var{breakpoint}) @var{new-behaviour}) -@end smalllisp - -@noindent -See the GOOPS manual for further information on accessors. - -Alternatively, if you know how to specify the @var{location-args} for -the breakpoint in question, you can change its behaviour using -@code{set-breakpoint!}. For example: - -@smalllisp -;; Change behaviour of breakpoint number 2. -(set-breakpoint! @var{new-behaviour} 2) - -;; Change behaviour of procedural breakpoint on [fact1]. -(set-breakpoint! @var{new-behaviour} fact1) -@end smalllisp - -In all cases, the behaviour that you specify should be either a single -thunk, or a list of thunks, to be called when the breakpoint is hit. - -The most common behaviours above are exported as thunks from the -@code{(ice-9 debugger behaviour)} module. So, if you use this module, you can -use those behaviours directly like this: - -@smalllisp -(use-modules (ice-9 debugger behaviour)) -(set-breakpoint! trace-subtree 2) -(set! (bp-behaviour (get-breakpoint 3)) debug-here) -@end smalllisp - -@noindent -You can also use the list option to combine common behaviours: - -@smalllisp -(set-breakpoint! (list trace-here debug-here) 2) -@end smalllisp - -@noindent -Or, for more customized behaviour, you could build and use your own -thunk like this: - -@smalllisp -(define (my-behaviour) - (trace-here) - (at-exit (lambda () - (display "Exiting frame of my-behaviour bp\n") - ... do something unusual ...))) - -(set-breakpoint my-behaviour 2) -@end smalllisp - - -@node Enabling and Disabling -@subsubsection Enabling and Disabling - -Independently of its behaviour, each breakpoint also keeps track of -whether it is currently enabled. This is a straightforward convenience -to allow breakpoints to be temporarily switched off without losing all -their carefully constructed properties. - -If you have a breakpoint instance in hand, you can enable or disable it -using the @code{bp-enabled?} accessor. - -Alternatively, you can enable or disable a breakpoint via its location -args by using @code{enable-breakpoint!} or @code{disable-breakpoint!}. - -@smalllisp -(disable-breakpoint! fact1) ; disable the procedural breakpoint on fact1 -(enable-breakpoint! 1) ; enable breakpoint 1 -@end smalllisp - -@code{enable-breakpoint!} and @code{disable-breakpoint!} are implemented -using @code{get-breakpoint} and @code{bp-enabled?}, so any -@var{location-args} that are valid for @code{get-breakpoint} will work -also for these procedures. - - -@node Deleting Breakpoints -@subsubsection Deleting Breakpoints - -Given a breakpoint instance in hand, you can deactivate it and remove -it from the global list of current breakpoints by calling -@code{bp-delete!}. - -Alternatively, you can delete a breakpoint by its location args: - -@smalllisp -(delete-breakpoint! 1) ; delete breakpoint 1 -@end smalllisp - -@code{delete-breakpoint!} is implemented using @code{get-breakpoint} and -@code{bp-delete!}, so any @var{location-args} that are valid for -@code{get-breakpoint} will work also for @code{delete-breakpoint!}. - -There is no way to reinstate a deleted breakpoint. Final destruction of -the breakpoint instance is determined by the usual garbage collection -rules. - - -@node Breakpoint Information -@subsubsection Breakpoint Information - -To get Guile to print a description of a breakpoint instance, use -@code{bp-describe}: - -@smalllisp -(bp-describe (get-breakpoint 1) #t) ; #t specifies standard output -@print{} -Breakpoint 1: [fact1] - enabled? = #t - behaviour = # -@end smalllisp - -Following the usual model, @code{describe-breakpoint} is also provided: - -@smalllisp -(describe-breakpoint 1) -@print{} -Breakpoint 1: [fact1] - enabled? = #t - behaviour = # -@end smalllisp - -Finally, two stragglers. @code{all-breakpoints} returns a list of all -current breakpoints. @code{describe-all-breakpoints} combines -@code{bp-describe} and @code{all-breakpoints} by printing a description -of all current breakpoints to standard output. - -@node Other Breakpoint Types -@subsubsection Other Breakpoint Types - -Besides source and procedural breakpoints, Guile includes an early -implementation of a third class of breakpoints: @dfn{range} breakpoints. -These are breakpoints that trigger when program execution enters (or -perhaps exits) a defined range of source locations. - -Sadly, these don't yet work well. The apparent problem is that the -extra methods for @code{set-breakpoint!} and @code{get-breakpoint} cause -some kind of explosion in the time taken by GOOPS to construct its -method cache and to dispatch calls involving these generic functions. -But we haven't really investigated enough to be sure that this is the -real issue. - -If you're interested in looking and/or investigating anyway, please feel -free to check out and play with the @code{(ice-9 debugger breakpoints -range)} module. - -The other kind of breakpoint that we'd like to have is watchpoints, but -this hasn't been implemented at all yet. Watchpoints may turn out to be -impractical for performance reasons. - - -@node Interactive Debugger -@subsection Using the Interactive Debugger - -Guile's interactive debugger is a command line application that accepts -commands from you for examining the stack and, if at a breakpoint, for -continuing program execution in various ways. Unlike in the normal -Guile REPL, commands are typed mostly without parentheses. - -When you first enter the debugger, it introduces itself with a message -like this: - -@lisp -This is the Guile debugger -- for help, type `help'. -There are 3 frames on the stack. - -Frame 2 at standard input:36:19 - [+ 3 #\s] -debug> -@end lisp - -@noindent -``debug>'' is the debugger's prompt, and a useful reminder that you are -not in the normal Guile REPL. The available commands are described in -detail in the following subsections. - -@menu -* Display Backtrace:: backtrace. -* Frame Selection:: up, down, frame. -* Frame Information:: info args, info frame, position. -* Frame Evaluation:: evaluate. -* Single Stepping:: step, next. -* Run To Frame Exit:: finish, trace-finish. -* Continue Execution:: continue. -* Leave Debugger:: quit. -@end menu - - -@node Display Backtrace -@subsubsection Display Backtrace - -The @code{backtrace} command, which can also be invoked as @code{bt} or -@code{where}, displays the call stack (aka backtrace) at the point where -the debugger was entered: - -@lisp -debug> bt -In standard input: - 36: 0* [make-string ... - 36: 1* [* 4 ... - 36: 2* [+ 3 #\s] -@end lisp - -@deffn {Debugger Command} backtrace [count] -@deffnx {Debugger Command} bt [count] -@deffnx {Debugger Command} where [count] -Print backtrace of all stack frames, or of the innermost @var{count} -frames. With a negative argument, print the outermost -@var{count} -frames. If the number of frames isn't explicitly given, the debug -option @code{depth} determines the maximum number of frames printed. -@end deffn - -The format of the displayed backtrace is the same as for the -@code{backtrace} procedure --- see @ref{Backtrace Format} for details. - - -@node Frame Selection -@subsubsection Frame Selection - -A call stack consists of a sequence of stack @dfn{frames}, with each -frame describing one level of the nested evaluations and applications -that the program was executing when it hit a breakpoint or an error. -Frames are numbered such that frame 0 is the outermost --- i.e. the -operation on the call stack that began least recently --- and frame N-1 -the innermost (where N is the total number of frames on the stack). - -When you enter the debugger, the innermost frame is selected, which -means that the commands for getting information about the ``current'' -frame, or for evaluating expressions in the context of the current -frame, will do so by default with respect to the innermost frame. To -select a different frame, so that these operations will apply to it -instead, use the @code{up}, @code{down} and @code{frame} commands like -this: - -@lisp -debug> up -Frame 1 at standard input:36:14 - [* 4 ... -debug> frame 0 -Frame 0 at standard input:36:1 - [make-string ... -debug> down -Frame 1 at standard input:36:14 - [* 4 ... -@end lisp - -@deffn {Debugger Command} up [n] -Move @var{n} frames up the stack. For positive @var{n}, this -advances toward the outermost frame, to higher frame numbers, to -frames that have existed longer. @var{n} defaults to one. -@end deffn - -@deffn {Debugger Command} down [n] -Move @var{n} frames down the stack. For positive @var{n}, this -advances toward the innermost frame, to lower frame numbers, to frames -that were created more recently. @var{n} defaults to one. -@end deffn - -@deffn {Debugger Command} frame [n] -Select and print a stack frame. With no argument, print the selected -stack frame. (See also ``info frame''.) An argument specifies the -frame to select; it must be a stack-frame number. -@end deffn - - -@node Frame Information -@subsubsection Frame Information - -[to be completed] - -@deffn {Debugger Command} {info frame} -All about selected stack frame. -@end deffn - -@deffn {Debugger Command} {info args} -Argument variables of current stack frame. -@end deffn - -@deffn {Debugger Command} position -Display the position of the current expression. -@end deffn - - -@node Frame Evaluation -@subsubsection Frame Evaluation - -[to be completed] - -@deffn {Debugger Command} evaluate expression -Evaluate an expression. -The expression must appear on the same line as the command, -however it may be continued over multiple lines. -@end deffn - - -@node Single Stepping -@subsubsection Single Stepping - -[to be completed] - -@deffn {Debugger Command} step [n] -Continue until entry to @var{n}th next frame. -@end deffn - -@deffn {Debugger Command} next [n] -Continue until entry to @var{n}th next frame in same file. -@end deffn - - -@node Run To Frame Exit -@subsubsection Run To Frame Exit - -[to be completed] - -@deffn {Debugger Command} finish -Continue until evaluation of the current frame is complete, and -print the result obtained. -@end deffn - -@deffn {Debugger Command} trace-finish -Trace until evaluation of the current frame is complete. -@end deffn - - -@node Continue Execution -@subsubsection Continue Execution - -[to be completed] - -@deffn {Debugger Command} continue -Continue program execution. -@end deffn - - -@node Leave Debugger -@subsubsection Leave Debugger - -[to be completed] - -@deffn {Debugger Command} quit -Exit the debugger. -@end deffn - - @node Tracing @subsection Tracing -Tracing has already been described as a breakpoint behaviour -(@pxref{Breakpoint Behaviours}), but we mention it again here because it -is so useful, and because Guile actually now has @emph{two} mechanisms -for tracing, and its worth clarifying the differences between them. +Tracing has already been described as a breakpoint behaviour, but we +mention it again here because it is so useful, and because Guile +actually now has @emph{two} mechanisms for tracing, and its worth +clarifying the differences between them. @menu * Old Tracing:: Tracing provided by (ice-9 debug). diff --git a/doc/ref/scheme-using.texi b/doc/ref/scheme-using.texi new file mode 100644 index 000000000..b596ce50a --- /dev/null +++ b/doc/ref/scheme-using.texi @@ -0,0 +1,411 @@ +@c -*-texinfo-*- +@c This is part of the GNU Guile Reference Manual. +@c Copyright (C) 2006 +@c Free Software Foundation, Inc. +@c See the file guile.texi for copying conditions. + +@node Using Guile Interactively +@section Using Guile Interactively + +When you start up Guile by typing just @code{guile}, without a +@code{-c} argument or the name of a script to execute, you get an +interactive interpreter where you can enter Scheme expressions, and +Guile will evaluate them and print the results for you. Here are some +simple examples. + +@lisp +guile> (+ 3 4 5) +12 +guile> (display "Hello world!\n") +Hello world! +guile> (values 'a 'b) +a +b +@end lisp + +@noindent +This mode of use is called a @dfn{REPL}, which is short for +``Read-Eval-Print Loop'', because the Guile interpreter first reads the +expression that you have typed, then evaluates it, and then prints the +result. + +@menu +* Readline:: +* Value Historyx:: +* Error Handling:: +* Interactive Debugger:: Using the interactive debugger. +@end menu + + +@node Readline +@subsection Readline + +To make it easier for you to repeat and vary previously entered +expressions, or to edit the expression that you're typing in, Guile +can use the GNU Readline library. This is not enabled by default +because of licensing reasons, but all you need to activate Readline is +the following pair of lines. + +@lisp +guile> (use-modules (ice-9 readline)) +guile> (activate-readline) +@end lisp + +It's a good idea to put these two lines (without the ``guile>'' +prompts) in your @file{.guile} file. Guile reads this file when it +starts up interactively, so anything in this file has the same effect +as if you type it in by hand at the ``guile>'' prompt. + + +@node Value Historyx +@subsection Value History + +Just as Readline helps you to reuse a previous input line, @dfn{value +history} allows you to use the @emph{result} of a previous evaluation +in a new expression. When value history is enabled, each evaluation +result is automatically assigned to the next in the sequence of +variables @code{$1}, @code{$2}, @dots{}, and you can then use these +variables in subsequent expressions. + +@lisp +guile> (iota 10) +$1 = (0 1 2 3 4 5 6 7 8 9) +guile> (apply * (cdr $1)) +$2 = 362880 +guile> (sqrt $2) +$3 = 602.3952191045344 +guile> (cons $2 $1) +$4 = (362880 0 1 2 3 4 5 6 7 8 9) +@end lisp + +To enable value history, type @code{(use-modules (ice-9 history))} at +the Guile prompt, or add this to your @file{.guile} file. (It is not +enabled by default, to avoid the possibility of conflicting with some +other use you may have for the variables @code{$1}, @code{$2}, +@dots{}, and also because it prevents the stored evaluation results +from being garbage collected, which some people may not want.) + + +@node Error Handling +@subsection Error Handling + +When code being evaluated from the REPL hits an error, Guile remembers +the execution context where the error occurred and can give you three +levels of information about what the error was and exactly where it +occurred. + +By default, Guile then displays only the first level, which is the most +immediate information about where and why the error occurred, for +example: + +@lisp +(make-string (* 4 (+ 3 #\s)) #\space) +@print{} +standard input:2:19: In procedure + in expression (+ 3 #\s): +standard input:2:19: Wrong type argument: #\s +ABORT: (wrong-type-arg) + +Type "(backtrace)" to get more information or "(debug)" to enter the debugger. +@end lisp + +@noindent +However, as the message above says, you can obtain more information +about the context of the error by typing @code{(backtrace)} or +@code{(debug)}. + +@code{(backtrace)} displays the Scheme call stack at the point where the +error occurred: + +@lisp +(backtrace) +@print{} +Backtrace: +In standard input: + 2: 0* [make-string ... + 2: 1* [* 4 ... + 2: 2* [+ 3 #\s] + +Type "(debug-enable 'backtrace)" if you would like a backtrace +automatically if an error occurs in the future. +@end lisp + +@noindent +In a more complex scenario than this one, this can be extremely useful +for understanding where and why the error occurred. You can make Guile +show the backtrace automatically by adding @code{(debug-enable +'backtrace)} to your @file{.guile}. + +@code{(debug)} takes you into Guile's interactive debugger, which +provides commands that allow you to + +@itemize @bullet +@item +display the Scheme call stack at the point where the error occurred +(the @code{backtrace} command --- see @ref{Display Backtrace}) + +@item +move up and down the call stack, to see in detail the expression being +evaluated, or the procedure being applied, in each @dfn{frame} (the +@code{up}, @code{down}, @code{frame}, @code{position}, @code{info args} +and @code{info frame} commands --- see @ref{Frame Selection} and +@ref{Frame Information}) + +@item +examine the values of variables and expressions in the context of each +frame (the @code{evaluate} command --- see @ref{Frame Evaluation}). +@end itemize + +@noindent +This is documented further in the following section. + + +@node Interactive Debugger +@subsection Using the Interactive Debugger + +Guile's interactive debugger is a command line application that accepts +commands from you for examining the stack and, if at a breakpoint, for +continuing program execution in various ways. Unlike in the normal +Guile REPL, commands are typed mostly without parentheses. + +When you first enter the debugger, it introduces itself with a message +like this: + +@lisp +This is the Guile debugger -- for help, type `help'. +There are 3 frames on the stack. + +Frame 2 at standard input:36:19 + [+ 3 #\s] +debug> +@end lisp + +@noindent +``debug>'' is the debugger's prompt, and a reminder that you are not in +the normal Guile REPL. The available commands are described in the +following subsections. + +@menu +* Display Backtrace:: backtrace. +* Frame Selection:: up, down, frame. +* Frame Information:: info args, info frame, position. +* Frame Evaluation:: evaluate. +* Single Stepping:: step, next. +* Run To Frame Exit:: finish, trace-finish. +* Continue Execution:: continue. +* Leave Debugger:: quit. +@end menu + + +@node Display Backtrace +@subsubsection Display Backtrace + +The @code{backtrace} command, which can also be invoked as @code{bt} or +@code{where}, displays the call stack (aka backtrace) at the point where +the debugger was entered: + +@lisp +debug> bt +In standard input: + 36: 0* [make-string ... + 36: 1* [* 4 ... + 36: 2* [+ 3 #\s] +@end lisp + +@deffn {Debugger Command} backtrace [count] +@deffnx {Debugger Command} bt [count] +@deffnx {Debugger Command} where [count] +Print backtrace of all stack frames, or of the innermost @var{count} +frames. With a negative argument, print the outermost -@var{count} +frames. If the number of frames isn't explicitly given, the debug +option @code{depth} determines the maximum number of frames printed. +@end deffn + +The format of the displayed backtrace is the same as for the +@code{backtrace} procedure. + + +@node Frame Selection +@subsubsection Frame Selection + +A call stack consists of a sequence of stack @dfn{frames}, with each +frame describing one level of the nested evaluations and applications +that the program was executing when it hit a breakpoint or an error. +Frames are numbered such that frame 0 is the outermost --- i.e. the +operation on the call stack that began least recently --- and frame N-1 +the innermost (where N is the total number of frames on the stack). + +When you enter the debugger, the innermost frame is selected, which +means that the commands for getting information about the ``current'' +frame, or for evaluating expressions in the context of the current +frame, will do so by default with respect to the innermost frame. To +select a different frame, so that these operations will apply to it +instead, use the @code{up}, @code{down} and @code{frame} commands like +this: + +@lisp +debug> up +Frame 1 at standard input:36:14 + [* 4 ... +debug> frame 0 +Frame 0 at standard input:36:1 + [make-string ... +debug> down +Frame 1 at standard input:36:14 + [* 4 ... +@end lisp + +@deffn {Debugger Command} up [n] +Move @var{n} frames up the stack. For positive @var{n}, this +advances toward the outermost frame, to higher frame numbers, to +frames that have existed longer. @var{n} defaults to one. +@end deffn + +@deffn {Debugger Command} down [n] +Move @var{n} frames down the stack. For positive @var{n}, this +advances toward the innermost frame, to lower frame numbers, to frames +that were created more recently. @var{n} defaults to one. +@end deffn + +@deffn {Debugger Command} frame [n] +Select and print a stack frame. With no argument, print the selected +stack frame. (See also ``info frame''.) An argument specifies the +frame to select; it must be a stack-frame number. +@end deffn + + +@node Frame Information +@subsubsection Frame Information + +[to be completed] + +@deffn {Debugger Command} {info frame} +All about selected stack frame. +@end deffn + +@deffn {Debugger Command} {info args} +Argument variables of current stack frame. +@end deffn + +@deffn {Debugger Command} position +Display the position of the current expression. +@end deffn + + +@node Frame Evaluation +@subsubsection Frame Evaluation + +[to be completed] + +@deffn {Debugger Command} evaluate expression +Evaluate an expression. +The expression must appear on the same line as the command, +however it may be continued over multiple lines. +@end deffn + + +@node Single Stepping +@subsubsection Single Stepping + +[to be completed] + +@deffn {Debugger Command} step [n] +Continue until entry to @var{n}th next frame. +@end deffn + +@deffn {Debugger Command} next [n] +Continue until entry to @var{n}th next frame in same file. +@end deffn + + +@node Run To Frame Exit +@subsubsection Run To Frame Exit + +[to be completed] + +@deffn {Debugger Command} finish +Continue until evaluation of the current frame is complete, and +print the result obtained. +@end deffn + +@deffn {Debugger Command} trace-finish +Trace until evaluation of the current frame is complete. +@end deffn + + +@node Continue Execution +@subsubsection Continue Execution + +[to be completed] + +@deffn {Debugger Command} continue +Continue program execution. +@end deffn + + +@node Leave Debugger +@subsubsection Leave Debugger + +[to be completed] + +@deffn {Debugger Command} quit +Exit the debugger. +@end deffn + + +@node Using Guile in Emacs +@section Using Guile in Emacs + +The Guile distribution includes a rich environment for working on Guile +Scheme code within Emacs. The idea of this environment is to allow you +to work on Guile Scheme code in the same kind of way that Emacs allows +you to work on Emacs Lisp code: providing easy access to help, +evaluating arbitrary fragments of code, a nice debugging interface, and +so on.@footnote{You can also, of course, run a Guile session in Emacs +simply by typing ``guile'' in a @code{*shell*} buffer. The environment +described here provides a much better integration than that, though.} + +The thinking behind this environment is that you will usually be doing +one of two things. + +@enumerate +@item +Writing or editing code. The code will be in a normal Emacs Scheme +mode buffer, and the Guile/Emacs environment extends Scheme mode to +add keystrokes and menu items for the things that are likely to be +useful to you when working on code: + +@itemize +@item +completing the identifier at point +@item +accessing Guile's built in help +@item +evaluating fragments of code to check what they do. +@end itemize + +@item +Debugging a Guile Scheme program. When your program hits an error or +a breakpoint, the Guile/Emacs environment shows you the relevant code +and the Scheme stack, and makes it easy to + +@itemize +@item +look at the values of local variables +@item +see what is happening at all levels of the Scheme stack +@item +continue execution, either normally or step by step. +@end itemize +@end enumerate + +Combinations of these work well too. You can evaluate a fragment of +code (in a Scheme buffer) that contains a breakpoint, then use the +debugging interface to step through the code at the breakpoint. You +can also run a program until it hits a breakpoint, then examine, +modify and reevaluate some of the relevant code, and then tell the +program to continue running. + + +@c Local Variables: +@c TeX-master: "guile.texi" +@c End: