Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-07 Thread David Roundy
On Thu, Sep 07, 2006 at 06:21:01AM +0100, Jn Fairbairn wrote:
> David Roundy <[EMAIL PROTECTED]> writes:
> 
> > On Wed, Sep 06, 2006 at 09:56:17AM -0700, Jason Dagit wrote:
> > > Or maybe even more extreme you could use template haskell or the c
> > > preprocessor to fill in the line number + column.
> > 
> > Which is precisely what darcs does for fromJust (which we use a lot):
> > we define a C preprocessor macro fromJust. 
> 
> Curiously, the only bug in darcs that has bitten me so far
> was a use of fromJust.  Perhaps that indicates a weakness in
> the style, rather than the tools?

Yeah, in general fromJust is a dangerous business, and most of the
uses of it in darcs can lead to trouble for partial repositories, for
instance.  I was just yesterday discussing with Jason the possibility
of switching away from a Maybe approach for lazily reading patches.
-- 
David Roundy
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-07 Thread Claus Reinke

>> thinking helps, but claiming that tools can't help doesn't.


Lets be absolutely clear about this: I've never claimed that
tools can't help. In this thread I've been using the term
debugger in the narrow sense implied by the OP's question --
something that steps through the execution of the code. Such
a debugger is inappropriate for Haskell programmers, and
doubly so for beginners.


well, then it is clear that we disagree on this. imho, being 
able to step through reductions is very appropriate for all
functional programmers (**), and an essential exercise 
for beginners. 

and if that is true for tiny examples on paper, then there 
should be tool support for applying it to larger programs.


from experience with the PI-RED systems, there are few
cases where one can apply such a tool without thinking
(eg. let it run till it gets stuck on an error, go a few steps
back to see where that erroneous part was constructed;
or let it run for a large number of steps, then check why
and where the program it is still growing instead of 
terminating). (*) 


after the initial learning phase, where such a stepper helps
to form the student's mental model of program evaluation,
the majority of debugging cases need to combine thinking
with experimentation, but dropping either of these two
ingredients makes the problem much harder. 

and it is nice to be able to do the experiments without 
having to switch tools or mindsets (although there are 
many ways in which the old PI-RED systems could have 
been improved, not to mention lessons learned from 
other tools, like Hat, that were developed for Haskell 
because there were no reduction systems for it).


claus

(*) note that the programmer never saw thunks, or 
   stacks, let alone heap objects or abstract machine
   code, only high-level program text, transformed by 
   reductions. intermediate programs were fully editable,
   in no way distinguished from the original programs 
   entered by the programmer, so one could make some 
   local observations, changes and reductions, then 
   continue with the overall reduction, or return to the 
   original program. compilation, decompilation, and 
   presentation were implicit, under the hood.


   for the PI-RED developers, though, there were 
   *separate* debugging tools that would allow them 
   to inspect the abstract machine's stack, heap, etc.. 
   and only if those failed to indicate the problem, 
   would they have to resort to C-level debugging 
   tools, another level lower.


(**) in fact, Berkling used to argue that was true for 
   all declarative programmers, and he extended his 
   ideas and machines to functional logic languages


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Jón Fairbairn
David Roundy <[EMAIL PROTECTED]> writes:

> On Wed, Sep 06, 2006 at 09:56:17AM -0700, Jason Dagit wrote:
> > Or maybe even more extreme you could use template haskell or the c
> > preprocessor to fill in the line number + column.
> 
> Which is precisely what darcs does for fromJust (which we use a lot):
> we define a C preprocessor macro fromJust. 

Curiously, the only bug in darcs that has bitten me so far
was a use of fromJust.  Perhaps that indicates a weakness in
the style, rather than the tools?

-- 
Jón Fairbairn [EMAIL PROTECTED]


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Jón Fairbairn
"Claus Reinke" <[EMAIL PROTECTED]> writes:


> thinking helps, but claiming that tools can't help doesn't.

Lets be absolutely clear about this: I've never claimed that
tools can't help. In this thread I've been using the term
debugger in the narrow sense implied by the OP's question --
something that steps through the execution of the code. Such
a debugger is inappropriate for Haskell programmers, and
doubly so for beginners.

-- 
Jón Fairbairn [EMAIL PROTECTED]


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Claus Reinke

"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:

   http://www.informatik.uni-kiel.de/~wk/papers_func.html
   ), 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.

claus

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Aaron Denney
On 2006-09-06, Andrae Muys <[EMAIL PROTECTED]> wrote:
> Jon understates it by implying this is a Functional/Haskell specific  
> quality - it's not.  Debuggers stopped being useful the day we  
> finally delegated pointer handling to the compiler/vm author and got  
> on with writing code that actually solves real problems.

Of course, these sometimes have bugs which we need to track down, in
which case having a debugger to show just how the vm is messing up 
can be very helpful.

-- 
Aaron Denney
-><-

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Neil Mitchell

Hi


I don't know what your getout plan was but when I'm in this situation
I do the following (hopefully listing this trick will help the OP):


I have headNote, fromJustNote, fromJustDefault, lookupJust,
lookupJustNote, tailNote - a whole set of functions which take an
extra note parameter - or for the example of lookupJust still give a
crash, but have both the thing you were searching for and the list of
things you were searching in - lookupJust requires a Show, so can
usually tell you roughly where you are.

I also always write it out as Module.Name.function - since line 5 has
a habit of being moved to a different line a lot more than names
changes.

And because I am used to this, maybe 95% of all unsafe functions are
already in Note form, so I just change the new ones I added since last
time I broke down and cried.

However, its useful, but hacky. Its not something I should have to do manually.

Thanks

Neil
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Chris Kuklewicz

David Roundy wrote:

On Wed, Sep 06, 2006 at 09:56:17AM -0700, Jason Dagit wrote:

Or maybe even more extreme you could use template haskell or the c
preprocessor to fill in the line number + column.


Which is precisely what darcs does for fromJust (which we use a lot):
we define a C preprocessor macro fromJust.  It's ugly, but beats any
other choice I'm aware of.  I wish that built in functions that call
error could be automatically this way...


This old mailing list message may help: 
http://www.mail-archive.com/haskell-cafe@haskell.org/msg13034.html


Suggested by a question from sethk on #haskell irc channel. 
Solves an FAQ where people have often resorted to cpp or m4:
a `trace' that prints line numbers.


--
Chris
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread David Roundy
On Wed, Sep 06, 2006 at 09:56:17AM -0700, Jason Dagit wrote:
> Or maybe even more extreme you could use template haskell or the c
> preprocessor to fill in the line number + column.

Which is precisely what darcs does for fromJust (which we use a lot):
we define a C preprocessor macro fromJust.  It's ugly, but beats any
other choice I'm aware of.  I wish that built in functions that call
error could be automatically this way...
-- 
David Roundy
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Johan Tibell

Note: I meant to send this to the whole list a couple of messages ago
but accidentally I only sent it to Lennart, sorry Lennart!

I know that Linus Torvalds doesn't find debuggers all that useful
either and he hacks C [1].

1. http://linuxmafia.com/faq/Kernel/linus-im-a-bastard-speech.html

On 9/6/06, Lennart Augustsson <[EMAIL PROTECTED]> wrote:

I've also used Visual Studio, and I wouldn't mind having something
like that for Haskell.  But I have to agree with Jon, I think the
best way of debugging is to understand your code.  I think people who
come from imperative programming come with a mind set that you
understand your code by stepping through it in the debugger.  But I
find this paradigm much less useful for functional code.

-- Lennart

On Sep 6, 2006, at 06:22 , Neil Mitchell wrote:

> Hi
>
>> But why should c and d exist at runtime? They're only used
>> once each, so the compiler is free to replace f with
>>
>> \a b -> (a+b)+ a*b
>
> Yes, and if the compiler is this clever, it should also be free to
> replace them back at debug time.
>
>
>> I've said this before, but I think it's worth repeating: in
>> most cases, if you need to debug your programme it's because
>> it's too complicated for you to understand, so the correct
>> thing to do is to simplify it and try again.
>
> That makes it impossible to ever improve - initially all programs are
> beyond you, and only by pushing the boundary do you get anywhere. As
> for me, I always write programs I can't understand, and that no one
> else can. Perhaps I understood it when I originally wrote it, perhaps
> not, but that was maybe over a year ago.
>
> It's been my experience that debugging is a serious weakness of
> Haskell - where even the poor mans printf debugging changes the
> semantics! And everyone comes up with arguments why there is no need
> to debug a functional language - that sounds more like excuses about
> why we can't build a good lazy debugger :)
>
> [Sorry for the slight rant, but I've used Visual Studio C++ so I know
> what a good debugger looks like, and how indispensable they are]
>
> Thanks
>
> Neil
> ___
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Jason Dagit

On 9/6/06, Neil Mitchell <[EMAIL PROTECTED]> wrote:


Let take for example a bug I spent tracking down in Haskell this
weekend. The bug can be summarized as "Program error: pattern match
failure: head []". And indeed, thats all you get. A quick grep reveals
there are about 60 calls to head in the program. In this instance I
have the choice between 1) crying, 2) a debugger, 3) a lot of hard
work. [Of course, knowing this situation arises, I had already
prepared my getout plan, so it wasn't a massive problem]


I don't know what your getout plan was but when I'm in this situation
I do the following (hopefully listing this trick will help the OP):

head' :: String -> [a] -> a
head' s [] = error $ "head' empty list at " ++ s
head' _ xs = head xs

Then I do the tedious thing of replacing all the heads in my program
with head' and giving each a unique string to print out, such as head'
"line 5".

You could even take this a step further and let the type system help
you find the places to replace head by doing something like:

import Prelude hiding (head)
import qualified Prelude (head)

head :: String -> [a] -> a
head s [] = error $ "head empty list at " ++ s
head _ xs = Prelude.head

Now you should get type errors anywhere you're using head.

Or maybe even more extreme you could use template haskell or the c
preprocessor to fill in the line number + column.

HTH,
Jason
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Malcolm Wallace
Andrae Muys <[EMAIL PROTECTED]> wrote:

> It's a truism to say if your code doesn't work it's because you don't 
> understand it; ...

Indeed, but tracing the execution of the code, on the test example where
it fails, will often give insight into one's misunderstanding.  And often,
the person trying to fix some code is not even the person who wrote it.

Help with understanding a program is the job of tracing tools like Hat,
Hood, or Buddha.  (These are often called debuggers.)  And I believe
this is what the original poster was asking for - a tool to reveal what
his code _really_ does as opposed to what he _thinks_ it ought to do.
Is that so terrible?

Many people seem to think that banishing some misunderstanding of a
piece of code is as simple as staring at it until enlightenment hits.  I
can vouch for the fact that, when the code is complex (and necessarily
so, because the problem logic is complex), then tools are needed for
full comprehension of the logic.

For example, when presented with a bug report for the nhc98 compiler
(which I maintain but did not create), using Hat has been invaluable to
me in narrowing down which function is to blame in mere minutes.  Prior
to Hat, it sometimes took several days of reading sources by hand,
manually tracking possible stacks of function calls over large data
structures, before even finding the site of the error.

Large software systems are complex.  Tool support for understanding
their behaviour is not needed because we humans are stupid, but because
there is just too much information context to keep in one head-ful at a
time.

> P.S. It is worth noting that I am here talking about the sort of  
> debugger raised in the original post. 
>   - I'm talking about runtime debugging with  
> variable watches, breakpoints, and line-by-line stepping.

I don't believe that is necessarily what the original poster was asking
for.  And reduction-by-reduction stepping can be extremely useful for
beginners to understand how lazy evaluation works.

Regards,
Malcolm
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Pepe Iborra
On 06/09/2006, at 17:10, Andrae Muys wrote:On 06/09/2006, at 8:22 PM, Neil Mitchell wrote:It's been my experience that debugging is a serious weakness ofHaskell - where even the poor mans printf debugging changes thesemantics! And everyone comes up with arguments why there is no needto debug a functional language - that sounds more like excuses aboutwhy we can't build a good lazy debugger :)[Sorry for the slight rant, but I've used Visual Studio C++ so I knowwhat a good debugger looks like, and how indispensable they are]I simply can't let this pass without comment.  It's irrelevant if you're using a functional or imperative language, debuggers are invariably a waste of time.  The only reason to use a debugger is because you need to inspect the contents of a processes address-space; so either you're using it as a disassembler, or you're using it to examine the consequences of heap/stack corruption.  Consequently, if you're using Java, C#, Scheme, Haskell, Erlang, Smalltalk, or any one of a myriad of languages that don't permit direct memory access, there's no reason for you to be using a debugger.Jon understates it by implying this is a Functional/Haskell specific quality - it's not.  Debuggers stopped being useful the day we finally delegated pointer handling to the compiler/vm author and got on with writing code that actually solves real problems.You seem to base everything on the assumption that a debugger is a program that lets you, and I quote your words below, "trace through individual lines of code".A debugger in the sense that this post regards it is any kind of program that helps you to understand a piece of code. A debugger is the program that tries to answer the following questions:"What information can we provide to the programmers about how a program is running?""What information will help the programmer most?"If it happens that traditionally debuggers are based in inspecting the memory, this is an unavoidable situation considering the history of programming languages. But certainly there are many other possibilities that can help a programmer to manage the complexity of a running program, and it seems as if you disregard them all completely in your argument !It's just that historically functional programmers have tended to already be experienced programmers who realise this.  Why would they waste their time building a tool that no-one needs?This whole block is offensive to the rest of the world. Fortunately it has nothing to do with reality: - the recent GHC survey uncovered "some kind of debugger" as the most demanded tool - Other functional languages have seen magnificent efforts in the debugging camp, such as the awesome Ocaml debugger or the now sadly defunct ML Time-Travel debugger from A. Tolmach - The Lispish languages, which are arguably on the functional side too, have always  enjoyed impressive online debugging tools.It's a truism to say if your code doesn't work it's because you don't understand it; clearly if you did understand it, you wouldn't have included the bug that's causing you difficulty.Therefore either1) The code is poorly structured and you need to restructure it to better represent your understanding of the problemor2) Your understanding of the problem is flawed, so you need to sit back and reexamine your thinking on this problem in light of the counter-example you have found (the bug).Spending your time tracing through individual lines of code is counter-productive in both cases.Andrae MuysP.S. It is worth noting that I am here talking about the sort of debugger raised in the original post.  I am not talking about using a separate tool to extract a stracktrace from a core file in a C/C++ program or equivalent - I'm talking about runtime debugging with variable watches, breakpoints, and line-by-line stepping. -- Andrae Muys[EMAIL PROTECTED]Principal Kowari ConsultantNetymon Pty Ltd ___Haskell-Cafe mailing listHaskell-Cafe@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Stefan Monnier
> I simply can't let this pass without comment.  It's irrelevant if you're
> using a functional or imperative language, debuggers are invariably
> a waste of time.  The only reason to use a debugger is because you need
> to inspect the contents of a processes address-space;

That's a very narrow definition of "debugger".


Stefan


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Neil Mitchell

Hi

I think that when it comes to debuggers and Haskell its fairly safe to say:

1) There aren't any which are production quality, regularly work "out
of the box" and are avaiable without much effort. There may be ones
which are debuggers (Hat/GHCi breakpoints), but we probably haven't
got to the stage where they are "polished" (being exceptionally vague
about what that means).

2) We disagree if they would be useful. I say yes. Others say no. I
guess this is an academic argument until we fix 1, and I guess no one
who says "no" to 2 is going to bother fixing 1.


H'm.  I've never been completely convinced that head should
be in the language at all.  If you use it, you really have
to think, every time you type in the letters h-e-a-d, "Am I
/really/ /really/ sure the argument will never be []?"
Otherwise you should be using a case expression or (more
often, I think) a subsidiary function with a pattern match.


I disagree (again...) - head is useful. And as you go on to say, if
you apply it to the infinite list, who cares if you used head. Head is
only unsafe on an empty list. So the problem then becomes can you
detect unsafe calls to head and let the programmer know.

Answer, not yet, but again, its being worked on:

http://www.cl.cam.ac.uk/~nx200/research/escH-hw.ps

http://www-users.cs.york.ac.uk/~ndm/projects/catch.php

Thanks

Neil
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Pepe Iborra

Here's another story.

A few weeks ago I was working on dynamic breakpoints for GHC. At that  
moment, I was trying to capture the bindings introduced by implicit  
parameters in the type of a function, in order to make them available  
at a breakpoint site.


Ok, disregard the stuff about me working on dynamic breakpoints. It  
is completely orthogonal to what I'm trying to convey here.


So, in order to capture these bindings, I had to introduce some code  
in dsBinds, the function that munches type constraints in the GHC  
desugarer. Or was it...? Doh, I don't even remember accurately and it  
was only a few days ago.


The problem is that this function would build on a lot of  
abstractions below it, particularly on a datatype called HsBind.  
There were some comments located near the datatype definition trying  
to give some insight about its meaning, but they were almost  
completely opaque to me. Even more, they referred to a paper, the one  
about Static Semantics of Haskell, which, even if interesting, was  
discouragingly long.


I was faced with the disjunctive of trying to completely understand  
the whole thing, or be more pragmatic and handle only the cases  
specific to my problem. A few traces showing me the structure  
received at dsBinds were incredibly productive: in a few minutes I  
was ready to test my solution.


The morale of the story is, imho, that sometimes the problem is not  
Haskell, the language; or C, the language. The problem is complexity  
and the size of the programs we are dealing with. It can easily be  
the case that you are dealing with code written by another person and  
you cannot afford the time necessary to completely understand its  
insides.


A good debugger may be counterproductive for issues in your own code,  
but it can be immensely helpful in a myriad other situations.


Cheers
pepe

On 06/09/2006, at 16:39, Jón Fairbairn wrote:


Here's a story:

A long time ago, when I was an undergraduate, I encountered
a visitor to the Computing Service who often asked for help
with the idiosyncrasies of the local system. I was happy to
help, though somewhat bemused by all the muttering at his
terminal while he was programming, which involved some sort
of debugging, for sure.  After some weeks he finished his
programme and whatever kept him in Cambridge and
disappeared.  Being curious, I dug (strictly against
regulations) a listing of his programme out of the scrap
bin. It was in PL/I, and several millimetres thick. It took
me quite a while (hours, though, not weeks) to work out what
the programme did, but eventually I understood it well
enough that I could write a version in Algol68 (my favourite
language at the time).  It came to one sheet of listing
paper.  This wasn't because A68 is more expressive than PL/I
(it is, but not by that much), it was because I understood
the problem before I started to write the code.

Now, you could argue that the first programmer spent most of
his time working out what the problem was (it might even be
true, but given that it boiled down to 1 page of A68, I'm
not sure), but my point is that if you proceed by debugging
rather than rewriting, you are likely to end up with this
sort of mess. Personally, I don't mind too much if that kind
of programmer finds Haskell too hard. Elitist? Certainly!
Immorally so? No.


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Jón Fairbairn
"Neil Mitchell" <[EMAIL PROTECTED]> writes:

> Hi
> 
> > > Yes, and if the compiler is this clever, it should also be free to
> > > replace them back at debug time.
> >
> > And where does that get us? You snipped the salient bit
> > where I said that you'd be debugging a different programme.
> 
> In Visual C there are two compilation modes. In debug mode, if you
> create a variable "i" it WILL be there in the compiled version. It
> won't be merged with another variable. It won't be constant folded. It
> won't have its value globablly computed and stored. It won't be placed
> only in the register. In release mode all these things can (and do)
> happen. I'm not saying Haskell compilers aren't free to optimize, but
> maybe there is a need for one that is this "debug mode" style.

I think this chiefly indicates that you think of variables
as things, which in Haskell they are not.

> > At no point have I ever
> > used a debugger on a Haskell programme.
> 
> Because you couldn't find a working debugger? ;) If one had been
> there, just a click away, would you never have been tempted?

Not in the least. The highest level language I've ever
wanted to use a debugger on was C, and that was for
debugging a pointer-reversing garbage collector, which ties
in with what Andrae says.

> Let take for example a bug I spent tracking down in Haskell this
> weekend. The bug can be summarized as "Program error: pattern match
> failure: head []". And indeed, thats all you get. A quick grep reveals
> there are about 60 calls to head in the program. In this instance I
> have the choice between 1) crying, 2) a debugger, 3) a lot of hard
> work. [Of course, knowing this situation arises, I had already
> prepared my getout plan, so it wasn't a massive problem]

H'm.  I've never been completely convinced that head should
be in the language at all.  If you use it, you really have
to think, every time you type in the letters h-e-a-d, “Am I
/really/ /really/ sure the argument will never be []?”
Otherwise you should be using a case expression or (more
often, I think) a subsidiary function with a pattern match.

Most of the occurrences of “head” in my code seem to be
applied to infinite lists, or commented out, or rebindings
of head to something else, sloppy bits of nonce programming
or references in comments to the top of my own noddle.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-07-14)

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Andrae Muys
On 06/09/2006, at 8:22 PM, Neil Mitchell wrote:It's been my experience that debugging is a serious weakness ofHaskell - where even the poor mans printf debugging changes thesemantics! And everyone comes up with arguments why there is no needto debug a functional language - that sounds more like excuses aboutwhy we can't build a good lazy debugger :)[Sorry for the slight rant, but I've used Visual Studio C++ so I knowwhat a good debugger looks like, and how indispensable they are]I simply can't let this pass without comment.  It's irrelevant if you're using a functional or imperative language, debuggers are invariably a waste of time.  The only reason to use a debugger is because you need to inspect the contents of a processes address-space; so either you're using it as a disassembler, or you're using it to examine the consequences of heap/stack corruption.  Consequently, if you're using Java, C#, Scheme, Haskell, Erlang, Smalltalk, or any one of a myriad of languages that don't permit direct memory access, there's no reason for you to be using a debugger.Jon understates it by implying this is a Functional/Haskell specific quality - it's not.  Debuggers stopped being useful the day we finally delegated pointer handling to the compiler/vm author and got on with writing code that actually solves real problems.It's just that historically functional programmers have tended to already be experienced programmers who realise this.  Why would they waste their time building a tool that no-one needs?It's a truism to say if your code doesn't work it's because you don't understand it; clearly if you did understand it, you wouldn't have included the bug that's causing you difficulty.Therefore either1) The code is poorly structured and you need to restructure it to better represent your understanding of the problemor2) Your understanding of the problem is flawed, so you need to sit back and reexamine your thinking on this problem in light of the counter-example you have found (the bug).Spending your time tracing through individual lines of code is counter-productive in both cases.Andrae MuysP.S. It is worth noting that I am here talking about the sort of debugger raised in the original post.  I am not talking about using a separate tool to extract a stracktrace from a core file in a C/C++ program or equivalent - I'm talking about runtime debugging with variable watches, breakpoints, and line-by-line stepping. -- Andrae Muys[EMAIL PROTECTED]Principal Kowari ConsultantNetymon Pty Ltd ___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Jón Fairbairn
Tamas K Papp <[EMAIL PROTECTED]> writes:

> On Wed, Sep 06, 2006 at 06:33:32AM -0400, Lennart Augustsson wrote:
> > I've also used Visual Studio, and I wouldn't mind having something  
> > like that for Haskell.  But I have to agree with Jon, I think the  
> > best way of debugging is to understand your code.  I think people who  
> > come from imperative programming come with a mind set that you  
> > understand your code by stepping through it in the debugger.  But I  
> > find this paradigm much less useful for functional code.
> 
> At this point, I need debugging not because I don't understand my
> code, but because I don't understand Haskell ;-) Most of the mistakes
> I make are related to indentation, precedence (need to remember that
> function application binds tightly).  The compiler and the type system
> catches some mistakes, but a few remain.

I don't think you need a debugger for that. In addition to
what Lennart and Ketil have said, I think you need to take
on board the usefulness of breaking functions up into small
pieces that can be run at the GHCi or Hugs command line. And
if you aren't sure about precedence, you can type something
that demonstrates it, like this sort of thing:

   *Main> let f = (+1)
   *Main> f 1 * 2
   4

(That particular example only works in GHCi, but you could use
let f = (+1) in f 1 * 2
in Hugs)

On top of that, in GHCi you can do this:

   *Main> :info +
   class (Eq a, Show a) => Num a where
 (+) :: a -> a -> a
 ...
   -- Imported from GHC.Num
   infixl 6 +
   *Main> :info *
   class (Eq a, Show a) => Num a where
 ...
 (*) :: a -> a -> a
 ...
   -- Imported from GHC.Num
   infixl 7 *
   *Main>

Note in particular the two infixl lines, which say that both
operators bind to the left and that “*” binds more tightly
than “+”

And there's always Hoogle (and the documentation it links
to) if you want to find something of a particular
type. Kudos to Neil for producing this, by the way (though I
do hope his remarks about the readability of his code were a
more self deprecating than accurate).

-- 
Jón Fairbairn [EMAIL PROTECTED]

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Neil Mitchell

Hi


> Yes, and if the compiler is this clever, it should also be free to
> replace them back at debug time.

And where does that get us? You snipped the salient bit
where I said that you'd be debugging a different programme.


In Visual C there are two compilation modes. In debug mode, if you
create a variable "i" it WILL be there in the compiled version. It
won't be merged with another variable. It won't be constant folded. It
won't have its value globablly computed and stored. It won't be placed
only in the register. In release mode all these things can (and do)
happen. I'm not saying Haskell compilers aren't free to optimize, but
maybe there is a need for one that is this "debug mode" style.


At no point have I ever
used a debugger on a Haskell programme.


Because you couldn't find a working debugger? ;) If one had been
there, just a click away, would you never have been tempted?



It may sound like that to you, but the arguments why
debugging is a bad thing are quite strong.  There are almost
certainly bugs in my Haskell code. Would a debugger help me
find them? Not in the least, because none of the testcases
I've used provokes them. Would it help when one is provoked?
I don't think so, because either the logic is right and
there's a slip up in the coding, which is usually easy to
find from the new testcase, or the logic is tortuous and
needs replacement.


Let take for example a bug I spent tracking down in Haskell this
weekend. The bug can be summarized as "Program error: pattern match
failure: head []". And indeed, thats all you get. A quick grep reveals
there are about 60 calls to head in the program. In this instance I
have the choice between 1) crying, 2) a debugger, 3) a lot of hard
work. [Of course, knowing this situation arises, I had already
prepared my getout plan, so it wasn't a massive problem]

Thanks

Neil
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Jón Fairbairn
"Neil Mitchell" <[EMAIL PROTECTED]> writes:

> Hi
> 
> > But why should c and d exist at runtime? They're only used
> > once each, so the compiler is free to replace f with
> >
> > \a b -> (a+b)+ a*b
> 
> Yes, and if the compiler is this clever, it should also be free to
> replace them back at debug time.

And where does that get us? You snipped the salient bit
where I said that you'd be debugging a different programme.

If the debugger serialises stuff and refers to variables, it
reinforces an imperative view of the world and supports the
erroneous view of variables as things that exist at
runtime. AFAIK, no implementation nowadays compiles to pure
combinators, but such would still be a valid implementation
of Haskell.  You need to develop a way of thinking about
programmes that produces insights that apply to Haskell, not
to a particular implementation.

> 
> > I've said this before, but I think it's worth repeating: in
> > most cases, if you need to debug your programme it's because
> > it's too complicated for you to understand, so the correct
> > thing to do is to simplify it and try again.
> 
> That makes it impossible to ever improve - initially all programs are
> beyond you, and only by pushing the boundary do you get anywhere.

I offer myself as a counter example. I'm not the world's
best Haskel programmer (that might be Lennart?;-), but I
understand it pretty well, I think. At no point have I ever
used a debugger on a Haskell programme. So clearly not
impossible (I didn't come into existence a fully fledged
functional programmer, which is the only other possibility
admitted by your argument).

> As for me, I always write programs I can't understand, and
> that no one else can. Perhaps I understood it when I
> originally wrote it, perhaps not, but that was maybe over
> a year ago.

No comment.

> It's been my experience that debugging is a serious weakness of
> Haskell - where even the poor mans printf debugging changes the
> semantics! And everyone comes up with arguments why there is no need
> to debug a functional language - that sounds more like excuses about
> why we can't build a good lazy debugger :)

It may sound like that to you, but the arguments why
debugging is a bad thing are quite strong.  There are almost
certainly bugs in my Haskell code. Would a debugger help me
find them? Not in the least, because none of the testcases
I've used provokes them. Would it help when one is provoked?
I don't think so, because either the logic is right and
there's a slip up in the coding, which is usually easy to
find from the new testcase, or the logic is tortuous and
needs replacement.

> [Sorry for the slight rant, but I've used Visual Studio C++ so I know
> what a good debugger looks like, and how indispensable they are]

So I'm ranting back at you.  I've used debuggers on C and
other old languages (particularly when writing in assembler)
and indeed they are useful when the language provides so
many opportunities for mistakes. When writing Haskell I've
never felt the need.

Here's a story:

A long time ago, when I was an undergraduate, I encountered
a visitor to the Computing Service who often asked for help
with the idiosyncrasies of the local system. I was happy to
help, though somewhat bemused by all the muttering at his
terminal while he was programming, which involved some sort
of debugging, for sure.  After some weeks he finished his
programme and whatever kept him in Cambridge and
disappeared.  Being curious, I dug (strictly against
regulations) a listing of his programme out of the scrap
bin. It was in PL/I, and several millimetres thick. It took
me quite a while (hours, though, not weeks) to work out what
the programme did, but eventually I understood it well
enough that I could write a version in Algol68 (my favourite
language at the time).  It came to one sheet of listing
paper.  This wasn't because A68 is more expressive than PL/I
(it is, but not by that much), it was because I understood
the problem before I started to write the code.

Now, you could argue that the first programmer spent most of
his time working out what the problem was (it might even be
true, but given that it boiled down to 1 page of A68, I'm
not sure), but my point is that if you proceed by debugging
rather than rewriting, you are likely to end up with this
sort of mess. Personally, I don't mind too much if that kind
of programmer finds Haskell too hard. Elitist? Certainly!
Immorally so? No.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-07-14)

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Ketil Malde
Tamas K Papp <[EMAIL PROTECTED]> writes:

> Most of the mistakes I make are related to indentation, 

I use Emacs, which has a reasonably decent mode for this.  Hit TAB
repeatedly to show the possible indentations.

> precedence (need to remember that function application binds
> tightly).

It's not always intuitive, but at least there is a fixed rule that's
easy to remember.

-k
-- 
If I haven't seen further, it is by standing in the footprints of giants

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Lennart Augustsson
So it sounds like what you need at the moment is more of a Haskell  
pretty printer than a debugger. :)
IDEs, like Visual Studio, can be very helpful when writing code in a  
language you don't really know, I've noticed this writing VBA.  I  
wish Visual Haskell were ready for real use.


-- Lennart

On Sep 6, 2006, at 08:13 , Tamas K Papp wrote:


On Wed, Sep 06, 2006 at 06:33:32AM -0400, Lennart Augustsson wrote:

I've also used Visual Studio, and I wouldn't mind having something
like that for Haskell.  But I have to agree with Jon, I think the
best way of debugging is to understand your code.  I think people who
come from imperative programming come with a mind set that you
understand your code by stepping through it in the debugger.  But I
find this paradigm much less useful for functional code.


At this point, I need debugging not because I don't understand my
code, but because I don't understand Haskell ;-) Most of the mistakes
I make are related to indentation, precedence (need to remember that
function application binds tightly).  The compiler and the type system
catches some mistakes, but a few remain.

Thanks for the suggestions.

Tamas
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Tamas K Papp
On Wed, Sep 06, 2006 at 06:33:32AM -0400, Lennart Augustsson wrote:
> I've also used Visual Studio, and I wouldn't mind having something  
> like that for Haskell.  But I have to agree with Jon, I think the  
> best way of debugging is to understand your code.  I think people who  
> come from imperative programming come with a mind set that you  
> understand your code by stepping through it in the debugger.  But I  
> find this paradigm much less useful for functional code.

At this point, I need debugging not because I don't understand my
code, but because I don't understand Haskell ;-) Most of the mistakes
I make are related to indentation, precedence (need to remember that
function application binds tightly).  The compiler and the type system
catches some mistakes, but a few remain.

Thanks for the suggestions.

Tamas
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Lennart Augustsson
I've also used Visual Studio, and I wouldn't mind having something  
like that for Haskell.  But I have to agree with Jon, I think the  
best way of debugging is to understand your code.  I think people who  
come from imperative programming come with a mind set that you  
understand your code by stepping through it in the debugger.  But I  
find this paradigm much less useful for functional code.


-- Lennart

On Sep 6, 2006, at 06:22 , Neil Mitchell wrote:


Hi


But why should c and d exist at runtime? They're only used
once each, so the compiler is free to replace f with

\a b -> (a+b)+ a*b


Yes, and if the compiler is this clever, it should also be free to
replace them back at debug time.



I've said this before, but I think it's worth repeating: in
most cases, if you need to debug your programme it's because
it's too complicated for you to understand, so the correct
thing to do is to simplify it and try again.


That makes it impossible to ever improve - initially all programs are
beyond you, and only by pushing the boundary do you get anywhere. As
for me, I always write programs I can't understand, and that no one
else can. Perhaps I understood it when I originally wrote it, perhaps
not, but that was maybe over a year ago.

It's been my experience that debugging is a serious weakness of
Haskell - where even the poor mans printf debugging changes the
semantics! And everyone comes up with arguments why there is no need
to debug a functional language - that sounds more like excuses about
why we can't build a good lazy debugger :)

[Sorry for the slight rant, but I've used Visual Studio C++ so I know
what a good debugger looks like, and how indispensable they are]

Thanks

Neil
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Neil Mitchell

Hi


But why should c and d exist at runtime? They're only used
once each, so the compiler is free to replace f with

\a b -> (a+b)+ a*b


Yes, and if the compiler is this clever, it should also be free to
replace them back at debug time.



I've said this before, but I think it's worth repeating: in
most cases, if you need to debug your programme it's because
it's too complicated for you to understand, so the correct
thing to do is to simplify it and try again.


That makes it impossible to ever improve - initially all programs are
beyond you, and only by pushing the boundary do you get anywhere. As
for me, I always write programs I can't understand, and that no one
else can. Perhaps I understood it when I originally wrote it, perhaps
not, but that was maybe over a year ago.

It's been my experience that debugging is a serious weakness of
Haskell - where even the poor mans printf debugging changes the
semantics! And everyone comes up with arguments why there is no need
to debug a functional language - that sounds more like excuses about
why we can't build a good lazy debugger :)

[Sorry for the slight rant, but I've used Visual Studio C++ so I know
what a good debugger looks like, and how indispensable they are]

Thanks

Neil
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: how do you debug programs?

2006-09-06 Thread Jón Fairbairn
Tamas K Papp <[EMAIL PROTECTED]> writes:

> I would like to learn a reasonable way (ie how others do it) to debug
> programs in Haskell.  Is it possible to "see" what's going on when a
> function is evaluated?  Eg in
> 
> f a b = let c = a+b
>   d = a*b
>   in c+d
> 
> evaluating 
> 
> f 1 2
> 
> would output something like
> 
> f called with values 1 2
> c is now (+) a b => (+) 1 2 => 3
> d is now (*) a b => (*) 1 2 => 2

But why should c and d exist at runtime? They're only used
once each, so the compiler is free to replace f with 

\a b -> (a+b)+ a*b

and indeed, it's quite likely that f should disappear
too. So if your debugger outputs what you want, it's not
debugging the programme that you would otherwise have run.

> Or maybe I am thinking the wrong way, and functional programming has
> its own debugging style...

I've said this before, but I think it's worth repeating: in
most cases, if you need to debug your programme it's because
it's too complicated for you to understand, so the correct
thing to do is to simplify it and try again. That's not to
say that I don't think you should test programmes... in fact
I'm all for testing little bits. You can define f above and
try it on a few arguments in ghci or hugs, and you can use
QuickCheck and/or HUnit to automate this. But there's no
reason for you to care what happens while f is evaluating.

Remember there's very little (often no) overhead for
defining subsidiary functions, so break complicated stuff
into parts you can understand.



-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-07-14)

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe