Peter Jipsen writes in his e-mail message of 6-Nov-92:
Is it possible to trace through gap code?
Are there some useful commands to help debugging
gap routines?
Well there  is  a function in the  GAP kernel that switches a flag  for a
function.  Afterwards this  function prints out its arguments whenever it
is called and its  result whenever  it is done.  This function is  called
'TraceFunc' and the corresponding function is called 'UntraceFunc' (or is
it only  'Untrace', I  can't remember).  Unfortunately  this  function is
next to useless because it simply produces too much output.
He continues:
I found out about Backtrace in some
message on this forum, but couldn't find it
in the manual.
Yes  it is  simply an oversight that 'Backtrace' isn't in the manual.  (I
guess  this  could happen because everyone of us used it so much  that we
never had to look it up in the manual ;-)
He continues:
Of course one can always interrupt
execution and inspect variables (very useful) and
after inserting enough ugly print statements in the
clean (but errant) gap code
one can eventually figure out what went wrong,
but then everything needs to be cleaned back up.
Yes, we do this a lot.  (A side note.  When I am  looking for a bug I use
lots of print  statemtents or  other  tools.  But more  often  than not I
finally nail  it  down while not sitting  at the terminal or  reading the
code.  It happens quite often on my way home.)
He continues:
Maybe other users have come up with more
elegant ideas?
Werner made one suggestion in his message. I address this below.
He continues:
I guess in an ideal world only bug
free code would be written, and gap goes a long way
towards implementing mathematical algorithms in a
natural way,
You might just as  well say  that  in  an  ideal world we would know  the
answers  to  all  (important)  questions  and  wouldn't  need  to  employ
computers at all.
He continues:
but with the innovative semantics of
list assingment I have managed to create some rather
subtle bugs.
Yes,  the  list  assignment  is  the  major  stumbling block  for  almost
everyone.  Especially those who had previously experience with Pascal, C,
or Fortran.   (Is anybody  reading this  forum  who was used to  Lisp and
found GAP's semantics quite natural?)
He continues:
Even so, writing gap routines is in my experience far
less time consuming that using traditional programming
tools.
Depends  on the problem of course.  But yes, for mathematical stuff  this
was our hope and is our experience too.
Werner Nickel answered less than 2 hours later:
Instead of interrupting an execution and end up at a more or
less random point in the GAP code one can use the function
Error() to halt the execution of GAP code at specific points.[example deleted]
As soon as Error() is executed, GAP goes into a break loop and one
can have a look at the state of the execution at this point. It is
possible, of course, to continue the execution by `returning' from
the break loop.
Indeed this is better than ordinary print statements,  because one can do
more things in the break loop.   (Of course one could  use '1/0;' instead
of 'Error()').
Still there are several problems  with this approach.  The  first is that
the bug  may not be  in your function but in a library function, and  you
may not have write permissions to edit the file in order to put a call to
'Error' into the function.
The other problem is more serious.  Suppose you have a  larger  function.
You have edited it, and it now contains a call to 'Error()'.  So you work
your  way through the execution.  After  quite some  time you finally see
something and  you say to yourself ``Ah,  I shouldn't  be looking at this
loop, this  loop  is probably o.k.  Instead I should be looking  at  this
other loop.''  Then you  would have to terminate your execution, edit the
file again, and *start all over again*.  This is very annoying.
Werner continues:
This technique suggests a way of implementing a step by step execution
of GAP code. The user would tell GAP at some point that she wants to
start to trace through the GAP code step by step. This could be done
by calling an internal function (which would have to be inserted at
some point into the GAP code). From then on, the internal functiont
which is responsible for executing a sequence of GAP statements could
generate a call to Error() after each statement has been executed. It
would also be useful to choose specific functions for step by step
execution. In this case a break loop would be created after each
statement in one of the chosen functions has been executed.I don't know how difficult it would be to make the necessary changes
to the GAP kernel. At a superficial level it does not look to be too hard.Any comments ?
(You knew I wouldn't resist ;-)
Let me put it this way.   Since the GAP kernel  is an interpreter (and so
the  machinery  to evaluate arbitrary expressions  is  always available),
since break-loops  are already  there,  and  since  the  functions of the
interpreter that  implement the (GAP level) function calls leave lots  of
information around  (which is  used  e.g. by  'Backtrace'),  most  of the
machinery to do all kinds of nice things is there.  Breakpoints that  can
be dynamically  set and  unset, single stepping, even  a  limited form of
watchpoints, should all be possible.
Still there  are a  few tricky issues.  The first is how to specify where
to put a breakpoint.  This will probably require that GAP keeps  track of
linenumbers.   For   another  example  if  one  wants   breakpoints  with
conditions  (e.g., break at line 123 but only if i <=  0), then it is not
so easy to ensure that  the variable  references  ('i'  in this case) are
evaluated in the right environment  (e.g.,  we probably  don't  mean  the
global variable 'i', but whatever variable would be referenced by  'i' in
line 123).
We are in contact  with Benno Fuchsteiners group in Paderborn.  They have
implemented a very nice debugger for a system that is implemented similar
to GAP.  We will see what of their ideas, or maybe even of their code, we
can use.
Martin.
-- .- .-. - .. -. .-.. --- ...- . ... .- -. -. .. -.- .- Martin Sch"onert, Martin.Schoenert@Math.RWTH-Aachen.DE, +49 241 804551 Lehrstuhl D f"ur Mathematik, Templergraben 64, RWTH, D 51 Aachen, Germany