<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Mar 4, 2016 at 8:30 AM, Eric Seidel <span dir="ltr"><<a href="mailto:eric@seidel.io" target="_blank">eric@seidel.io</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Fri, Mar 4, 2016, at 06:53, Johannes Waldmann wrote:<br>
> Dear Cafe,<br>
><br>
> the new (8.*) call stack feature<br>
> <a href="https://downloads.haskell.org/~ghc/8.0.1-rc2/docs/html/users_guide/glasgow_exts.html#hascallstack" rel="noreferrer" target="_blank">https://downloads.haskell.org/~ghc/8.0.1-rc2/docs/html/users_guide/glasgow_exts.html#hascallstack</a><br>
> is certainly nice for debugging during development.<br>
><br>
> But how costly is it at runtime? I notice a 5 percent slowdown.<br>
<br>
</span>HasCallStack is really just a type class with a couple special rules for<br>
building dictionaries in GHC's constraint solver. So at runtime each<br>
function with a HasCallStack constraint takes an extra CallStack<br>
argument. I don't know how to quantify the performance implications<br>
beyond that, but you're right that HasCallStack is not free.</blockquote><div><br></div><div>Hmm, is it no longer an implicit parameter?  I thought the new</div><div>HasCallStack stuff was just a constraint synonym like</div><div><br></div><div>type HasCallStack = (?callStack :: CallStack)</div><div><br></div><div>For the most part the distinction doesn't matter, but it does when it</div><div>comes to constraints in instance heads.  The issue is that constraints</div><div>are not solved at their callsites.  Do we want `HasCallStack` to be</div><div>able to be present in an instance head, and potentially get a location</div><div>quite different from the actual use site?  I would find this confusing,</div><div>though sometimes helpful.</div><div><br></div><div>Implicit parameters are a good match for this callstack stuff, because</div><div>they have the restriction that they cannot be used as supeclass</div><div>constraints.</div><div><br></div><div>Does your work on the callstack stuff (thanks!) introduce backwards</div><div>compatibility issues?  I'm working on a library that will make extensive</div><div>use of 7.10's implementation of callstacks.</div><div> </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> That's not a problem if there's an easy way to switch<br>
> this off for production (without changing the code).<br>
<br>
</span>Since HasCallStack is not a feature of the RTS, but actually part of the<br>
generated code, there's not really an easy way to disable it without<br>
changing the code. As much as I dislike CPP, I think it's the best<br>
solution for a toggleable HasCallStack, something like<br>
<br>
#if DEBUG<br>
#define HASCALLSTACK (HasCallStack)<br>
#else<br>
#define HASCALLSTACK ()<br>
#endif<br>
<br>
foo :: HASCALLSTACK => a -> b<br>
<br>
ought to work.<br>
<span class=""><br>
> Related: how to make code that uses it,<br>
> compile with older ghcs that don't have it.<br>
><br>
> I made this hack: do not import GHC.Stack.Types, but instead<br>
><br>
> {-# language CPP, MultiParamTypeClasses #-}<br>
><br>
> #if (__GLASGOW_HASKELL__ < 710)<br>
> {-# language NullaryTypeClasses #-}<br>
> #endif<br>
><br>
> module Stack<br>
> ( HasCallStack )<br>
> where<br>
><br>
> #if (__GLASGOW_HASKELL__ >= 800)<br>
> import GHC.Stack.Types<br>
> #else<br>
> class HasCallStack<br>
> instance HasCallStack<br>
> #endif<br>
<br>
</span>This might be a nice addition to the base-compat package.<br>
<span class=""><br>
> When I compile with 8.rc2, and change ">= 800" to ">= 900",<br>
> I am getting the 5 percent speedup mentioned above.<br>
><br>
> But does it really do what I hope it does<br>
> (remove all runtime overhead that call stacks may have)?<br>
<br>
</span>It should remove all the overhead of call stacks for calling functions<br>
you wrote. If you import a function with a HasCallStack constraint<br>
there's no way to disable the overhead for that function (for good<br>
reason, it might use the CallStack!).<br>
<span class=""><br>
> When I compile with 7.10.3, I am getting 5 .. 10 percent faster again.<br>
><br>
> My code does nothing fancy (w.r.t. types and libraries),<br>
> it just uses Data.IntMap heavily. And it has some<br>
><br>
> class Semiring s where<br>
>   zero :: s<br>
>   one  :: s<br>
>   plus :: HasCallStack => s -> s -> s<br>
>   times :: HasCallStack => s -> s -> s<br>
<br>
</span>I'm curious, why do plus and times take a CallStack? I wouldn't expect<br>
them to be partial, so it seems like unnecessary overhead.<br>
<span class="HOEnZb"><font color="#888888"><br>
Eric<br>
</font></span><div class="HOEnZb"><div class="h5">_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br>
</div></div></blockquote></div><br></div></div>