* [Caml-list] Differences between Array and Strings
@ 2011-04-29 11:51 louis.jachiet
2011-04-29 14:36 ` David Allsopp
2011-04-30 14:06 ` Philippe Wang
0 siblings, 2 replies; 6+ messages in thread
From: louis.jachiet @ 2011-04-29 11:51 UTC (permalink / raw)
To: caml-list
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 ?
> let l () = "1" ;;
> (l ()).[0] <- '2';;
> l ();;
> l()==l();;
> let l () = [|1|] ;;
> (l ()).(0) <- 2;;
> l ();;
> l() == l() ;;
# val l : unit -> string = <fun>
# - : unit = ()
# - : string = "2"
# - : bool = true
# val l : unit -> int array = <fun>
# - : unit = ()
# - : int array = [|1|]
# - : bool = false
Louis Jachiet
^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: [Caml-list] Differences between Array and Strings
2011-04-29 11:51 [Caml-list] Differences between Array and Strings louis.jachiet
@ 2011-04-29 14:36 ` David Allsopp
2011-04-30 14:06 ` Philippe Wang
1 sibling, 0 replies; 6+ messages in thread
From: David Allsopp @ 2011-04-29 14:36 UTC (permalink / raw)
To: louis.jachiet, caml-list
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Caml-list] Differences between Array and Strings
2011-04-29 11:51 [Caml-list] Differences between Array and Strings louis.jachiet
2011-04-29 14:36 ` David Allsopp
@ 2011-04-30 14:06 ` Philippe Wang
1 sibling, 0 replies; 6+ messages in thread
From: Philippe Wang @ 2011-04-30 14:06 UTC (permalink / raw)
To: louis.jachiet; +Cc: caml-list
It's a weird feature of OCaml...
Anyway, if you want to allocate a string, you should write
let l () = String.copy "1"
instead of
let l () = "1"
--
Philippe Wang
mail@philippewang.info
On Fri, Apr 29, 2011 at 1:51 PM, <louis.jachiet@ens.fr> 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 ?
>
>> let l () = "1" ;;
>> (l ()).[0] <- '2';;
>> l ();;
>> l()==l();;
>
>> let l () = [|1|] ;;
>> (l ()).(0) <- 2;;
>> l ();;
>> l() == l() ;;
>
> # val l : unit -> string = <fun>
> # - : unit = ()
> # - : string = "2"
> # - : bool = true
> # val l : unit -> int array = <fun>
> # - : unit = ()
> # - : int array = [|1|]
> # - : bool = false
>
> Louis Jachiet
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Caml-list] Differences between Array and Strings
2011-04-30 13:34 ` David Allsopp
@ 2011-04-30 23:10 ` Martin Jambon
0 siblings, 0 replies; 6+ messages in thread
From: Martin Jambon @ 2011-04-30 23:10 UTC (permalink / raw)
To: caml-list
On 04/30/11 06:34, David Allsopp wrote:
> Radu Grigore wrote:
>> On Friday, April 29, 2011 12:51:59 PM UTC+1, louis....@ens.fr wrote:
>>>> let l () = "1" ;;
>>>> [...]
>>>> l()==l();;
>>> # val l : unit -> string = <fun>
>>> # [...]
>>> # - : bool = true
>>
>> Is there a good reason for this behavior?
>
> Whether it's good is debatable, but in most instances you don't want a fresh string being allocated each time for a constant value as it would be a waste of time and memory (most strings are used immutably).
I concur.
And the strings that we mutate are buffers which are not created from
string literals anyway.
Martin
^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: [Caml-list] Differences between Array and Strings
2011-04-30 11:03 ` Radu Grigore
@ 2011-04-30 13:34 ` David Allsopp
2011-04-30 23:10 ` Martin Jambon
0 siblings, 1 reply; 6+ messages in thread
From: David Allsopp @ 2011-04-30 13:34 UTC (permalink / raw)
To: caml-list
Radu Grigore wrote:
> On Friday, April 29, 2011 12:51:59 PM UTC+1, louis....@ens.fr wrote:
> > > let l () = "1" ;;
> > > [...]
> > > l()==l();;
> > # val l : unit -> string = <fun>
> > # [...]
> > # - : bool = true
>
> Is there a good reason for this behavior?
Whether it's good is debatable, but in most instances you don't want a fresh string being allocated each time for a constant value as it would be a waste of time and memory (most strings are used immutably).
> My first thought was that that code should behave the same as
>
> let f () = ref () in f () == f ()
> (A satisfying explanation would *not* involve the compiler.)
Look at the OCaml language specification - "1" is a constant and the result of that expression is the constant itself (6.7.1). [|1|] is an array expression and the result of that expression is a "1-element array, whose element(s) are initialized with the value(s) 1" (roughly quoting section 6.7.3). i.e. an array expression implies the creation of the array as its result but a constant evaluation does not.
C behaves in the same (or at least in a very similar) way... not that that could ever be used as a justification for behaviour in a sane language like OCaml ;o)
David
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Caml-list] Differences between Array and Strings
[not found] <fa.YVp+LBcZBn2VVSqyBV+/Bw0Mb/I@ifi.uio.no>
@ 2011-04-30 11:03 ` Radu Grigore
2011-04-30 13:34 ` David Allsopp
0 siblings, 1 reply; 6+ messages in thread
From: Radu Grigore @ 2011-04-30 11:03 UTC (permalink / raw)
To: fa.caml; +Cc: caml-list
On Friday, April 29, 2011 12:51:59 PM UTC+1, louis....@ens.fr wrote:
> > let l () = "1" ;;
> > [...]
> > l()==l();;
> # val l : unit -> string = <fun>
> # [...]
> # - : bool = true
Is there a good reason for this behavior? My first thought was that that code should behave the same as
let f () = ref () in f () == f ()
(A satisfying explanation would *not* involve the compiler.)
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-04-30 23:09 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-29 11:51 [Caml-list] Differences between Array and Strings louis.jachiet
2011-04-29 14:36 ` David Allsopp
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
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).