Claus Reinke | 24 Nov 18:41 2008

Re: GHCi debugger status

> fun x y =
> let f1 = ... (f2 x) ...   -- f1 calls f2
>     f2 x = x * 2
> in case x of
>     1 -> f2 0
>     _ -> f2 (f1 y)
> 
> g x = let z = (some complex computation) in z `div` x
> 
> main = print (g (fun 1 2))
> 
> This is a classical example of why laziness gets in the way of
> debugging. Now, when (f2 0) gets finally evaluated and throws a
> divByZero error, x and y are nowhere to be found.
> Since we do not have a real dynamic stack, it is difficult to say
> where their values should be stored. The only place I can think of is
> at the breakpoint itself, but then as Simon said this poses a serious
> efficiency problem.

Isn't that a case of premature optimization? I will happily compain
about performance issues later, after the debugger turns out to be
merely too slow!-) Currently, the issue is one of it not working as 
well as it could, which seems rather more important to me (think 
of it as infinitely too slow for my needs:-). 

Once it comes to performance issues (btw, is there a debugger 
home page on the wiki, where issues/FAQs like "why can't I have 
scope contexts" are documented?), an obvious compromise would 
be to state explicitly where to preserve scope information - 
something like:

    :break fun{x,y}/{f1,f2}/f2{x}

would set a breakpoint on f2, associating with it information about 
the static scope context including only the named names (items 
between // define the path towards the name we want to break, 
level by level; additional names can be added in {} at each level), 
without affecting other parts of the program.

Claus

Gmane