<div dir="ltr">Thanks for all your response very much, I greatly appreciate that my immature idea was discussed seriously. I like this community and hope to do more, but now I have several questions and I cannot answer them by myself since my knowledge is limited.<br><br>1. Is `-xc` as good as `HasCallStack` in debugging experience, without considering performance issue?<br>2. Will `withFrozenCallStack` cancel the adverse effect of performance caused by `HasCallStack`?<br>3. Is there a test set for performance so we can measure the performance lost after the change?<br><br>For the 1st question, AFAIK there is indeed some differences between the two stack tracing solutions:<div>First, the stack trace generated by `-xc` has no line number and column number of the call site.</div><div>Second, when we run a long running program, such as a web service, it is not easy to reproduce the issue, most of the time, you have no chance to recompile or restart your program to debug, all you can rely on is the printed logs, this makes `-xc` not as useful as `HasCallStack`. </div><div>Third, the `HasCallStack` solution is much more friendly for learners, you don't need to know any tricks to get a stack trace printed, this reason seems ridiculous but IMHO it indeed affects the learning curve of Haskell.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Carter Schonwald <<a href="mailto:carter.schonwald@gmail.com">carter.schonwald@gmail.com</a>> 于2019年6月22日周六 上午2:42写道:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">agreed, the -xc flag is an underused debugging tool, and making that easier to work with / front and center is probably a high impact approach</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jun 19, 2019 at 11:11 AM Matthew Pickering <<a href="mailto:matthewtpickering@gmail.com" target="_blank">matthewtpickering@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I find this thread a bit concerning. In my opinion the current best<br>
way to get call stacks on exceptions is with `-xc`. Adding runtime<br>
overhead to every user program is not acceptable.<br>
<br>
`HasCallStack` is useful in libraries such as shake or hspec which use<br>
them to good effect to provide callstacks to users on exceptions<br>
controlled by the libraries.<br>
<br>
There is an argument that it would be good to disentangle `-xc` from<br>
`prof` but you would still have to compile `base` in this way which<br>
instruments these partial functions (as a user can not do it herself).<br>
I'm not too sure on the details but I don't think -xc uses any<br>
information from the profiling header so the fact it's connected with<br>
-prof seems more like convenience than necessity.<br>
<br>
Matt<br>
<br>
On Wed, Jun 19, 2019 at 3:48 PM LuoChen <<a href="mailto:luochen1990@gmail.com" target="_blank">luochen1990@gmail.com</a>> wrote:<br>
><br>
> @eric Thanks, this withFrozenCallstack  works as expected! Maybe we can provide a compiler option to automatically insert `withFrozenCallstack` somewhere when importing other packages, so that we can focus on current working package's call stack, just like david said.<br>
><br>
> Eric Seidel <<a href="mailto:eric@seidel.io" target="_blank">eric@seidel.io</a>> 于2019年6月19日周三 下午7:25写道:<br>
>><br>
>> You can use withFrozenCallstack to avoid adding new entries to the stacktrace (but you still need HasCallstack constraints all the way down to error, of course).<br>
>><br>
>> <a href="http://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-Stack.html#v:withFrozenCallStack" rel="noreferrer" target="_blank">http://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-Stack.html#v:withFrozenCallStack</a><br>
>><br>
>> Sent from my iPhone<br>
>><br>
>> On Jun 19, 2019, at 00:41, LuoChen <<a href="mailto:luochen1990@gmail.com" target="_blank">luochen1990@gmail.com</a>> wrote:<br>
>><br>
>> @david It seem that we doesn't have such a mechanism yet. AFAIK with `HasCallStack` we can only build a call stack from the deepest bottom.<br>
>><br>
>> Is it possible to build a call stack from middle of the call chain to the top, without containing the deepest parts?<br>
>> e.g. f1 -> f2 -> f3 -> error  (f -> g means f call g) , is it possible to build a call stack only contains f1 and f2, without f3 and error?<br>
>><br>
>> David Feuer <<a href="mailto:david.feuer@gmail.com" target="_blank">david.feuer@gmail.com</a>> 于2019年6月18日周二 上午3:57写道:<br>
>>><br>
>>> As I recall, the main things to watch out for, performance-wise, are recursive definitions. When we throw an error from a library function, we *typically* mean that the caller made a mistake. We don't want to build up the call stacks we'd need to debug the library function itself, unless we're actually doing so (in which case we can edit it in, of course).<br>
>>><br>
>>> On Mon, Jun 17, 2019, 1:09 PM Edward Kmett <<a href="mailto:ekmett@gmail.com" target="_blank">ekmett@gmail.com</a>> wrote:<br>
>>>><br>
>>>> Re: your code. This is passing the callStack to each instance and dropping it on the floor for the cases where you ignore the constraint.<br>
>>>><br>
>>>> I’m starting to warm to the idea of putting HasCallStack constraints on the obviously partial combinators in base if we can demonstrate that the performance impact isn't bad in practice, and even really, to some extent if there is a somewhat middling impact on the performance of code that leans on these hard to debug combinators, so long as the performance of their more total siblings remains unaffected. The impact on the perceived debuggability of Haskell seems _likely_ to significantly outweigh the performance concerns.<br>
>>>><br>
>>>> Heck, off of the HEAD of cabal, which we’re encouraging folks to build to play with the ghc 8.8.1 alpha, just today we ran into an issue where the very build system we are using spat out an oh so informative “Prelude.foldr1: Empty list” when using a pkgconfig-depends stanza that didnt include any explicit bounds.<br>
>>>><br>
>>>> It seems worth implementing and measuring quite how bad the impact would be before pulling the trigger for good. The impact should be reasonable if the constraints only really live right at the outside of base though, then users can choose to propagate the constraint further outwards, just like they get to do with “error” today.<br>
>>>><br>
>>>> Slightly more controversially, MonadFail’s fail could be similarly modified with near zero user facing impact other than a bit of additional static info flowing to explicit callstacks to make it take a HasCallStack constraint. The code in existing instances would all still work. This one I think would need more benchmarking though, as recovering from a fail is a far “lighter” affair than catching an exception, but I’d be happy to raise it to the CLC as a question, especially if we can get benchmarks in hand.<br>
>>>><br>
>>>> —Edward<br>
>>>><br>
>>>><br>
>>>> On Jun 17, 2019, at 4:06 PM, LuoChen <<a href="mailto:luochen1990@gmail.com" target="_blank">luochen1990@gmail.com</a>> wrote:<br>
>>>><br>
>>>> I have just confirmed that we can specify HasCallStack separately for different instance of same typeclass, and here is the test code.<br>
>>>><br>
>>>><br>
>>>> Oliver Charles <<a href="mailto:ollie@ocharles.org.uk" target="_blank">ollie@ocharles.org.uk</a>> 于2019年6月17日周一 上午3:02写道:<br>
>>>>><br>
>>>>> Surely then the call stack is only foldr1, and not foldr1's callsite?<br>
>>>>><br>
>>>>> On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, <<a href="mailto:lemming@henning-thielemann.de" target="_blank">lemming@henning-thielemann.de</a>> wrote:<br>
>>>>>><br>
>>>>>><br>
>>>>>> On Sun, 16 Jun 2019, Simon Jakobi wrote:<br>
>>>>>><br>
>>>>>> > >  I think only the partial implementations should get that constraint.<br>
>>>>>><br>
>>>>>> > Oops, I had the misconception that one couldn't add a HasCallStack<br>
>>>>>> > constraint to method implementations.<br>
>>>>>><br>
>>>>>> I think you have to declare:<br>
>>>>>><br>
>>>>>> instance Foldable [] where<br>
>>>>>>     foldl1 = foldl1List<br>
>>>>>><br>
>>>>>> foldl1List :: HasCallStack => (a->a->a) -> [a] -> a<br>
>>>>>> foldl1List = ...<br>
>>>>>><br>
>>>>>> Would this work?_______________________________________________<br>
>>>>>> Libraries mailing list<br>
>>>>>> <a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
>>>>>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
>>>><br>
>>>> _______________________________________________<br>
>>>> Libraries mailing list<br>
>>>> <a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
>>>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
>>>><br>
>>>> _______________________________________________<br>
>>>> Libraries mailing list<br>
>>>> <a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
>>>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
>><br>
>> _______________________________________________<br>
>> Libraries mailing list<br>
>> <a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
><br>
> _______________________________________________<br>
> Libraries mailing list<br>
> <a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></div>
</blockquote></div>