caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: David Allsopp <dra-news@metastack.com>
To: "louis.jachiet@ens.fr" <louis.jachiet@ens.fr>,
	"caml-list@inria.fr" <caml-list@inria.fr>
Subject: RE: [Caml-list] Differences between Array and Strings
Date: Fri, 29 Apr 2011 14:36:11 +0000	[thread overview]
Message-ID: <E51C5B015DBD1348A1D85763337FB6D972AB0481@Remus.metastack.local> (raw)
In-Reply-To: <sympa.1304077303.17524.902@inria.fr>

Louis Jachiet wrote:
> Hi, I'am failing to understand the behavior of the code below. Why the
> string is not regenerated ? Why strings and array have not the same
> behavior ?

This has been commented on before (see the list archives) - if I understand correctly, it's a consequence of the code generator...

> > let l () = "1" ;;

Compiles to

(let (l/1030 (function param/1032 "1")) (makeblock 0 l/1030))

i.e. a reference to a constant with value "1" - not an allocation. So l always returns the same physical string, rather than allocating a new one. This makes sense if you're assuming that strings are by default used immutably (there have been plenty of discussions in the past on the relative merits of having the same string type for both immutable and mutable strings)

However, the constants clearly aren't used in a pool:

# let f () = "1";;
val f : unit -> string = <fun>
# let g () = "1";;
val g : unit -> string = <fun>

given:

# f () == g ();;
- : bool = false

> > (l ()).[0] <- '2';;
> > l ();;
> > l()==l();;
> 
> > let l () = [|1|] ;;
> > (l ()).(0) <- 2;;

This, however, compiles to

(let (l/1030 (function param/1032 (makearray 1))) (makeblock 0 l/1030))

i.e. it allocates a fresh array each time. The behaviour of the compiler would suggest that its authors considered string "constants" to be just that but the syntax for array literals to be simply sugar for an array allocation followed by initialisation of the members.

As a rule of thumb, if you're dealing with mutable strings, it's a good idea to be very clear who allocated them and where so personally I quite like the fact that the compiler forces you to need to write:

let l () = String.copy "1"

which will behave as you expected.

HTH,


David


  reply	other threads:[~2011-04-29 14:36 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-29 11:51 louis.jachiet
2011-04-29 14:36 ` David Allsopp [this message]
2011-04-30 14:06 ` Philippe Wang
     [not found] <fa.YVp+LBcZBn2VVSqyBV+/Bw0Mb/I@ifi.uio.no>
2011-04-30 11:03 ` Radu Grigore
2011-04-30 13:34   ` David Allsopp
2011-04-30 23:10     ` Martin Jambon

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=E51C5B015DBD1348A1D85763337FB6D972AB0481@Remus.metastack.local \
    --to=dra-news@metastack.com \
    --cc=caml-list@inria.fr \
    --cc=louis.jachiet@ens.fr \
    /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).