Inconsistent (apparently) behaviour with static members in F#
Solution 1:
I think your question is a good one. The definition of a static property is syntactically very similar to definition of a value - so I can see why you think the two should behave the same.
This is slightly misleading, because behind the senes, properties have a getter method that is evaluated each time the property is accessed. As a minimal example, in the following, accessing A1.B
twice prints "hi" twice:
type A1 = A1 with
static member B =
printfn "hi"
A1.B; A1.B
There is actually a more verbose syntax for properties in F#, which reveals what is going on - the fact that B
is actually backed by a get()
method that is invoked by the compiled code behind the scenes:
type A2 = A2 with
static member B
with get() = printfn "hi"
A2.B; A2.B
Now, you would never actually do this in practice, but you can even invoke the method (which is hidden from IntelliSense) directly:
A2.get_B(); A2.get_B()
Solution 2:
The following first 2 F# snippets get different results, but I find this a little inconsistent, even though I understand that members and values have different semantics. I would expect both of them getting the same results (the second one, as they have a similar value syntax).
You're expecting that evaluating _b
caused it to re-evaluate itself, but that's not how values evaluate in F#. If I define let x = 12
it doesn't re-evaluate what x
is each time I access it.
That's why it always prints 1
. When _b
is first accessed, it is evaluated once and that's it.
IMHO the third snippet, which explicitly defines a get method, should be differentiated from the first.
Why? It's no different than the first snippet. An F# property defined like so:
type A =
static member X = 12
Is compiled with a getter just like if you define it explicitly.