Re: [Haskell-cafe] Debugging

On 5/4/07, Monang Setyawan
On 5/5/07, Stefan O'Rear
wrote: On Sat, May 05, 2007 at 11:36:16AM +0700, Monang Setyawan wrote:
Hi, I'm a beginner Haskell user.
Is there any way to trace/debug the function application in GHC?
Absolutely!
stefan@stefans:/tmp$ ghci X.hs ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.7.20070502, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help.
Loading package base ... linking ... done. [1 of 1] Compiling Main ( X.hs, interpreted ) Ok, modules loaded: Main. *Main> :break fac
Great!! Thanks, it really helps. I should update my GHC to the newest version (I use the old 6.4.2 with no break command)
Is there any editor/IDE supporting this break command? It should be cooler if we can debug functions just by placing mark in the line.
Stefan
-- Demi masa..
-- Demi masa.. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
I've only written trivial applications and functions in haskell. But the title of this thread got me thinking. In an imperative language you have clear steps, states, variables to watch, etc. What techniques/strategies might one use for a functional language? --ryan

On Fri, May 04, 2007 at 10:44:15PM -0700, Ryan Dickie wrote:
I've only written trivial applications and functions in haskell. But the title of this thread got me thinking.
In an imperative language you have clear steps, states, variables to watch, etc. What techniques/strategies might one use for a functional language?
I personally most often use a divide-and-conquer approach. I pick a point about halfway down the call stack, and add trace calls. If the subproblems are handled correctly, narrow scope to higher levels; otherwise narrow to lower levels. Repeat until you have a single misbehaving function. Stefan

On 5/5/07, Stefan O'Rear
On Fri, May 04, 2007 at 10:44:15PM -0700, Ryan Dickie wrote:
I've only written trivial applications and functions in haskell. But the title of this thread got me thinking.
In an imperative language you have clear steps, states, variables to watch, etc. What techniques/strategies might one use for a functional language?
I personally most often use a divide-and-conquer approach. I pick a point about halfway down the call stack, and add trace calls. If the subproblems are handled correctly, narrow scope to higher levels; otherwise narrow to lower levels. Repeat until you have a single misbehaving function.
Isn't that called binary search, instead of divide-and-conquer? BTW, how about adding assertion in Haskell? Can it be done? (I've searched in my GHC 6.4.2 library documentation, and can't find 'assert') Is there any way to automatically clean all the mess I've done in debugging/asserting (like removing all trace/assert expressions) when I compile Haskell source code? Or should I create a simple program to remove them?
Stefan
-- Demi masa..

monang:
On 5/5/07, Stefan O'Rear
wrote: On Fri, May 04, 2007 at 10:44:15PM -0700, Ryan Dickie wrote:
I've only written trivial applications and functions in haskell. But the title of this thread got me thinking.
In an imperative language you have clear steps, states, variables to watch, etc. What techniques/strategies might one use for a functional language?
I personally most often use a divide-and-conquer approach. I pick a point about halfway down the call stack, and add trace calls. If the subproblems are handled correctly, narrow scope to higher levels; otherwise narrow to lower levels. Repeat until you have a single misbehaving function.
Isn't that called binary search, instead of divide-and-conquer?
BTW, how about adding assertion in Haskell? Can it be done? (I've searched in my GHC 6.4.2 library documentation, and can't find 'assert')
'assert' is in Control.Exception. there's also a couple of 3rd party packages for assert-like behaviour: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/loch-0.2 http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Safe-0.1
Is there any way to automatically clean all the mess I've done in debugging/asserting (like removing all trace/assert expressions) when I compile Haskell source code? Or should I create a simple program to remove them?
Using a logging/writer monad might be a nice approach. 'assert's are compiled out under -O, in G, too. -- Don

Sorry, replying myself.
On 5/5/07, Monang Setyawan
BTW, how about adding assertion in Haskell? Can it be done? (I've searched in my GHC 6.4.2 library documentation, and can't find 'assert')
This can be done using Assertions. Lines below are taken from the docs. Assertions assert :: Bool -> a -> a If the first argument evaluates to True, then the result is the second argument. Otherwise an AssertionFailed exception is raised, containing a String with the source file and line number of the call to assert. Assertions can normally be turned on or off with a compiler flag (for GHC, assertions are normally on unless optimisation is turned on with -O or the -fignore-asserts option is given). When assertions are turned off, the first argument to assert is ignored, and the second argument is returned as the result.

Ryan Dickie wrote:
I've only written trivial applications and functions in haskell. But the title of this thread got me thinking.
In an imperative language you have clear steps, states, variables to watch, etc. What techniques/strategies might one use for a functional language?
Well, breakpoints and traces exist, and they're useful, as Stefan showed. However in the presence of a decent repl (ghci) and a useful type system, I most often find myself debugging by trying out my functions in the repl. If your problem is nicely broken down, you can test the smallest functions first, see if they are behaving as expected, and then work up. The 'next step' is to move from testing by hand in ghci to writing quickcheck properties / smallcheck / unit tests for the functions. You'll find the need for imperative-style debugging techniques surprisingly infrequent. Jules

On May 10, 2007, at 10:19 AM, Jules Bean wrote:
The 'next step' is to move from testing by hand in ghci to writing quickcheck properties / smallcheck / unit tests for the functions.
I still don't understand the difference between QC and SC. Would someone kindly explain and provide an example or two of when SC should be used? Thanks, Joel -- http://wagerlabs.com/

Joel Reymont wrote:
On May 10, 2007, at 10:19 AM, Jules Bean wrote:
The 'next step' is to move from testing by hand in ghci to writing quickcheck properties / smallcheck / unit tests for the functions.
I still don't understand the difference between QC and SC. Would someone kindly explain and provide an example or two of when SC should be used?
The most important difference is that: QC checks 'a random selection' of possible parameter values. SC checks 'every possible' in some methodical way, stopping at a certain depth for recursive structures.

Hi
The basic advantages of SC (stolen from the user manual):
* write test generators for your own types more easily?
* be sure that any counter-examples found are minimal?
* write properties using existentials as well as universals?
* establish complete coverage of a defined test-space?
* display counter-examples of functional type?
* guarantee repeatable test results?
The disadvantage is that if your program only crashes on larger
expressions, it will probably take forever to find a counter example.
Thanks
Neil
On 5/10/07, Jules Bean
Joel Reymont wrote:
On May 10, 2007, at 10:19 AM, Jules Bean wrote:
The 'next step' is to move from testing by hand in ghci to writing quickcheck properties / smallcheck / unit tests for the functions.
I still don't understand the difference between QC and SC. Would someone kindly explain and provide an example or two of when SC should be used?
The most important difference is that:
QC checks 'a random selection' of possible parameter values.
SC checks 'every possible' in some methodical way, stopping at a certain depth for recursive structures.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (7)
-
dons@cse.unsw.edu.au
-
Joel Reymont
-
Jules Bean
-
Monang Setyawan
-
Neil Mitchell
-
Ryan Dickie
-
Stefan O'Rear