I am a bit confused by the Literal keyword and why it is necessary in F#.
Reading the docs, it sounds to me that [<Literal>]
is used to define a constant, however I am a bit confused how this constant differs from all other constants in F#..
Values that are intended to be constants can be marked with the Literal attribute. This attribute has the effect of causing a value to be compiled as a constant.
When I think of a constant, I think of something which is immutable....
let x = "a" + "b" //this is a immutable value, its value is constant [<Literal>] let y = "a" + "b" //this is also a immutable value, but why is this a special constant?
Is it because the 'normal' F# values are evaluated lazily and the [<Literal>]
is not evaluated lazily..? is that what they mean with 'compiled as constant'..? or is there something else to it?
Constants are variables that can't vary, whereas Literals are literally numbers/letters that indicate the value of a variable or constant.
A literal is a value that is expressed as itself. For example, the number 25 or the string "Hello World" are both literals. A variable in a program can change its value during the course of execution of the program. A constant retains the same value throughout the program.
A literal both defines data and represents data. The address of the literal is assembled into the object code of the instruction in which it is used. The constant specified by the literal is assembled into the object code, in the literal pool. A constant is represented by a symbol with a relocatable value.
Named literalsThis attribute has the effect of causing a value to be compiled as a constant. Named literals are useful for: Pattern matching without a when clause.
In your example, x
is an immutable value that is assigned during runtime (but NOT evaluated lazily), whereas y
is assigned during compiletime. As an example,
let myDLL = "foo.dll" [<DllImport(myDLL, CallingConvention = CallingConvention.Cdecl)>] extern void HelloWorld()
will not work, because DllImport is an attribute and needs to know the value of myDLL
during compilation. However, this will work:
[<Literal>] let myDLL = "foo.dll" [<DllImport(myDLL, CallingConvention = CallingConvention.Cdecl)>] extern void HelloWorld()
If you come from C# background, you can think of Literal
values as const
fields, and non-literal ones as readonly
fields. The same differences apply.
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