<?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/01/4a9754e53ff07723caf21b4496d1d267"
  from="Brian Hurt &lt;brian.hurt@q...&gt;"
  author="Brian Hurt"
  date="2003-01-24T01:14:50"
  subject="[Caml-list] @, List.append, and tail recursion"
  prev="2003/01/be461c4ff942cdbf26f01b18b78f15db"
  next="2003/01/9fc87d4341639803357cc36b0fe95ba9"
  next-in-thread="2003/01/899bda8a77b5c4c96e73e91b5cca074b"
  prev-thread="2003/01/0e9c2bc35f3c3fbbe7e967dccafbddfc"
  next-thread="2003/01/d579dc7183e18352238ff4a8f4a069ee"
  root="../../"
  period="month"
  listname="caml-list"
  title="Archives of the Caml mailing list">

<thread subject="[Caml-list] @, List.append, and tail recursion">
<msg 
  url="2003/01/4a9754e53ff07723caf21b4496d1d267"
  from="Brian Hurt &lt;brian.hurt@q...&gt;"
  author="Brian Hurt"
  date="2003-01-24T01:14:50"
  subject="[Caml-list] @, List.append, and tail recursion">
<msg 
  url="2003/01/899bda8a77b5c4c96e73e91b5cca074b"
  from="Olivier Andrieu &lt;andrieu@i...&gt;"
  author="Olivier Andrieu"
  date="2003-01-30T18:10:32"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
<msg 
  url="2003/01/fab35b022410822cb86a9793044747e0"
  from="Brian Hurt &lt;brian.hurt@q...&gt;"
  author="Brian Hurt"
  date="2003-01-30T19:37:04"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
<msg 
  url="2003/01/84b55a0c74cfad2033538b3b7b54c310"
  from="Olivier Andrieu &lt;oandrieu@n...&gt;"
  author="Olivier Andrieu"
  date="2003-01-31T09:40:48"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
<msg 
  url="2003/01/2431333c3c6b36d46b3e0780dfccb921"
  from="Brian Hurt &lt;brian.hurt@q...&gt;"
  author="Brian Hurt"
  date="2003-01-30T21:48:04"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
<msg 
  url="2003/01/9676deab43bb44cb174c80433348dec3"
  from="james woodyatt &lt;jhw@w...&gt;"
  author="james woodyatt"
  date="2003-01-31T02:18:43"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
<msg 
  url="2003/01/a9673766c5e0333ea0c657cce6e6a1c6"
  from="Brian Hurt &lt;brian.hurt@q...&gt;"
  author="Brian Hurt"
  date="2003-01-31T17:04:15"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
<msg 
  url="2003/01/f09c1cd83ec921dc87b5dc72261e2890"
  from="Issac Trotts &lt;ijtrotts@u...&gt;"
  author="Issac Trotts"
  date="2003-01-31T23:07:46"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
</msg>
<msg 
  url="2003/01/43d4021b732340168a7aa2d608ef4e32"
  from="brogoff@s..."
  author="brogoff@s..."
  date="2003-01-31T17:42:54"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
</msg>
<msg 
  url="2003/01/879004760584f7faab4a520558ec76fd"
  from="Russ Ross &lt;caml@r...&gt;"
  author="Russ Ross"
  date="2003-01-31T19:18:57"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
<msg 
  url="2003/02/e6489db58afc9a883258a73c728cb74c"
  from="brogoff@s..."
  author="brogoff@s..."
  date="2003-02-01T02:30:58"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
</msg>
<msg 
  url="2003/01/e8ff6f38a8931153eb164322e7095221"
  from="Alexander V. Voinov &lt;avv@q...&gt;"
  author="Alexander V. Voinov"
  date="2003-01-31T19:39:44"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
</msg>
</msg>
</msg>
<msg 
  url="2003/01/1c9ca4f143a0ace6056cb77ebfb173e0"
  from="Diego Olivier Fernandez Pons &lt;Diego-Olivier.FERNANDEZ-PONS@c...&gt;"
  author="Diego Olivier Fernandez Pons"
  date="2003-01-31T17:06:41"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
<msg 
  url="2003/01/5cfa2d91424bf433790e9d4c7ffeb3d6"
  from="Brian Hurt &lt;brian.hurt@q...&gt;"
  author="Brian Hurt"
  date="2003-01-31T19:43:14"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
<msg 
  url="2003/02/fe0747cbf160b030a7c262d2d3175a0e"
  from="Diego Olivier Fernandez Pons &lt;Diego-Olivier.FERNANDEZ-PONS@c...&gt;"
  author="Diego Olivier Fernandez Pons"
  date="2003-02-01T10:19:59"
  subject="Linear systems (was Re: [Caml-list] @, List.append, and tail recursion)">
</msg>
</msg>
<msg 
  url="2003/01/bc5c8643c380f6aab1a0509ce17e2872"
  from="Issac Trotts &lt;ijtrotts@u...&gt;"
  author="Issac Trotts"
  date="2003-01-31T21:30:38"
  subject="Re: [Caml-list] @, List.append, and tail recursion">
</msg>
</msg>
</msg>
</msg>
</msg>
</msg>
</msg>
</msg>
</thread>

<contents>

I hit a bug recently wiith @ and List.append.  Since they're recursive, 
not tail-recursive, on long enough lists Ocaml thinks you've gone 
infinitely recursive and aborts.  The code:


let longlist len =
    let rec longlist_int v c acc =
        if (c == 0) then acc else longlist_int (v + 1) (c - 1) (v :: acc)
    in
    longlist_int 0 len []
;;

let x = longlist 65536 ;;

List.append x [] ;;

Exits with:

Stack overflow during evaluation (looping recursion?).

So does:
x @ [] ;;

You can work around this like:

let append' a b =
   List.rev_append (List.rev a) b
;;

Since both rev_append and rev are tail recursive (looping) and not 
recursive, this works.  But some ad-hoc testing says that this method is 
about 50% slower than normal append for lists short enough not to abort.

Thinking about this, I realized that my code is doing stuff like this all
over the place.  I'm basically doing sparse vector/matrix stuff, handling
(effectively) (colno * value) list for vectors, and (rowno * vector) list
for matrix.  And I may be hitting lists long enough to trip the problem.

Which means I'm currently doing a lot of recursion of the form:

let rec foo x = 
   match x with
       [] -&gt; []
       | head :: tail -&gt; (expr head) :: (foo tail)
;;

for various complexities.  And it has occured to me that all of these 
forms *should* be optimizable into loops.  The general case would work 
something like this in C:

struct list_t {
    void * datum;
    struct list_t * next_p;
}

struct list_t * foo (struct list_t * x) {
    struct list_t * retval = NULL;
    struct list_t ** ptr_pp = &amp;retval;

    while (x != NULL) {
        struct list_t * temp = alloc(sizeof(struct list_t));
        *ptr_pp = temp;
        temp-&gt;datum = expr(x-&gt;datum);
        temp-&gt;next_p = NULL; /* be nice to the GC */
        ptr_pp = &amp;(temp-&gt;next_p);
        x = x-&gt;next_p;
    }
    return retval;
}

If expr() returned a list, the only change necessary would be to find the 
end of the list before moving on, like:

struct list_t * foo (struct list_t * x) {
    struct list_t * retval = NULL;
    struct list_t ** ptr_pp = &amp;retval;

    while (x != NULL) {
        *ptr_p = expr(x-&gt;datum); /* expr allocates the list */
        /* We assume the last element of the list expr() returned has
         * NULL for next_p.
         */
        while (*ptr_p != NULL) {
           ptr_p = &amp;((*ptr_p)-&gt;next_p);
        }
        x = x-&gt;next_p;
    }
    return retval;
}

Rather than just looking at making @ an inline C function, I think we (the 
Ocaml community) should be looking at adding this more general 
optimization in.

So now we get to my two questions:
a) is anyone working on this/intending to work on this RSN?
b) if the answer to (a) is no, can anyone give me some pointers on where 
to start looking at code, so I can add it in?

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>

