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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With