<div dir="ltr">Concur with Jon's point. <div>I'm uncomfortable with making foldMap/sum strict.</div><div>Haskell was intended to explore a region of the programming design space that had not been well covered. and it remains</div><div>if not unique then at least exemplary in that respect. When I write in Haskell I do so with the knowledge that I am working with</div><div>lazy evaluation with the benefits and risk that comes with that. If I'm desperate to have finer operational control, I either</div><div>swallow that pill and adapt my use of Haskell accordingly, or pick up a different tool from the programming language toolbox.</div><div><br></div><div>Now the OP pointed to an issue with one specific use of sum. However, that seems like weak grounds to make library changes:</div><div>1. we dont knowing the context. the best way to avoid the cost of computation is not to compute it; what alternatives are there</div><div>i this s[ecific problem.</div><div>2. if one was to make foldMap/sum strict why not also other functions, e.g. scanAccum, where does one stop on the grounds of possibly saving costs in so as yet</div><div>unknown application</div><div>3. Instead of thinking/programming in a pure lazy language, you are then in the position of thinking lazily apart from some set of</div><div>to be determined exceptional cases. the simplicity and uniformity of the model is gone.</div><div>4. As per item 3 but from a pedagogical point of view. I taught UG FP for years. Complicating the model is not going to help students,</div><div>to say nothing of the caveats that would have to be added to existing teaching materials.</div><div>So whilst the post was clearly intended to trigger discussion, in terms on conveying sentiment a strict foldMap would be a big '-'</div><div>for me personally. Whilst there are performance challenges in working with Haskell. The primary role of the programming notation</div><div>is allowing one to think about the problem and obtain a clear, correct solution. Performance tuning comes later if at all, and</div><div>her are known techniques for doing so with Haskell/ghc.</div><div>5. OTOH I see little harm in adding a library that provides a strict foldMap for those</div><div>who want to use it after deliberate thought.</div><div><br></div><div>YMMMocV</div><div>David</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Oct 22, 2020 at 10:36 AM Jon Fairbairn <<a href="mailto:jon.fairbairn@cl.cam.ac.uk">jon.fairbairn@cl.cam.ac.uk</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Sylvain Henry <<a href="mailto:sylvain@haskus.fr" target="_blank">sylvain@haskus.fr</a>> writes:<br>
<br>
> Do we have an actual example of the use of a lazy sum in the<br>
> wild?<br>
<br>
That’s not a very good argument, though I’ve seen it used quite<br>
a lot. The problem is that just because no-one can currently<br>
think of a “real” example it doesn’t mean that there are no<br>
cases where laziness is required.<br>
<br>
For a forced example, consider a wrapping of Double with a test<br>
for infinity on the left argument<br>
<br>
…<br>
a + b | isInfinite a = a<br>
…<br>
<br>
which doesn’t evaluate it’s second argument if the first is<br>
infinite.<br>
<br>
> If the most common case is the strict one, making `sum`<br>
> strict would be a better default.<br>
<br>
Haskell should remain a lazy language, so the defaults should be<br>
lazy unless they can be proved strict anyway.<br>
<br>
> If need be we could also provide `lazySum` or something, but<br>
> is there really a need?<br>
<br>
Who can truly say? I’d support sum' as the strict version as<br>
that is consistent with other usages.<br>
<br>
— Jón<br>
<br>
><br>
> Sylvain<br>
><br>
><br>
> On 18/10/2020 22:16, Oleg Grenrus wrote:<br>
>><br>
>> Sorry I wasn't clear myself. Option C is "add sum'"<br>
>><br>
>> For lists:<br>
>><br>
>> sum = foldr (+) 0<br>
>> sum' = foldl' (+) 0<br>
>><br>
>> For Foldable<br>
>><br>
>> sum = getSum #. foldMap Sum<br>
>> sum' = getSum #. foldMap' Sum<br>
>><br>
>> - Oleg<br>
>><br>
>> On 18.10.2020 23.11, Hécate wrote:<br>
>>><br>
>>> Indeed, and I initially went to suggest a<br>
>>> foldMap'`-based implementation to keep with the current<br>
>>> implementation of many Foldable functions that are based<br>
>>> on `foldMap` rather than a raw `fold`.<br>
>>><br>
>>> On 18/10/2020 22:04, Oleg Grenrus wrote:<br>
>>>> For the sake of bigger audience I didn't bother<br>
>>>> mentioning #. which is a coercion helper. It's<br>
>>>> essentially better (.) when the first argument is<br>
>>>> newtype constructor (i.e. coerce).<br>
>>>><br>
>>>> So with Option A (strict):<br>
>>>><br>
>>>> sum = getSum #. foldMap' Sum<br>
>>>><br>
>>>> Or Option B (lazy)<br>
>>>><br>
>>>> sum = getSum #. foldMap Sum<br>
>>>><br>
>>>> ---<br>
>>>><br>
>>>> There is also third option, Option C:<br>
>>>><br>
>>>> sum = foldr (+) 0<br>
>>>> sum' = foldl' (+) 0<br>
>>>><br>
>>>> I don't think this is worthwhile, but it is an option.<br>
>>>> (to rehash, I don't consider maintaining status quo to<br>
>>>> be an option at all).<br>
>>>><br>
>>>> - Oleg<br>
>>>> On 18.10.2020 22.54, Vanessa McHale wrote:<br>
>>>>><br>
>>>>> It's<br>
>>>>><br>
>>>>> sum = getSum #. foldMap Sum<br>
>>>>><br>
>>>>> in base.<br>
>>>>><br>
>>>>> On 10/18/20 2:49 PM, Oleg Grenrus wrote:<br>
>>>>>><br>
>>>>>> The problem is the current definition of sum for lists<br>
>>>>>> which uses foldl, i.e non-strict left fold<br>
>>>>>><br>
>>>>>> sum = foldl (+) 0<br>
>>>>>><br>
>>>>>> It's utterly broken. Either we should change it to<br>
>>>>>> foldl' to work on some types where addition is strict,<br>
>>>>>> Option A:<br>
>>>>>><br>
>>>>>> sum = foldl' (+) 0<br>
>>>>>><br>
>>>>>> or alternatively (to make people using lazy<br>
>>>>>> accumulator types), Option B:<br>
>>>>>><br>
>>>>>> sum = foldr (+) 0<br>
>>>>>><br>
>>>>>> The current state is no good for anyone or anything.<br>
>>>>>><br>
>>>>>> ---<br>
>>>>>><br>
>>>>>> Related issue which Hecate didn't clearly mention, is<br>
>>>>>> that Foldable class default implementation has<br>
>>>>>><br>
>>>>>> class Foldable f where<br>
>>>>>> ...<br>
>>>>>> sum = getSum . foldMap Sum -- this is "good" lazy definition<br>
>>>>>><br>
>>>>>> If we select option A, then I argue that for<br>
>>>>>> consistency the default `Foldable.sum` should be<br>
>>>>>><br>
>>>>>> sum = getSum . foldMap' Sum -- strict foldMap'<br>
>>>>>><br>
>>>>>> If we select option B, Foldable definition doesn't need to be changed.<br>
>>>>>><br>
>>>>>> ---<br>
>>>>>><br>
>>>>>> I repeat, using non-strict left fold, foldl, for sum<br>
>>>>>> and product is not good for anything.<br>
>>>>>> Either foldr or foldl'.<br>
>>>>>><br>
>>>>>> I have no strong preference. Current state is unacceptable.<br>
>>>>>><br>
>>>>>> - Oleg<br>
>>>>>><br>
>>>>>> On 18.10.2020 22.24, Henning Thielemann wrote:<br>
>>>>>>><br>
>>>>>>> On Sun, 18 Oct 2020, Hécate wrote:<br>
>>>>>>><br>
>>>>>>>> In conclusion, leaving things to the optimiser that<br>
>>>>>>>> could be trivially made fast every time seems<br>
>>>>>>>> needlessly risky.<br>
>>>>>>><br>
>>>>>>> `seq` is still a hack. A strict 'sum' and 'product'<br>
>>>>>>> would still fail on a lazy accumulator type, say a<br>
>>>>>>> lazy pair type. If at all, sum and product should be<br>
>>>>>>> deepseq-strict. So currently, letting the optimiser<br>
>>>>>>> make a lazy sum strict is still the smaller hack.<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>
>>> Hécate ✨<br>
>>> IRC: Uniaika<br>
>>> WWW:<a href="https://glitchbra.in" rel="noreferrer" target="_blank">https://glitchbra.in</a><br>
>>> RUN: BSD<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>
<br>
-- <br>
Jón Fairbairn <a href="mailto:Jon.Fairbairn@cl.cam.ac.uk" target="_blank">Jon.Fairbairn@cl.cam.ac.uk</a><br>
<a href="http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html" rel="noreferrer" target="_blank">http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html</a> (updated 2014-04-05)<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>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div>David Duke</div><div>Emeritus Professor of Computer Science</div><div>School of Computing University of Leeds UK</div><div><a href="mailto:E%3Aduke.j.david@gmail.com" target="_blank">E:duke.j.david@gmail.com</a></div><div>W:<a href="https://engineering.leeds.ac.uk/staff/334/Professor_David_Duke" target="_blank">https://engineering.leeds.ac.uk/staff/334/Professor_David_Duke</a></div></div></div></div></div></div></div></div></div>