Subject: Re: [PATCH v2] doc: Document the peek and pk procedures.

From: Maxim Cournoyer <[email-masked]>
Date: Mon, 08 Jul 2024 22:56:55 -0400

Hi Juliana,

Juliana Sims <[email-masked]> writes:

> * doc/ref/api-debug.texi: Document the peek and pk procedures.
> ---
>
> Hi Maxim,
>
> Thanks for the quick review! I thought I'd made sure to double-space after
> periods, but I guess my Emacs fill settings overwrote that when I made sure
> everything flowed properly. The contemporary consensus on double spaces in
> English is to not use them, and I write a lot so I have my text-mode settings
> geared to that purpose. I used manual filling this time so hopefully that issue
> has been resolved.

Thanks!  It's a peculiar/historical typography choice that seems rooted
in being able to navigate unambiguously between sentences in Emacs (and
elsewhere where implemented).

> I didn't use Emacs to regenerate all the menus in this file because it produced
> diffs in unrelated sections.

Fair enough!

> Otherwise, I've taken all of your feedback into
> account. If someone chimes in to say they really liked the smores example, we
> can always build out from the first version of the patch. There was a lot of
> code involved in making that actually work (three record types, two predicates,
> and a utility function) so I don't think that's the right solution.

Sounds good.

[...]

> diff --git a/doc/ref/api-debug.texi b/doc/ref/api-debug.texi
> index faa0c40bd..76d636d13 100644
> --- a/doc/ref/api-debug.texi
> +++ b/doc/ref/api-debug.texi
> @@ -1,27 +1,125 @@
>  @c -*-texinfo-*-
>  @c This is part of the GNU Guile Reference Manual.
> -@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2010, 2011, 2012, 2013, 2014, 2018, 2021
> +@c Copyright (C)  1996-1997, 2000-2004, 2007, 2010-2014, 2018, 2021, 2024
>  @c   Free Software Foundation, Inc.
>  @c See the file guile.texi for copying conditions.
>  
>  @node Debugging
>  @section Debugging Infrastructure
>  
> -@cindex Debugging
> -In order to understand Guile's debugging facilities, you first need to
> -understand a little about how Guile represents the Scheme control stack.
> -With that in place we explain the low level trap calls that the virtual
> -machine can be configured to make, and the trap and breakpoint
> -infrastructure that builds on top of those calls.
> +@cindex debugging
> +Guile provides facilities for simple print-based debugging as well as
> +more advanced debugging features. In order to understand Guile's
> +advanced debugging facilities, one first must understand a little about
> +how Guile represents the Scheme control stack. With that in place, we
> +can explain the low level trap calls that the virtual machine can be
> +configured to make, and the trap and breakpoint infrastructure that
> +builds on top of those calls.
>  
>  @menu
> -* Evaluation Model::            Evaluation and the Scheme stack.
> -* Source Properties::           From expressions to source locations.
> +* Simple Debugging::             Print-based debugging.
> +* Evaluation Model::             Evaluation and the Scheme stack.
> +* Source Properties::            From expressions to source locations.
>  * Programmatic Error Handling::  Debugging when an error occurs.
> -* Traps::                       Breakpoints, tracepoints, oh my!
> -* GDB Support::                 C-level debugging with GDB.
> +* Traps::                        Breakpoints, tracepoints, oh my!
> +* GDB Support::                  C-level debugging with GDB.
>  @end menu
>  
> +
> +@node Simple Debugging
> +@subsection Simple Debugging
> +
> +Guile offers powerful tools for introspection and debugging at the REPL,
> +covered in the rest of this section and elsewhere in this manual
> +(@pxref{Interactive Debugging}).  Here we deal with a more primitive
> +approach, commonly called ``print debugging,'' which is a quick way to
> +diagnose simple errors by printing values during a program's execution.
> +Guile provides the @code{peek} procedure, more commonly known as
> +@code{pk} (pronounced by naming the letters), as a convenient and
> +powerful tool for this kind of debugging.
> +
> +@deffn {Scheme Procedure} peek stuff @dots{}
> +@deffnx {Scheme Procedure} pk stuff @dots{}
> +Print @var{stuff} to the current output port using @code{write}.  Return
> +the last argument.
> +@end deffn
> +
> +@code{pk} improves on using @code{write} directly because it enables
> +inspection of the state of code as it runs without breaking the normal
> +code flow.  It is also more convenient than a full debugger because it
> +does not require the program to be stopped for inspection.  Here is a
> +basic example:

I hadn't commented on that last sentence before, but if I knew how to
have the Guile debugger reliably break where I want it to (I don't, or
somehow haven't managed to have it work well), I don't think using 'pk',
which requires editing files before and after debugging, could be
described as more convenient :-).

> +@lisp
> +(define fire 'burns)
> +
> +(pk fire)
> +@result{}
> +
> +;;; (burns)
> +burns
> +@end
> +
> +Here is an example of inspecting a value in the midst of code flow:
> +
> +@lisp
> +(map (lambda (v)
> +       (if (number? v)
> +           (number->string v)
> +           (pk v)))
> +     '(1 "2" "3" 4))
> +@result{}
> +
> +;;; ("2")
> +
> +;;; ("3")
> +("1" "2" "3" "4")
> +@end
> +
> +A common technique when using @code{pk} is to label values with symbols
> +to keep track of where they're coming from.  There's no reason these
> +labels need to be symbols; symbols are just convenient.  Here's a
> +slightly more complex example demonstrating that pattern:
> +
> +@lisp
> +(define (pk-identity x)
> +  (pk 'arg-to-identity x))
> +
> +(pk-identity 42)
> +@result{}
> +
> +;;; (arg-to-identity 42)
> +42
> +@end
> +
> +@code{pk} has one small quirk of note.  Currently, it only returns the
> +first value returned from any multi-value returns.  So for example:
> +
> +@lisp
> +(pk 'vals (values 1 2 3))
> +@result{}
> +
> +;;; (vals 1)
> +1
> +@end
> +
> +The way to get around this limitation is to bind such multi-value
> +returns then inspect the results.  Still, @code{pk} can only return a
> +single value:
> +
> +@lisp
> +(use-modules (srfi srfi-11))
> +
> +(let-values (((x y z)
> +              (values 1 2 3)))
> +  (pk 'vals x y z))
> +@result{}
> +
> +;;; (vals 1 2 3)
> +3
> +@end
> +
> +
>  @node Evaluation Model
>  @subsection Evaluation and the Scheme Stack

I like the new, 'evaluatable' examples :-).  It's also a much shorter
read.  Thanks for sending a v2!

I would commit this if I was a committer, but I am not, so here's at
least my reviewed trailer:

Reviewed-by: Maxim Cournoyer <maxim.cournoyer@gmail>

-- 
Thanks,
Maxim