<div class="gmail_quote">2009/4/28 Thomas Hartman <span dir="ltr">&lt;<a href="mailto:tphyahoo@gmail.com">tphyahoo@gmail.com</a>&gt;</span></div><div class="gmail_quote"><span dir="ltr"></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

I suppose this means that the points-free/pattern binding-style<br>
version is a bit less work for ghc to execute (fewer reductions),<br>
whereas the version with lambda bound variables is easier to debug.</blockquote><div><br></div><div>I don&#39;t think there is any (significant) difference between them in the amount of work done at runtime. The observed difference in behaviour is more a matter of how the debugging transformation in GHCi interprets the command &quot;set a breakpoint on f&quot;, and how the code for f is generated.</div>
<div><br></div><div>I think my previous email was slightly misleading, and we should be careful to distinguish between &#39;evaluating f&#39; and &#39;evaluating applications of f&#39;. In both cases f is already a value (either a partial application or a lambda function). So f itself doesn&#39;t really undergo &#39;reduction&#39;, in the theoretical sense. However, a compiler, such as GHC, may generate code which does a little bit of work at runtime, and the debugger may be able to observe that work. When f is written in the pattern binding style, the breakpoint on f reveals the &#39;evaluation of f&#39;, which is just the little bit of work at runtime I was talking about. When f is written in function binding style, the breakpoint on f reveals &#39;an evaluation of an application of f&#39; (which may happen more than once).</div>
<div><br></div><div>Normally, when people attach a breakpoint on a function, they want to see the evaluation of applications of the function. So the behaviour of the debugger for functions defined in the pattern binding style can be confusing.</div>
<div><br></div><div>The debugger could arrange things so that both styles of definition give the same behaviour wrt breakpoints, for example by eta-expanding definitions.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
On balance, I think I&#39;ll frequently write my functions with lambda<br>
bound variables then.</blockquote><div><br></div><div>It does seem a shame to modify your code style for the sake of the debugger, but I guess that is inevitable with procedural debuggers anyway.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
2009/4/26 Bernie Pope &lt;<a href="mailto:florbitous@gmail.com">florbitous@gmail.com</a>&gt;:<br>
<div><div></div><div class="h5">&gt; 2009/4/25 Thomas Hartman &lt;<a href="mailto:tphyahoo@gmail.com">tphyahoo@gmail.com</a>&gt;<br>
&gt;&gt;<br>
&gt;&gt; In the program below, can someone explain the following debugger output to<br>
&gt;&gt; me?<br>
&gt;&gt;<br>
&gt;&gt;  After :continue, shouldn&#39;t I hit the f  breakpoint two more times?<br>
&gt;&gt;  Why do I only hit the f breakpoint once?<br>
&gt;&gt;  Is this a problem in the debugger?<br>
&gt;&gt;<br>
&gt;&gt; thartman@ubuntu:~/haskell-learning/debugger&gt;cat debugger.hs<br>
&gt;&gt;<br>
&gt;&gt; -- try this:<br>
&gt;&gt; -- ghci debugger.hs<br>
&gt;&gt; -- &gt; :break f<br>
&gt;&gt; -- &gt; :trace t<br>
&gt;&gt; -- &gt; :history -- should show you that f was called from h<br>
&gt;&gt; t = h . g . f $ &quot;hey!&quot;<br>
&gt;&gt; t2 = h . g . f $ &quot;heh!&quot;<br>
&gt;&gt; t3 = h . g . f $ &quot;wey!&quot;<br>
&gt;&gt;<br>
&gt;&gt; f = (&quot;f -- &quot; ++)<br>
&gt;&gt; g = (&quot;g -- &quot; ++)<br>
&gt;&gt; h = (&quot;h -- &quot; ++)<br>
&gt;&gt;<br>
&gt;&gt; ts = do<br>
&gt;&gt;  putStrLn $ t<br>
&gt;&gt;  putStrLn $ t2<br>
&gt;&gt;  putStrLn $ t3<br>
&gt;<br>
&gt; What you are observing is really an artifact of the way breakpoints are<br>
&gt; attached to definitions in the debugger, and the way that GHCi evaluates<br>
&gt; code.<br>
&gt; f is clearly a function, but its definition style is a so-called &quot;pattern<br>
&gt; binding&quot;. The body contains no free (lambda bound) variables, so it is also<br>
&gt; a constant. GHCi arranges for f to be evaluated at most once. The breakpoint<br>
&gt; associated with the definition of f is fired if and when that evaluation<br>
&gt; takes place. Thus, in your case it fires exactly once.<br>
&gt; You can re-write f to use a so-called &quot;function binding&quot; instead, by<br>
&gt; eta-expansion (introduce a new fresh variable, and apply the function to it<br>
&gt; on both sides):<br>
&gt;    f x = (&quot;f -- &quot; ++) x<br>
&gt; This denotes the same function, but the breakpoint on f works differently.<br>
&gt; In this case, a breakpoint attached to f will fire whenever an application<br>
&gt; of f is reduced. If you write it this way you will see that the program<br>
&gt; stops three times instead of one.<br>
&gt; You might ask: if both definitions denote the same function, why does the<br>
&gt; debugger behave differently? The short answer is that the debugger in GHCi<br>
&gt; is an operational debugger, so it exposes some of the operational details<br>
&gt; which may be invisible in a denotational semantics. In this case it revels<br>
&gt; that GHCi treats the two definitions of f differently.<br>
&gt; Cheers,<br>
&gt; Bernie.<br>
&gt;<br>
</div></div></blockquote></div><br>