Proposal: add HasCallStack for all partial functions in base
Edward Kmett
ekmett at gmail.com
Mon Jun 17 20:18:20 UTC 2019
I definitely do not want to push them through recursive functions! But e.g. foldr1 builds its error just once despite being recursive. We’d need to be somewhat careful there, but otherwise the cost should basically be comparable to a cons.
-Edward
> On Jun 17, 2019, at 10:02 PM, Eric Seidel <eric at seidel.io> wrote:
>
> I did some very basic benchmarks back when I implemented HasCallStack. What I remember finding back then was that there was a small overhead for non-recursive functions like `head` but a substantial overhead for recursive functions. (My benchmarks are available at https://github.com/gridaphobe/located-base/tree/master/bench.)
>
> So if we want to add HasCallStack to partial `base` functions, I'd suggest extra care around recursive functions ((!!) comes to mind). Perhaps rewrite them to use an inner recursive loop that does not extend the CallStack (this might produce nicer stacktraces anyway).
>
> Eric
>
>> On Mon, Jun 17, 2019, at 13:09, Edward Kmett wrote:
>> 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.
>>
>> 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.
>>
>> 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.
>>
>> 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.
>>
>> 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.
>>
>> —Edward
>>
>>
>>> On Jun 17, 2019, at 4:06 PM, LuoChen <luochen1990 at gmail.com> wrote:
>>>
>>> I have just confirmed that we can specify `HasCallStack` separately for different instance of same typeclass, and here <https://gist.github.com/luochen1990/bc556d0fc6a1355e5d1bd27a81114870> is the test code.
>>
>>>
>>> Oliver Charles <ollie at ocharles.org.uk> 于2019年6月17日周一 上午3:02写道:
>>>> Surely then the call stack is only foldr1, and not foldr1's callsite?
>>>>
>>>>> On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, <lemming at henning-thielemann.de> wrote:
>>>>>
>>>>> On Sun, 16 Jun 2019, Simon Jakobi wrote:
>>>>>
>>>>>>> I think only the partial implementations should get that constraint.
>>>>>
>>>>>> Oops, I had the misconception that one couldn't add a HasCallStack
>>>>>> constraint to method implementations.
>>>>>
>>>>> I think you have to declare:
>>>>>
>>>>> instance Foldable [] where
>>>>> foldl1 = foldl1List
>>>>>
>>>>> foldl1List :: HasCallStack => (a->a->a) -> [a] -> a
>>>>> foldl1List = ...
>>>>>
>>>>> Would this work?_______________________________________________
>>>>> Libraries mailing list
>>>>> Libraries at haskell.org
>>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>> _______________________________________________
>>> Libraries mailing list
>>> Libraries at haskell.org
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>> _______________________________________________
>> Libraries mailing list
>> Libraries at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
More information about the Libraries
mailing list