caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Florian Hars <florian@hars.de>
To: Brian Hurt <brian.hurt@qlogic.com>
Cc: Markus Mottl <markus@oefai.at>, Ocaml Mailing List <caml-list@inria.fr>
Subject: Re: [Caml-list] Probably FAQ: Why is list-append (list :: elem) so expensive?
Date: Thu, 26 Sep 2002 09:10:11 +0200	[thread overview]
Message-ID: <3D92B2D3.3090201@hars.de> (raw)
In-Reply-To: <Pine.LNX.4.33.0209251315440.1974-100000@eagle.ancor.com>

Brian Hurt wrote:
> Consider the following Ocaml code:
> 
>     let dup_list lst =
>         let rec reverse_list l accum =
>             match l with
>                 [] -> accum
>                 | head :: tail -> reverse_list tail (head :: accum)
>         in
>             reverse_list (reverse_list lst)

This should probably be reverse_list (reverse_list lst []) []

>     ;;
[...]
> So why not reuse the cells from l to form the accum?  

To optimize reverse_list in the way you propose, the compiler would have to be 
smart enough to see that reverse_list is only ever called twice, so as to 
return (a list that is equivalent to) the original list. (If reverse_list were 
called in any other context, the optimazition would be illegal, since it 
destroys the original list). But then the compiler would know enough to perform 
the correct optimization of your code to

let dup_list lst = lst

and then eliminate all calls to dup_list entirely. But since the same effect 
can be had by not introducing the function in the first place, it would be a 
royal waste of ressources to make the compiler detect this case.

> Yes, I know this violates the immutability of l.  But it seems to me that, 
> with the exception of garbage creation rates, the two are identical.

Yes, of course. Your dup_list is one of the most expensive no-ops you can 
perform on a list.

The point is: unlike in languages of the Fortran heritage (C, Java...), 
variables in functional languges designate values and are not names for 
physical storage locations. To add to the confusion, ocaml blurs this by 
supporting both physical (==, !=) and value (=, <>) comparisions:

$ ledit ocaml
         Objective Caml version 3.06

# let dup_list lst =
   let rec reverse_list l accum =
     match l with
           [] -> accum
       | head :: tail -> reverse_list tail (head :: accum)
     in
     reverse_list (reverse_list lst []) []
     ;;
val dup_list : 'a list -> 'a list = <fun>
# let l = [1; 2; 3];;
val l : int list = [1; 2; 3]
# let l' = dup_list l;;
val l' : int list = [1; 2; 3]
# l = l';;
- : bool = true
# l == l';;
- : bool = false

This last inequality is the *only* difference between using

let l' = dup_list l

and using

let l' = l

and it would disappear if your optimazation were performed (since then dup_list 
would just return its argument restored to its original state). So there is no 
reason not to use the second, simpler and more efficient version.

Even with your dup_list, the contents of the two list are physically the same:

# let m = [ref 1; ref 2; ref 3];;
val m : int ref list = [{contents = 1}; {contents = 2}; {contents = 3}]
# let m' = dup_list m;;
val m' : int ref list = [{contents = 1}; {contents = 2}; {contents = 3}]
# m == m';;
- : bool = false
# List.hd m == List.hd m';;
- : bool = true
# List.hd m := 42;;
- : unit = ()
# m';;
- : int ref list = [{contents = 42}; {contents = 2}; {contents = 3}]

Yours, Florian.

-------------------
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


  parent reply	other threads:[~2002-09-26  7:10 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-09-25 15:33 Brian Hurt
2002-09-25 15:39 ` Noel Welsh
2002-09-25 15:42 ` Oleg
2002-09-25 16:17 ` Markus Mottl
2002-09-25 18:44   ` Brian Hurt
2002-09-25 19:22     ` Markus Mottl
2002-09-26  7:10     ` Florian Hars [this message]
2002-09-26 14:44 ` Kontra, Gergely

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3D92B2D3.3090201@hars.de \
    --to=florian@hars.de \
    --cc=brian.hurt@qlogic.com \
    --cc=caml-list@inria.fr \
    --cc=markus@oefai.at \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).