<br><br><div class="gmail_quote">On Fri, Apr 16, 2010 at 8:35 PM, C K Kashyap <span dir="ltr">&lt;<a href="mailto:ckkashyap@gmail.com">ckkashyap@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
I am a little surprised by the &quot;shortcomings&quot; of Haskell mentioned in the thread.<div><br></div><div>I was under the impression that Haskell was closest to Nirvana on the usefulness vs safety graph.</div><div><br>

</div><div>In the paper &quot;Why FP matters&quot; - Laziness is stated as one of the two key features of FP that allows conceptual modularity! If I understand right, Laziness is not a first class stuff in OCaml - is that not right?</div>
</blockquote><div><br></div><div>That&#39;s right.  You can simulate laziness in OCaml.  OCaml compilers cannot assume code is pure and lazy so many very useful optimizations are not performed by the OCaml compiler.  And some syntactic and stylist things are not available.  See for example Ganesh&#39;s comment about combinators earlier in this thread.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><br></div><div>If I understand correctly - Not allowing side-effects allow for equational reasoning - which in turn allows you to &quot;reason&quot; about the program better. If I understand right - OCaml allows side effects right?</div>
</blockquote><div><br></div><div>Right.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><br></div><div>Jeff, could you please expand on the tail recursion bit - what do you mean when you say, in OCaml, &quot;one has to write tail recursively in OCaml&quot;?</div></blockquote><div><br></div><div>Tail recursive functions do not need to maintain a stack for their recursive calls and the optimizer may replace them with a loop.  In strict functional languages such as OCaml this means that by writing your recursive functions to be tail recursive you won&#39;t run out of stack space.  Many recursive functions can be transformed to be tail recursive by adding an accumulator argument and building up the return value there.</div>
<div><br></div><div>In a lazy language if you write something to be tail recursive, then each time the function recurses it will add to the accumulator.  Because it&#39;s tail recursive it typically also won&#39;t evaluate this accumulator.  This means that in memory you have to build up the unevaluated representation, or thunk.  This thunk keeps getting bigger and bigger until something demands the value.  This means that if you need to write a recursive function in haskell which has an accumulator, you often want to make the function strict in the accumulator.  Meaning the strict function will evaluate the accumulator as it goes.</div>
<div><br></div><div>One place where lazy accumulators is bad are the left folds.  There is the lazy foldl and the version which is strict in the accumulator, foldl&#39;.  Try summing big lists of integers, let&#39;s use ghci and limit the heap to 1 meg:</div>
<div><br></div><div>ghci +RTS -M1M</div><div>Prelude&gt; foldl (+) 0 [1..10000000]</div><div>Heap exhausted;</div><div>Current maximum heap size is 6291456 bytes (6 MB);</div><div>use `+RTS -M&lt;size&gt;&#39; to increase it.</div>
<div><br></div><div>ghci +RTS -M1M</div><div>Prelude&gt; :m + Data.List</div><div>Prelude Data.List&gt; foldl&#39; (+) 0 [1..10000000]</div><div>50000005000000</div><div><br></div><div>Haskell lets us choose the evaluation strategy here.  After programming in both Haskell and Common Lisp for several years each I can tell you that Haskell&#39;s way of dealing with evaluation strategies and letting the user pick the desired one is easier to manage and deal with.  I would expect OCaml less nice than Haskell here as well.</div>
<div><br></div><div>Jason</div><div><br></div><div><br></div></div>