I need to understand something very important regarding F#: how it handles references and values. I know that F# defines immutable and mutable objects and also know the reason why.
But there is one thing that I do not know: how are objects treated?
I mean, in C# everything is a pointer and when assigning to an object the reference of another one, data are the same, and we'll have two pointers pointing the same data.
So in C# if I have this:
Object myobj1 = new Object();
Object myobj2 = myobj1;
bool myobj1 == myobj2; // It is true
Well, what about f#?
let myvar: MyObj = new MyObj ()
let myvar2: MyObj = myvar
What's the situation here? Does the assignment involves copy? or not.
And, generally speaking, what's f# approach to this topic? (I mean value vs reference).
When working with reference types and value types, F# behaves just like C#.
Struct
attribute),The only notable difference is that standard F# types (discriminated unions, records, lists, arrays and tuples) have structural equality semantics. This means that they are compared by comparing the actual value stored in them and not by comparing references (even if they are reference types). For example, if you create two lists of tuples containing the same data you get:
> let l1 = [ ("Hello", 0); ("Hi", 1) ]
let l2 = [ ("Hi", 1); ("Hello", 0) ] |> List.rev;;
(...)
> l1 = l2;;
val it : bool = true
You get true
even though lists and tuples are reference types. If you compare the references however (EDIT: Added sample inspired by kvb):
> System.Object.ReferenceEquals(l1, l2);;
val it : bool = false
The use of structural equality makes sense in F# because the types are immutable - when you create two values containing the same data, they will always be the same. If they were mutable, you could change one and they wouldn't be equal anymore - that's why it makes more sense to use reference equality for mutable types.
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