"scientists, who ought to know,
assure us that it must be so,
oh, let us never, never, doubt,
what nobody is sure about."
(or something like that..;-)
as everyone else in this thread, I have my own experiences and
firm opinions on the state of debugging support in Haskell (in
particular on the apparent ease with which operational semantics
or stepwise reduction are often dismissed), but just a few points:
- if you're sure about anything, that probably just means you've
stopped thinking about that thing - not a good position for
imposing your assured opinion on others, imho.
- a debugger is (mainly) a tool for finding and removing bugs:
- if you're crawling through the machine's circuitboards in
search of a real bug, that might be a screwdriver, a
flashlight, and a circuitdiagram/floorplan
- if you don't like to use computers to augment your
mental processes, that might be pencil and paper
- if you do like to use computers to augment your
mental processes, that might be some piece of software
- what kind of software might be helpful in debugging
depends as much on what you are debugging as on
your individual approach to debugging
- assuming that you're not debugging the hardware, compiler,
runtime system, or foreign code, functional languages free
you from many sources of bugs. but not of all sources.
- simplifying the code until it becomes easily comprehensible
is a good habit anyway, and it does help to expose bugs
that creep in while you're juggling too many balls at once
(is the code "obviously correct" or "not obviously wrong"?).
for those so inclined, tools can help here, too: they can
expand our limits of comprehension, they can assist in
the simplification, they can highlight big-balls-of-mud in
your code, etc.
- often, finding bugs is linked to comprehending the program's
operational behaviour, so that you can be sure that it is
going to do all that you need it to do, and nothing else.
that in itself does not imply, however, that you need to
include your language's implementation into the set of
things to debug.
- it is perfectly possible to study the operational behaviour
of functional programs without resorting to implementation
details - that falls under operational semantics, and last
time I checked, it had become at least as well respected
as denotational semantics, not least because of its successes
in reasoning about programs in concurrent languages.
- a useful equivalent to observing instruction-by-instruction
state changes when debugging imperative programs is to
observe reduction-by-reduction program transformations
when debugging functional programs.
based on operational semantics, tool support for this
approach is not just possible, but was used with good
success in the past (interested parties might like to browse,
eg, the 1994 user's guide for PI-RED, or the 1996 papers
on teaching experience, in FPLE, and system overview, in JFP:
), just not for Haskell.
note that this constitutes a semantics-based inspection at
the language level, completely independent of the actual
implementation below. hiding implementation details while
presenting a high-level operational semantics is a non-trivial
exercise that includes such topics as variables, bindings
and substitution, as well as retranslating low-level machine
states to corresponding intermediate high-level programs.
so, while there are reasonable and less reasonable ways of
using debuggers, the question is not whether or not there
should be debuggers, but what kind of tools we have or
need to help debugging and, more generally, comprehending,
Haskell programs. and if the state of the art indicates that
such tools are either kludges (affecting program semantics,
exposing low-level machine details, etc), do not cover the
whole Haskell-in-use, or simply don't help those who'd
like to use them, then that state is not good. it is a lot better
than it used to be, but far from optimal.
thinking helps, but claiming that tools can't help doesn't.