<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
p.Code, li.Code, div.Code
{mso-style-name:Code;
mso-style-link:"Code Char";
margin-top:0cm;
margin-right:0cm;
margin-bottom:0cm;
margin-left:36.0pt;
margin-bottom:.0001pt;
font-size:12.0pt;
font-family:"Courier New";}
span.CodeChar
{mso-style-name:"Code Char";
mso-style-link:Code;
font-family:"Courier New";}
span.EmailStyle19
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri",sans-serif;
mso-fareast-language:EN-US;}
.MsoPapDefault
{mso-style-type:export-only;
margin-top:6.0pt;
margin-right:0cm;
margin-bottom:6.0pt;
margin-left:0cm;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
/* List Definitions */
@list l0
{mso-list-id:579487055;
mso-list-template-ids:1223966546;}
@list l0:level1
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:36.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level2
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:72.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level3
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:108.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level4
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:144.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level5
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:180.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level6
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:216.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level7
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:252.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level8
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:288.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l0:level9
{mso-level-number-format:bullet;
mso-level-text:;
mso-level-tab-stop:324.0pt;
mso-level-number-position:left;
text-indent:-18.0pt;
mso-ansi-font-size:10.0pt;
font-family:Symbol;}
@list l1
{mso-list-id:1597592907;
mso-list-template-ids:-464634030;}
ol
{margin-bottom:0cm;}
ul
{margin-bottom:0cm;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-GB" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">Ryan<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">Yes, I’m sure there is room for improvement here! Good observations.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">In particular, while I’d like DATA to support this, I believe that most ‘eval’s find that the thing being evaluated is already evaluated; so the fast-path should
be that case. We should bet for evaluated.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">NB, however, that the stack-overflow check applies to the entire function body. Suppose we do<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"> f x = case x of (p,q) -> case p of True -> False; False -> True<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">Then we can eliminate the stack check only if
<b>both</b> the eval of ‘x’ <b>and</b> the eval of ‘p’ both take the fast path.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">Another avenue you might like to think about is this: if function f calls g, then g’s stack-overflow test could perhaps be absorbed into ‘f’s. So<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"> f x = case (g x) of True -> False; False -> True<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">So maybe f could call a super-fast entry point for g that didn’t have a stack overflow test!<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">(Watch out: loops, recursion, etc)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">I’m happy to advise.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US">Simon<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Calibri",sans-serif;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Ryan Newton [mailto:rrnewton@gmail.com]
<br>
<b>Sent:</b> 23 October 2015 19:31<br>
<b>To:</b> Simon Peyton Jones<br>
<b>Cc:</b> ghc-devs@haskell.org; Ömer Sinan Ağacan; Ryan Scott; Chao-Hong Chen; Johan Tibell<br>
<b>Subject:</b> Re: Better calling conventions for strict functions (bang patterns)?<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
Ah, yes, so just to give a concrete example in this thread, if we take the `foo` function above and say `map foo ls`, we may well get unevaluated arguments to foo. (And this is almost precisely the same as the first example that Strict-Core paper!)<o:p></o:p></p>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
<o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:6.0pt;margin-right:0cm;margin-bottom:6.0pt;margin-left:0cm">
Thanks for the paper reference. I read it and it's great -- just what I was looking for. An approach that eliminates any jealousy of ML/Scheme compiler techniques vis a vis calling conventions ;-). I'm also wondering if there are some incremental steps that
can be taken, short of what is proposed in the paper.<o:p></o:p></p>
</div>
<div>
<ol start="1" type="1">
<li class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:12.0pt;mso-list:l1 level1 lfo1">
Small tweaks: The CMM code above seems to be <i>betting</i> than the thunk is unevaluated, because it does the stack check and stack write <i>before</i> the predicate test that checks if the thunk is evaluated (<span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">if</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">
(R1 & </span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">7</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> !=
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">0</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">)
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">goto</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3aO;
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">else</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">goto</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3aP;</span>). With a bang-pattern function, couldn't it make the opposite bet? That is, branch on whether
the thunk is evaluated first, and then the wasted computation is only a single correctly predicted branch (and a read of a tag that we need to read anyway). <o:p></o:p></li><li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;mso-list:l1 level1 lfo1">
The option of multiple entrypoints which is considered and discarded as fragile in the beginning of the paper (for direct call vs indirect / 1st order vs higher order). That fragile option is along the lines of what I wanted to discuss on this thread. It
does seem like a tricky phase ordering concern, but how bad is it exactly? The conflict with the a case-expr rewrite is illustrated clearly in the paper, but that just means that such optimizations must happen
<i>before </i>the final choice of which function entrypoint to call, doesn't it? I'm not 100% sure where it could go in the current compiler pipeline, but couldn't the adjustment of call target from "foo" to "foo_with_known_whnf_args" happen quite late? <o:p></o:p></li></ol>
</div>
<div>
<p class="MsoNormal">Cheers,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> -Ryan<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">P.S. One of the students CC'd, Ryan Scott, is currently on internship at Intel labs and is working to (hopefully) liberate the Intell Haskell Research Compiler as open source. Like the 2009 paper, it also uses a strict IR, and I think
it will be interesting to see exactly how it handles the conversion from Core to its IR. (Probably the same as Fig 10 in the paper.)<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">On Fri, Oct 23, 2015 at 10:11 AM, Simon Peyton Jones <<a href="mailto:simonpj@microsoft.com" target="_blank">simonpj@microsoft.com</a>> wrote:<o:p></o:p></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-family:"Calibri",sans-serif">It’s absolutely the case that bang patterns etc tell the caller what to do, but the function CANNOT ASSUME that its argument is evaluated.
Reason: higher order functions.</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-family:"Calibri",sans-serif"> </span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-family:"Calibri",sans-serif">I think that the way to allow functions that can assume their arg is evaluated is through types: see
<a href="https://na01.safelinks.protection.outlook.com/?url=http:%2f%2fresearch.microsoft.com%2f~simonpj%2fpapers%2fstrict-core%2ftacc-hs09.pdf&data=01%7C01%7Csimonpj%40064d.mgd.microsoft.com%7C6c26443b080f47ded44d08d2dbd82785%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=apsJhmnvf2Y0M2KhNcmPzg%2bqkd5zYl2MmDYvOcCObJA%3d" target="_blank">
Type are calling conventions</a>. But it’d be a fairly big deal to implement.</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-family:"Calibri",sans-serif"> </span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-family:"Calibri",sans-serif">Simon</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-family:"Calibri",sans-serif"> </span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><span style="font-family:"Calibri",sans-serif">
</span><o:p></o:p></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span lang="EN-US" style="font-size:11.0pt;font-family:"Calibri",sans-serif"> ghc-devs
[mailto:<a href="mailto:ghc-devs-bounces@haskell.org" target="_blank">ghc-devs-bounces@haskell.org</a>]
<b>On Behalf Of </b>Ryan Newton<br>
<b>Sent:</b> 23 October 2015 14:54<br>
<b>To:</b> <a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a>; Ömer Sinan Ağacan; Ryan Scott; Chao-Hong Chen; Johan Tibell<br>
<b>Subject:</b> Better calling conventions for strict functions (bang patterns)?</span><o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt">Hi all,<o:p></o:p></p>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt">With module-level Strict and StrictData pragmas coming soon, one obvious question is what kind of the code quality GHC can achieve for strict programs.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt">When it came up in discussion in our research group we realized we didn't actually know whether the bang patterns, `f !x`, on function arguments were enforced by caller or callee.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt">Here's a Gist that shows the compilation of a trivial function:<o:p></o:p></p>
</div>
<div>
<table class="MsoNormalTable" border="0" cellspacing="0" cellpadding="0" style="border-collapse:collapse;border-spacing:0px">
<tbody>
<tr>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#795DA3">foo</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">::</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">Maybe</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">Int</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">-></span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">Int</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333">foo !x =</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> </span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">case</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> x
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">of</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> </span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">Just</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> y -> y</span><o:p></o:p></p>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt"> <a href="https://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2fgist.github.com%2frrnewton%2f1ac722189c65f26fe9ac&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7cb006dcdbfe834ebb6c1e08d2dbb16c03%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=qxrT8r1VSP97xQUF2qqkLlxEtSGi9VOzfmORl25W%2fWY%3d" target="_blank">https://gist.github.com/rrnewton/1ac722189c65f26fe9ac</a><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt">If that function is compiled to *assume* its input is in WHNF, it should be just as efficient as the isomorphic MLton/OCaml code, right? It only needs to branch on the tag, do a field
dereference, and return.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt">But as you can see from the STG and CMM generated, foo
<i>does indeed</i> enter the thunk, adding an extra indirect jump. Here's the body:<o:p></o:p></p>
</div>
<div>
<table class="MsoNormalTable" border="0" cellspacing="0" cellpadding="0" style="border-collapse:collapse;border-spacing:0px">
<tbody>
<tr>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3aY:</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> </span>
<span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">if</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> ((Sp + -</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">)
< SpLim) </span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">goto</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3aZ;
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">else</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">goto</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3b0;</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3aZ:</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> </span>
<span style="font-size:9.0pt;font-family:Consolas;color:#969896">// nop</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> R1 = PicBaseReg + foo_closure;</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> </span>
<span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">call</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> (I64[BaseReg -
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">])(R2, R1) args:
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">, res:
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">0</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">, upd:
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">;</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3b0:</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> I64[Sp -
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">] = PicBaseReg + block_c3aO_info;</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> R1 = R2;</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> Sp = Sp -
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">;</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> </span>
<span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">if</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> (R1 &
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">7</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> !=
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">0</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">)
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">goto</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3aO;
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">else</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">goto</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3aP;</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3aP:</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> </span>
<span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">call</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> (I64[R1])(R1) returns to c3aO, args:
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">, res:
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">, upd:
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">;</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3aO:</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> </span>
<span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">if</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> (R1 &
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">7</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> >=
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">2</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">)
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">goto</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3aW;
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">else</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">
</span><span style="font-size:9.0pt;font-family:Consolas;color:#A71D5D">goto</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3aX;</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3aW:</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> R1 = P64[R1 +
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">6</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">] & (-</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">);</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> Sp = Sp +
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">;</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> </span>
<span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">call</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> (I64[R1])(R1) args:
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">, res:
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">0</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">, upd:
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">;</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> c3aX:</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> R1 = PicBaseReg + lvl_r39S_closure;</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> Sp = Sp +
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">;</span><o:p></o:p></p>
</td>
</tr>
<tr>
<td width="50" nowrap="" valign="top" style="width:37.5pt;border:solid #EEEEEE 1.0pt;border-top:none;padding:0cm 7.5pt 0cm 7.5pt;min-width:50px;color:rgba(0,0,0,0.298039)">
</td>
<td valign="top" style="padding:0cm 7.5pt 0cm 7.5pt;word-wrap:normal;overflow:visible">
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt;line-height:13.65pt">
<span style="font-size:9.0pt;font-family:Consolas;color:#333333"> </span>
<span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">call</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333"> (I64[R1])(R1) args:
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">, res:
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">0</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">, upd:
</span><span style="font-size:9.0pt;font-family:Consolas;color:#0086B3">8</span><span style="font-size:9.0pt;font-family:Consolas;color:#333333">;</span><o:p></o:p></p>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt">The call inside c3aP is entering "x" as a thunk, which also incurs all of the stack limit check code. I believe that IF the input could be assumed to be in WHNF, everything above the
label "c3aO" could be omitted.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;margin-bottom:6.0pt">So... if GHC is going to be a fabulous pure
<i>and</i> imperative language, and a fabulous lazy <i>and</i> strict compiler/runtime.. is there some work we can do here to improve this situation? Would the following make sense:<o:p></o:p></p>
</div>
<div>
<ul type="disc">
<li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;mso-list:l0 level1 lfo2">
Put together a benchmark suite of all-strict programs with Strict/StrictData (compare a few benchmark's generated code to MLton, if time allows)<o:p></o:p></li><li class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;mso-list:l0 level1 lfo2">
Modify GHC to change calling conventions for bang patterns -- caller enforces WHNF rather than callee. Existing strictness/demand/cardinality analysis would stay the same.<o:p></o:p></li></ul>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Unless there's something I'm really missing here, the result should be that you can have a whole chain of strict function calls, each of which knows its arguments and the arguments
it passes to its callees are all in WHNF, without ever generating thunk-entry sequences.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Thanks for your time,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> -Ryan<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
</div>
</body>
</html>