caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Mututal Recursion and Tail Recursion
@ 2005-07-13 19:03 Jonathan Bryant
  2005-07-15  6:40 ` [Caml-list] " Jean-Christophe Filliatre
  0 siblings, 1 reply; 4+ messages in thread
From: Jonathan Bryant @ 2005-07-13 19:03 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 948 bytes --]

Is is possible to have mutually recursive functions that are also tail
recursive?  For example, attached is some code I wrote to flatten a list
of lists using mutually recursive functions.  I've tried this with large
lists (5,000,000+) and have not encountered a stack overflow, but that
does not necessarily mean that tail recursion is happening.

Also, I know that there are ZAM opcodes that indicate a tail recursive
function (TAILCALL, if I am not mistaken) and one or two of the
undocumented compiler options will dump the opcodes.  Could someone
briefly explain what each of those options do so I wouldn't have to take
up everybody's time asking if this is tail recursive?

--Jonathan

-- 
*=========================*
|Jonathan Bryant          |
|Valdosta State University|
|Information Technology   |
|System Operations        |
|-------------------------|
|jtbryant@valdosta.edu    |
|x6358                    |
*=========================*

[-- Attachment #2: list_aux.ml --]
[-- Type: text/plain, Size: 2643 bytes --]

let print l = 
    let rec aux l1 = match l1 with
          []    -> Printf.printf "[]";
        | h::[] -> Printf.printf "%d]" h
        | h::t  -> Printf.printf "%d; " h; aux t in
    Printf.printf "[";
    aux l;;

let print_ll ll =
    let rec aux l1 = match l1 with
          [] -> Printf.printf "[]";
        | h::[] -> print h; Printf.printf "]"
        | h::t -> print h; Printf.printf "; "; aux t in
    Printf.printf "[";
    aux ll;;

let flatten ll =
    let rec flat_out ol oa = match ol with
          []   -> oa
        | h::t -> flat_in h t oa
    and flat_in il ot ia = match il with
          []   -> flat_out ot ia
        | h::t -> flat_in t ot (h::ia) in
    List.rev (flat_out ll []);;

let interpolate l1 l2 =
    let rec inter x y a = match x,y with
          [],[]         -> a
        | [],h::t       -> inter t x (h::a)
        | h::t,[]       -> inter t y (h::a)
        | h1::t1,h2::t2 -> inter y t1 (h1::a) in
    List.rev (inter l1 l2 []);;

let range x m s =
    let rec aux c a = if c > m then a else aux (c + s) (c :: a) in
    List.rev (aux x []);;

let range_ll min max step division =
    let l = range min max step in
    let rec aux1 l1 a1 = match l1 with
          []   -> (List.rev a1)
        | h::t -> aux2 l1 0 [] a1
    and aux2 l2 len a2 a1 =
        if len < division
        then match l2 with
              []   -> aux2 [] division a2 a1
            | h::t -> aux2 t (len + 1) (h::a2) a1
        else aux1 l2 ((List.rev a2)::a1)
    in aux1 l [];;

let _ =
    let min = 1 and max = 5000000 in
    Printf.printf "Generating lists"; flush stdout;
    Printf.printf "."; flush stdout;
    let my_list = range min max 2 in
    Printf.printf "."; flush stdout;
    let my_other_list = range (min + 1) max 2 in
    Printf.printf "."; flush stdout;
    let my_list_list = range_ll min max 1 1 in
    Printf.printf "\n"; flush stdout;
    Printf.printf "\nMy List: "; flush stdout;
    (* print my_list; *)
    Printf.printf "\nMy Other List: "; flush stdout;
    (* print my_other_list; *)
    Printf.printf "\nMy List and My Other List Interpolated: "; flush stdout;
    (* print (interpolate my_list my_other_list); *)
    Printf.printf "\nMy List List: "; flush stdout;
    (* print_ll my_list_list; *)
    Printf.printf "\nMy List List Flattened: "; flush stdout;
    (* print (flatten my_list_list); *)
    Printf.printf "\n\n"; flush stdout;
    if (interpolate my_list my_other_list) = (flatten my_list_list)
    then (
        Printf.printf "The interpolated and flattened lists are equal!\n";
        flush stdout
    ) else (
        Printf.printf "Hmmm...\n";
        flush stdout
    );;

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-07-18  0:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-07-13 19:03 Mututal Recursion and Tail Recursion Jonathan Bryant
2005-07-15  6:40 ` [Caml-list] " Jean-Christophe Filliatre
2005-07-15 12:15   ` Jonathan Bryant
2005-07-18  0:56     ` Jacques Garrigue

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).