Newbie:Debugging and Overgeneralization

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Newbie:Debugging and Overgeneralization

Aditya Siram
I have been working with a Haskell text for the past couple of months or so
and I have some general problem solving questions.

1. Is there a way to output intermediate values of a calculation? As an
imperative programmer I have become used to using "System.out"'s or 'cout's
to check that my function works as intended. I can see no easy way to do
that in Haskell. The only solution I could come up with was to avoid using
nested functions except for the most trivial expressions and test all
expressions in the interpreter. This approach seems to make my code ugly and
less readable.

2. Haskell is great because it makes abstracting from problem very easy. For
example, if the problem asks for the area of a square, why not write a
function to compute the area of all polygons?  find myself falling into the
trap of generalizing to the point that a simple problem becomes quite a bit
harder . From a general design perspective should I concentrate on
abstracting away just enough to solve the problem or solve the harder
problem in the hoping of reusing that code to make life easier in the
future?


Thanks....
Deech


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Newbie:Debugging and Overgeneralization

Neil Mitchell
Hi Deech,

> 1. Is there a way to output intermediate values of a calculation?
Debug.Trace.trace is what you want, its not quite as convenient (or
safe) as cout, but its usually good enough. If you want to see more
detail then Hat (http://www.haskell.org/hat) is probably what you
want.

> From a general design perspective should I concentrate on
> abstracting away just enough to solve the problem or solve the harder
> problem in the hoping of reusing that code to make life easier in the
> future?
Do what you need to do now, only abstract if it makes this current
problem easier to solve. For example, by separating two phases of an
algorithm, the code might become cleaner and more abstract. In this
case, the code becoming cleaner is the thing to strive for, not more
abstract. If however you know that you will need a function in the
future, you might as well abstract now, but don't do it on the
offchance that it will be useful.

Thanks

Neil
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Newbie:Debugging and Overgeneralization

Bugzilla from robdockins@fastmail.fm
In reply to this post by Aditya Siram

On May 15, 2006, at 11:14 AM, Aditya Siram wrote:

> I have been working with a Haskell text for the past couple of  
> months or so and I have some general problem solving questions.
>
> 1. Is there a way to output intermediate values of a calculation?  
> As an imperative programmer I have become used to using  
> "System.out"'s or 'cout's to check that my function works as  
> intended. I can see no easy way to do that in Haskell. The only  
> solution I could come up with was to avoid using nested functions  
> except for the most trivial expressions and test all expressions in  
> the interpreter. This approach seems to make my code ugly and less  
> readable.

Two responses here:

1) Check out Debug.Trace in the standard libs.  (http://
www.haskell.org/ghc/docs/latest/html/libraries/base/Debug-
Trace.html)  It lets you insert debugging messages into pure code.  
Be warned, its a little tricky to use; your message will only be  
printed _when_and_if_ the thing you "attach" the message to is  
evaluated.

2) I'm not sure exactly what you mean by "nested functions", but  
writing small functions and composing them together to do larger  
tasks is a pretty Haskellish way to approach things.  As you noted,  
this lets you easily test subparts of your computation, and it's  
generally considered good style.  Appropriate use of the composition  
operator (.) or of monads can make function composition more readable.

Creating intermediate representations and writing functions that  
transform data between these representations is a good way to  
structure programs that allows this compositional style.  See: http://
www.haskell.org/hawiki/IntermediateRepresentation

> 2. Haskell is great because it makes abstracting from problem very  
> easy. For example, if the problem asks for the area of a square,  
> why not write a function to compute the area of all polygons?  find  
> myself falling into the trap of generalizing to the point that a  
> simple problem becomes quite a bit harder . From a general design  
> perspective should I concentrate on abstracting away just enough to  
> solve the problem or solve the harder problem in the hoping of  
> reusing that code to make life easier in the future?

I'd say, unless you are developing a general-purpose library, solve  
the problem in the simplest (correct!) way first.  One of the nice  
things about Haskell is that its easy to replace code under the hood  
at a later time (pure functional programming is your friend).


For example if you write:

 > areaOfSquare :: Square -> Double
 > areaOfSquare = <special purpose code>


And later you discover you also need:

 > areaOfNPolygon :: NPolygon -> Double
 > areaOfNPolygon = <n-polygon code>


You can replace areaOfSquare with:

 > areaOfSquare = areaOfNPolygon . squareToNPolygon


to reduce duplication, or you can keep the special-purpose code in  
the interests of efficiency.  If you keep the special-purpose code,  
you can use quick check to make sure it gives the same answer as the  
n-polygon routine, which is a nice benefit.



Rob Dockins

Speak softly and drive a Sherman tank.
Laugh hard; it's a long way to the bank.
           -- TMBG

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe