<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE message PUBLIC
  "-//MLarc//DTD MLarc output files//EN"
  "../../mlarc.dtd"[
  <!ATTLIST message
    listname CDATA #REQUIRED
    title CDATA #REQUIRED
  >
]>

  <?xml-stylesheet href="../../mlarc.xsl" type="text/xsl"?>


<message 
  url="2003/11/74fd6d12b051517ef4b87994851705ad"
  from="Brian Hurt &lt;bhurt@s...&gt;"
  author="Brian Hurt"
  date="2003-11-19T05:52:29"
  subject="Re: [Caml-list] tail call optimization"
  prev="2003/11/1f551b7bf53f76d0b573b176d6687798"
  next="2003/11/76bfb2b8df6616335e079e0acbffab67"
  prev-in-thread="2003/11/1f551b7bf53f76d0b573b176d6687798"
  next-in-thread="2003/11/cfdde01e96dd3fcc2e53c6be05b8a419"
  prev-thread="2003/11/f112840855ba7fadd40cd35228f1ee0a"
  next-thread="2003/11/222e3da9e074f94c1e735e19b5df6c54"
  root="../../"
  period="month"
  listname="caml-list"
  title="Archives of the Caml mailing list">

<thread subject="[Caml-list] tail call optimization">
<msg 
  url="2003/11/1f551b7bf53f76d0b573b176d6687798"
  from="Dustin Sallings &lt;dustin@s...&gt;"
  author="Dustin Sallings"
  date="2003-11-19T05:24:17"
  subject="[Caml-list] tail call optimization">
<msg 
  url="2003/11/74fd6d12b051517ef4b87994851705ad"
  from="Brian Hurt &lt;bhurt@s...&gt;"
  author="Brian Hurt"
  date="2003-11-19T05:52:29"
  subject="Re: [Caml-list] tail call optimization">
<msg 
  url="2003/11/cfdde01e96dd3fcc2e53c6be05b8a419"
  from="Dustin Sallings &lt;dustin@s...&gt;"
  author="Dustin Sallings"
  date="2003-11-19T06:24:25"
  subject="Re: [Caml-list] tail call optimization">
<msg 
  url="2003/11/27534b11b64fdea5311fde54c963c9c3"
  from="Frederic van der Plancke &lt;fvdp@d...&gt;"
  author="Frederic van der Plancke"
  date="2003-11-19T11:38:54"
  subject="Re: [Caml-list] tail call optimization">
</msg>
<msg 
  url="2003/11/030cefc60478232c72d1ae302af3e813"
  from="Brian Hurt &lt;bhurt@s...&gt;"
  author="Brian Hurt"
  date="2003-11-19T16:24:34"
  subject="Re: [Caml-list] tail call optimization">
<msg 
  url="2003/11/b3024c61f50d75b522f680a905aa2286"
  from="Dustin Sallings &lt;dustin@s...&gt;"
  author="Dustin Sallings"
  date="2003-11-19T17:46:34"
  subject="Re: [Caml-list] tail call optimization">
</msg>
</msg>
</msg>
</msg>
<msg 
  url="2003/11/76bfb2b8df6616335e079e0acbffab67"
  from="Dustin Sallings &lt;dustin@s...&gt;"
  author="Dustin Sallings"
  date="2003-11-19T06:09:01"
  subject="Re: [Caml-list] tail call optimization">
</msg>
</msg>
</thread>

<contents>
On Tue, 18 Nov 2003, Dustin Sallings wrote:

&gt; 
&gt; 	I read something on the list about how a function may be tail 
&gt; recursive, but not be compiled with tail call optimization.  What kinds 
&gt; of things might cause this?
&gt; 
&gt; 	Specifically, I've got an ``iter_lines'' function I'd like to turn 
&gt; into a ``fold_lines'' function that looks something like this (a few 
&gt; different functions for different things):
&gt; 
&gt; let rec fold_lines f init_value ch =
&gt;      try
&gt;          let v = f (input_line ch) init_value in
&gt;          fold_lines f v ch
&gt;      with End_of_file -&gt; init_value;
&gt; ;;

This function is not tail recursive.  Basically, if the recursive call 
either a) is wrapped in a try block, or b) has it's return value modified 
in any way, the function isn't tail recursive.  Your function violates 
clause a, the following function violates clause b:

let append a b =
	match a with
		| [] -&gt; b
		| h :: t -&gt; h :: (append t b)
;;

Since we're appending h to the return value of the recursive call, it 
isn't tail recursive.

I recommend coding the your function like:

let rec fold_lines f init_value ch =
	let line, eof = try (input_line ch), false
			with End_of_file -&gt; "", true
	in
	if eof then
		init_value
	else
		fold_lines f (f line init_value) ch
;;

Now that the recursive call is outside the try block, and you aren't 
modifying the return value, so all is good.
 
&gt; dustinti:~/prog/eprojects/snippets/ocaml/lib 586% wc -l numbers
&gt;   4769526 numbers
&gt; # Fileutils.fold_file_lines (fun x y -&gt; y + 1) 0 "numbers";;
&gt; Stack overflow during evaluation (looping recursion?).

Stack overflows are a classic sign of a function you thought was tail 
recursive not being tail recursive.

-- 
"Usenet is like a herd of performing elephants with diarrhea -- massive,
difficult to redirect, awe-inspiring, entertaining, and a source of
mind-boggling amounts of excrement when you least expect it."
                                - Gene Spafford 
Brian

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners

</contents>

</message>

