<div dir="ltr"><div><div>Hi dev,<br><br></div>I'm trying to get this benchmark running: <a href="https://raw.githubusercontent.com/MLton/mlton/master/benchmark/tests/tailfib.sml" target="_blank">https://raw.githubusercontent.<wbr>com/MLton/mlton/master/<wbr>benchmark/tests/tailfib.sml</a> on a recent build of the bootstrapped compiler<br><br>I ran into this strange scenario:<br><br>Writing the loop like the following makes CakeML run out of stack (I think it fails to optimize the tail call because increasing the stack limit manually works):<br><br>val doit =<br>  fn n =><br>  let<br>    fun loop n =<br>      if n = 0<br>        then ()<br>        else (doit();loop(n-1))<br>  in loop (n * 1000000)<br>  end;<br><br></div><div>On the other hand, making the ; explicit:<br><br>val doit =<br>  fn n =><br>  let<br>    fun loop n =<br>      if n = 0<br>        then ()<br>        else <b>(let val foo = doit() in loop(n-1) end)<br></b>  in loop (n * 1000000)<br>  end;g<br><br></div><div>works fine.<br><br></div><div>I checked out the compilation down to patLang, and the only difference between the two is that the first is compiled to a Seq while the second is compiled to a Let.<br><br></div><div>There are actually two things of interest:<br><br></div><div>1) The ground check in exh_to_pat incorrectly says that  <b>(let val foo = doit() in loop(n-1) end) </b>is not ground, and does not compile it to doit() ; loop (n-1)<br><br></div><div>2) pat_to_clos compiles Seqs to Let [compile e1;compile e2] (Var 1) while the Lets go to Let [compile e1] (compile e2)<br><br></div><div>I think the issue is that the tail call detector cannot / does not detect the first tail call shape.<br></div><div><br></div><div>I'm not sure what the best fix is here, is the multiple-argument Let compilation of Seq important? If so, I guess the tail call detector in bvi_to_data should be updated to detect those shapes too.<br></div></div>