Reputation: 12107
After some practice with F#, I have still some points where I need to clear confusion:
The question is specifically about fields in a type.
This is what I understand and, some must be wrong because the naming wouldn't make sense if I was right:
let x -> private read-only field, evaluated once
let mutable x -> private mutable field
val x -> public read-only field.. difference with let?
val mutable x -> public mutable field
member this.x -> private read-only field, evaluated every time
member val -> public mutable field.. difference with val? why no mutable keyword?
Can someone tell me what is right / wrong, or some concepts I may have gotten wrong.
Upvotes: 0
Views: 51
Reputation: 243041
First of all, you can pretty much ignore val
and val mutable
. Those two are used with an older syntax for defining classes that is not exactly formally deprecated, but I would almost never use it when writing new normal F# code (there are some rare use cases, but I don't think it's worth worrying about those).
This leaves let
and let mutable
vs. member
and member val
.
let
defines a private field that can only be accessed within the class. The value you assign to it is evaluated once. You can also define functions like let foo x = x + 1
or let bar () = printfn "hi"
which have body that's evaluated when the function is called.
let mutable
defines a private mutable field. This is initialized by evaluating the right-hand side, but you can later mutate it using fld <- <new value>
.
member this.Foo = (...)
defines a get-only property. The expression (...)
is evaluated repeatedly whenever the property is accessed. This is a side-effect of how .NET properties work - they have a hidden get()
method that's called whenever they are accessed, so the body is the body of this method.
member val Foo = (...)
is a way of writing a property that is evaluated only once. In earlier versions of F#, this was not available, so you had to implement this functionality quite tediously yourself by definining a local field (to run the code once) and then returning that from a regular property:
let foo = (...)
member x.Foo = foo
Upvotes: 2