Re: [Haskell-cafe] Laziness leaks

2008-06-04 Thread Bernie Pope


On 04/06/2008, at 10:12 AM, Ronald Guida wrote:

I would ask, how do I examine the evaluation order of my code, but
the answer is already available: use a debugger.  Haskell already has
debugging tools that do exactly what I need.
(http://www.haskell.org/haskellwiki/Debugging)

In particular, HOOD looks extremely interesting.


I would recommend the GHCi debugger for looking at the evaluation  
order of code.

Single stepping can be very illuminating.

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


Re: [Haskell-cafe] Laziness leaks

2008-06-04 Thread Jules Bean

Ronald Guida wrote:

[snip]


By default, a lazy language will procrastinate.  By default, a strict
language will anticrastinate.  Either way, I can waste resources by
blindly accepting the default time management plan.


Nice analysis.

Would you like to put that (the whole thing, not just that last para) on 
the wiki?


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


[Haskell-cafe] Laziness leaks

2008-06-03 Thread Ronald Guida
I was looking at the real time queues in [1] and I wanted to see what
would happen if I tried to write one in Haskell.  The easy part was
translating the real time queue from [1], p43 into Haskell.

The hard part is testing to see if the rotations really happen what
they should.  Basically, I decided to use Debug.Trace.trace to see
when rotations were actually occurring.

I pushed the numbers 1 to 10 into the queue, and then I popped the
queue ten times.  What I found is that none of the rotations would
actually take place until the first time I actually tried to /display
the value/ of a popped element.  What I realized is that my test
driver is lazy.  I figured out that I could put a bunch of 'seq'
functions in the test driver to get the rotations to happen.

My demonstration code is in:
http://hpaste.org/8080

This leads to two questions:

1. If I find a laziness leak, is 'seq' the appropriate way to plug it?

2. Is there any way to systematically search for or detect laziness
   leaks?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Laziness leaks

2008-06-03 Thread Albert Y. C. Lai

Ronald Guida wrote:

I was looking at the real time queues in [1] and I wanted to see what
would happen if I tried to write one in Haskell.  The easy part was
translating the real time queue from [1], p43 into Haskell.

The hard part is testing to see if the rotations really happen what
they should.  Basically, I decided to use Debug.Trace.trace to see
when rotations were actually occurring.

I pushed the numbers 1 to 10 into the queue, and then I popped the
queue ten times.  What I found is that none of the rotations would
actually take place until the first time I actually tried to /display
the value/ of a popped element.  What I realized is that my test
driver is lazy.  I figured out that I could put a bunch of 'seq'
functions in the test driver to get the rotations to happen.

My demonstration code is in:
http://hpaste.org/8080

This leads to two questions:

1. If I find a laziness leak, is 'seq' the appropriate way to plug it?

2. Is there any way to systematically search for or detect laziness
   leaks?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe



I want to point out several non-causes of laziness. For a no-magic, 
no-surprise understanding, it is important to know both what causes 
laziness and what does not.


A. The lazy list at rtqRear, which is originally a strict list. It is an 
invariant that every thunk you put there is [] or x:y. (As a result, it 
is unnecessary to make RTQueue a strict record, since you want two of 
the fields to be lazy, and the remaining field rtqRear is de facto strict.)


B. rtqueue's thunked call to rotate, i.e.,

   rtqueue f r []= let f' = rotate f r [] in RTQueue f' [] f'

Originally f' is forced before the record is returned (SML convention). 
In Haskell the rotate call is thunked as f' and the record is returned. 
But there will not be an accumulation of such rotate thunks. For example 
if you snoc twice in succession and the first instance builds a rotate 
thunk:


   snoc p (snoc q (RTQueue f r []))
- snoc p (rtqueue f (q:r) [])
- snoc p (RTQueue f' [] f')  where f' = thunk
- rtqueue f' p:[] f'  where f' = thunk
- f' is now forced by rtqueue's pattern matching on the 3rd param

So if one snoc builds a rotate thunk, the next snoc kills it. And 
similarly any interleaving of queue operations. (head and tail add their 
extra pattern matching.) Thus it can be proved that Haskell lags behind 
the original by just one step in this regard. This is ok unless you're 
done with reducing asymptotic cost and start looking at constant factor 
cost.


A true cause of laziness is in accumulating a chain of tail's and snocs 
without intermediate forcing, as observed.

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


Re: [Haskell-cafe] Laziness leaks

2008-06-03 Thread Ronald Guida
Don Stewart wrote:
 2. Is there any way to systematically search for or detect laziness
leaks?

 Profiling, and looking at the Core. Being explicit about the
 evaluation strategy you want is a fine idea though.

Albert Y. C. Lai wrote
 A true cause of laziness is in accumulating a chain of tail's and
 snocs without intermediate forcing, as observed.

So I just thought of something.  If laziness leads to laziness leaks,
then is there such a thing as a strictness leak?  I realized that the
answer is yes.

A lazy leak is a situation where I'm wasting resources to delay a
sequence of calculations instead of just doing them now.  But in a
strict language, I might waste resources to compute things that I'll
never need.  I would call that a strictness leak.

Now I could ask the dual question, How do I detect strictness leaks,
and I would probably get the same answers: profiling, looking at
object code, and being explicit about the evaluation strategy.

Both types of leaks share a lot in common.  In both cases, I'm wasting
resources.  If I have a real-time system, then either type of leak can
cause me to a miss a deadline.

With a strict evaluation strategy, I might miss a nearby deadline
because I'm busy calculating things that I don't need until the
distant future.

With a lazy evaluation strategy, I might miss a distant deadline
because I'm lazily putting off a calculation now.

If I were a college student, then this would be a laziness leak:

  Professor X assigns a report, due in a month.  Two days before the
  report is due, I'll head to the drugstore, load up on caffeine, and
  work for 48 hours straight to get it done.

And this would be a strictness leak:

  Professor X assigns a report, due in a month.  As soon as I leave
  the classroom, I'll head to the drugstore, load up on caffeine, and
  work for 48 hours straight to get it done.

And this would be an effective solution:

  Professor X assigns a report, due in a month.  I'll select 15 days,
  spaced out over the next month, and allocate four hours per day to
  work on the report.

By default, a lazy language will procrastinate.  By default, a strict
language will anticrastinate.  Either way, I can waste resources by
blindly accepting the default time management plan.

So the real question is How do I avoid laziness leaks or strictness
leaks and apparently, the real answers are (1) learn how to
recognize when the default plan will waste resources, and (2) learn
how to express reasonable evaluation strategies in code.

I would ask, how do I examine the evaluation order of my code, but
the answer is already available: use a debugger.  Haskell already has
debugging tools that do exactly what I need.
(http://www.haskell.org/haskellwiki/Debugging)

In particular, HOOD looks extremely interesting.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Laziness leaks

2008-06-03 Thread Derek Elkins
On Tue, 2008-06-03 at 20:12 -0400, Ronald Guida wrote:
 Don Stewart wrote:
  2. Is there any way to systematically search for or detect laziness
 leaks?
 
  Profiling, and looking at the Core. Being explicit about the
  evaluation strategy you want is a fine idea though.
 
 Albert Y. C. Lai wrote
  A true cause of laziness is in accumulating a chain of tail's and
  snocs without intermediate forcing, as observed.
 
 So I just thought of something.  If laziness leads to laziness leaks,
 then is there such a thing as a strictness leak?  I realized that the
 answer is yes.

I ask a similar question here albeit for a much narrower and more
technical notion:
http://lambda-the-ultimate.org/node/2273#comment-40156
and come to the same conclusion (at least for an even more narrow
notion).

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