Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do literals not const by default?

If F# encourages to write immutable eagerly evaluated data, why did F# not enforce simple let bindings to be const by default?

I need to explicitly write [<Literal>] attributes. For example:

module ConstVsStaticReadOnly =

    [<Literal>]
    let ConstInt32 = 1

    [<Literal>]
    let ConstString = "A" + "B" + "C"

    let staticReadOnlyBoolean = true
like image 277
MiP Avatar asked Apr 24 '17 17:04

MiP


1 Answers

When you use a const in .NET, all references to it are replaced by its value at compile time.

It sounds fine until you realize it is not limited to the assembly where the constant is defined. Other assemblies referencing it will also copy the value of the constant at the time of compilation.

You can see the results in a simple example:

Create a new F# Library project with a single module

module ConstTest 

let [<Literal>] ConstInt = 1
let NotConstInt = ConstInt

Then a console app with a reference to the library

[<EntryPoint>]
let main argv = 
    printfn "%A %A" ConstTest.ConstInt ConstTest.NotConstInt
    0

When run, it prints 1 1 - as expected.

Now modify the constant in the library

module ConstTest 

let [<Literal>] ConstInt = 2
let NotConstInt = ConstInt

Build the library (but not the console app!), copy the dll to the console app folder and run the app. It prints 1 2. Quite a surprise if you're not aware of this behavior.

Once you create a public constant, it should never change. That's why compilers will not create constants implicitly.

like image 164
Jakub Lortz Avatar answered Sep 23 '22 23:09

Jakub Lortz