<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Hi Vanessa, thanks for the question.<br>
      <br>
      I compiled the following code:<br>
      <br>
      ```<br>
      module Main where               <br>
                                      <br>
      main = do                       <br>
        let result = sum [1..10^9]      <br>
        print result                    <br>
      ```<br>
      <br>
      with the following command:<br>
      <br>
      ghc -rtsopts -On --make Main.hs<br>
      <br>
      and ran the binary like that:<br>
      <br>
      ./Main +RTS -M1024m -RTS <br>
      <br>
      Compiled with -O0, the heap overflows<br>
      <br>
      Starting with -O1, it runs fine.<br>
      <br>
      However:<br>
      <br>
      I am not able to tell you what kind of optimisation is responsible
      for this,<br>
      and to be quite honest, I don't see why we should trust the
      optimiser to produce behaviours that could be upstreamed;
      behaviour that  is enabled at the first sign of optimisation.<br>
      <br>
      I am not fundamentally opposed to the concept of having neat
      optimisations in GHC, but experience tells me that<br>
      1. They can (and will) regress<br>
      2. They can (and will) interact in weird ways<br>
      3. This naked call gets optimised, that's great, but how will it
      react with other Foldables, with fusion, etc?<br>
      <br>
      In conclusion, leaving things to the optimiser that could be
      trivially made fast every time seems needlessly risky.<br>
      <br>
      Cheers!<br>
    </p>
    <div class="moz-cite-prefix">On 18/10/2020 20:46, Vanessa McHale
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:390dbc99-abdc-2b00-366d-50cb4291380f@gmail.com">
      <pre class="moz-quote-pre" wrap="">For my own edification, what happens in actual code? i.e. not GHCi

Cheers,
Vanessa McHale

On 10/18/20 1:13 PM, Hécate wrote:
</pre>
      <blockquote type="cite">
        <pre class="moz-quote-pre" wrap="">My fellow Haskell developers, contributors and maintainers,

I wish to present what is certainly a controversial proposal for the
`base` library:
   Making the `sum` and `product` functions from the `base` library
strict.

This is not a new question, the debate is old, but I am personally
convinced that the existence of those two lazy functions is something
that should never have happened.
One of the first goals that led to the creation of Haskell was to
enable collaboration and research in the domain of lazy (or
non-strict) programming languages and techniques.
While it led to the discovery of new methods and ways to represent
programs, we also realised that this paradigm has proven to produce
sub-optimal implementations for
these functions.

And while maintaining backward compatibility *is* important when
designing and maintaining a programming language, we have thankfully
developed deprecation mechanisms
that can be used to signal that bad, or sub-optimal decisions of the
past can be corrected.

To refresh our collective memory, here is the current state of things,
regarding `sum`:

```
❯ ghci +RTS -M1024m
GHCi, version 8.10.1: <a class="moz-txt-link-freetext" href="https://www.haskell.org/ghc/">https://www.haskell.org/ghc/</a>  :? for help
λ❯ sum [1..10^9]
*** Exception: heap overflow
```
Whereas, with an alternative implementation, such as `foldl'`:
```
λ❯ foldl' (+) 0 [1..10^9]
500000000500000000
(31.35 secs, 88,000,076,288 bytes)
```

I do not think a heap overflow, and the underlying space leak
occasioned by the laziness of `foldl`, are behaviours we should aim to
preserve for the sake of backward compatibility.

And actually, I think that moving these two functions to a strict,
space leak-free implementation would benefit the lazy PL research
domain by showing a good counter-example
of why it is not necessarily suitable for every kind of computation.
I also think, and this is rooted from experience, that we must strive
to empower our users with the power of laziness. Not burden them with it.
Standing on the shoulders of giants is what made Haskell so great, but
this should not prevent us from spreading our wings to go higher.

———

Now, there have been Prelude replacements (such as Relude) and
companion libraries (like `strict`) who have been shipping such
alternative implementations for quite some time now.

A point that can be raised is: Why should we bother? Isn't `strict`
already enough?
To this I answer: `strict` and Relude, ultimately, patches on an
tire's inner tube. We may be able to roll with them for some distance,
but their very existence is a response to an abnormal situation that
we have grown to accept.
However, any bicycle rider who has the means to change their tire
should do so.
I believe we have the means to do so.

Another point that could be raised as well is the fact that this
implementation change would deviate from the 2010 Haskell Report[0].
If we want to stay true to the spirit and letter of the Report, this
is actually a non-issue. Indeed, it is noted that:

</pre>
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap="">This  report  defines  the  syntax  for Haskell  programs and  an 
</pre>
        </blockquote>
        <pre class="moz-quote-pre" wrap="">informal  abstract  semantics  for  the  meaning of such programs.  We
leave as implementation dependent the ways in which Haskell programs
are to be manipulated, interpreted, compiled, etc. This includes such
issues as the nature of programming environments and the error
messages returned for undefined programs (i.e. programs that formally
evaluate to⊥).[1]

As well as in chapter 9:

</pre>
        <blockquote type="cite">
          <pre class="moz-quote-pre" wrap="">In this chapter the entire Haskell Prelude is given. It constitutes a 
</pre>
        </blockquote>
        <pre class="moz-quote-pre" wrap="">specification for the Prelude. Many of the definitions are written
with clarity rather than efficiency in mind, and it is not required
that the specification be implemented as shown here.[2]

And finally, regarding the non-strict nature of Haskell, the Report
references strict evaluation to avoid "unneeded laziness."[3]
Thus it was expected that laziness would not be a silver bullet, and
it could harm performance.

———

Regarding the implementation detail, `sum` and `product` would
piggy-back on the already-present `foldMap'` function.


Thank you very much for reading,
I believe we can all go together towards improving the experience of
Haskell developers, starting with this.

[0]: Haskell 2010 Language Report,
<a class="moz-txt-link-freetext" href="https://www.haskell.org/definition/haskell2010.pdf">https://www.haskell.org/definition/haskell2010.pdf</a>
[1]: Haskell 2010 Language Report, page 3
[2]: Haskell 2010 Language Report, Chapter 9 Standard Prelude, page 105
[3]: Haskell 2010 Language Report, Section 6.2 Strict Evaluation, page 75

</pre>
      </blockquote>
      <pre class="moz-quote-pre" wrap="">
</pre>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <pre class="moz-quote-pre" wrap="">_______________________________________________
Libraries mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Libraries@haskell.org">Libraries@haskell.org</a>
<a class="moz-txt-link-freetext" href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a>
</pre>
    </blockquote>
    <pre class="moz-signature" cols="72">-- 
Hécate ✨
IRC: Uniaika
WWW: <a class="moz-txt-link-freetext" href="https://glitchbra.in">https://glitchbra.in</a>
RUN: BSD</pre>
  </body>
</html>