tags:

views:

170

answers:

2

In C# one can define a type member constant like this:

class Foo { public const int Bar = 600; }

The IL looks like this.

.field public static literal int32 Bar = int32(600)

How can I do the same within Visual F# / FSharp?

I tried this to no avail:

[<Sealed>]
 type Foo() =

    [<Literal>]
    let Bar = 600
A: 

I'm not sure that this is possible. In fact, I don't even think that you can create immutable public fields, not to mention constants.

kvb
I believe you can create public immutable fields using the `val` declaration and explicit initialization in the constructor written using `new()`, but that wouldn't work for constants, because `val` fields are initialized in the constructor.
Tomas Petricek
@Tomas - I think that you'll find that your suggestion actually results in a property being defined, rather than a field. Using a `val mutable` does result in a mutable field, however.
kvb
@kvb - You're right. public `val` results in a property with a private field (the motivation is to forbid possible C# users of the class from modifying a field that should be immutable).
Tomas Petricek
+6  A: 

I did a couple of experiments with the F# compiler an here are some my observations. If you want to create IL literal, then you need to place the value marked as a Literal inside a module. For example like this:

module Constants = 
  [<Literal>]
  let Num = 1

As a side-note, I did a quick search through the F# specification and it seems that literals can be very useful for pattern matching, because you can use them as a pattern (as long as they start with an uppercase letter):

open Constants
match 1 with
| Num -> "1"
| _ -> "other"

Now, the question is, why Literal doesn't behave as you would expect when you place it inside a type declaration. I think the reason is that let declaration inside an F# type declaration cannot be public and will be visible only inside the class/type. I believe that both C# and F# inline literal values when you use them and this is done inside type declarations too. However since the literal cannot be public, there is no reason for generating the literal IL field, because nobody could ever access it.

Tomas Petricek
In C# the literals will be inlined in the bytecode, but the const field will still be there for other types to be used.
zproxy
Yes - in F# the `field` will be generated if the literal is public (e.g. in a module) and can be used by someone; if it is visible only inside the class, there is no point generating the bytecode, because other types can't use it anyway.
Tomas Petricek