When are physically different values ​​created in OCaml?

I am trying to understand what the physical equality operators ( Pervasives.(==) and Pervasives.(!=) ) Mean in OCaml.

The instruction manual says that the expression "" is a "constant" and not an "expression":

6.5 Constants

constant :: == ... string-literal

but I cannot find a phrase indicating that the constants are once / pre-evaluated or combined, and REPL indicates that mutable string values ​​(fortunately) are not combined.

 (* a *) "" == "";; (* false *) (* b *) "foo" == "foo";; (* false *) (* c *) "" == String.copy "";; (* false *) (* d *) () == ();; (* true *) (* e *) (42, -42) == (42, -42);; (* false *) (* f *) ("", 1) == ("", 1);; (* false *) (* g *) None == None;; (* true *) (* h *) (Some None) == (Some None);; (* false *) 

Section " 19.3 Representation of OCaml Data Types " assumes that language specification requires bools, ints, chars, a unit value, simple options, and empty lists are disinterested.

Should the implementation behave as described above as an executable implementation of OCaml?

Can the running OCaml implementation rewrite the pointer to b to point to a when a = b (* structurally *) is true, and both are values ​​of immutable type (or actually immutable values, such as strings / arrays of zero length), as sometimes made to reduce the number of achievable low values ​​in the GC generation?

+4
source share
2 answers

When I read the language specification, there are very few guarantees as to when the meanings are different. I believe that the only guarantee is the Pervasives module documentation:

For mutable types, such as references, arrays, strings, records with mutable fields, and objects with mutable instance variables, e1 == e2 is true if and only if the physical modification of e1 also affects e2. For non-variable types, behavior (==) is implementation dependent; however, it is guaranteed that e1 == e2 implies a comparison of e1 e2 = 0.

One of the interesting things about FP is that the compiler and runtime can do arbitrarily smart things with immutable values. Thus, this guarantee applies to everything that you really would like to have (IMHO).

In general, yes, the runtime or the compiler is free (again, IMHO) to share (and not pass) immutable values ​​in any way that, in his opinion, will be useful.

I would not interpret the presentation section as part of the language specification. These are just useful documentation for the current implementation.

+5
source

Just a note: String constants are combined differently than the ones you are testing:

 let f () = "foo" let b = f () == f () (* true *) 

This can lead to errors if you mutate the output of the f () call: it will affect all further calls. The consensus on this behavior is that a mutable string is a historical error (one must have a mutable buffer type different from the main string type, according to which the encoding choice and concatenation complexity should be more important) and that legibility with semantics is interesting enough to suggest that string constants are not mutated. If you want to avoid the pool, you just need to call String.copy directly in the string constant.

+3
source

All Articles