let rect = new Rectangle(x, y, sprite.Width, sprite.Height)
rect.X <- 888
The second line fails in F#, but in C# the assignment works. I am not sure why.
Rectangle is a struct rather than a class. You can have that line work as you'd expect if you mark the value with mutable:
let mutable rect = new Rectangle(10, 21, 10, 21)
rect.X <- 888
This is actually quite interesting, as F# makes the value-type semantics of structs more visible compared to what C# does.
rect.X <- 888 does not really mutate the field, rather it updates rect with a new value of the struct with the X field modified. So you can imagine it does an equivalent of rect <- { rect with X = 888 }. At that point it's quite clear why the compiler wants to see mutable there.
I wonder why F# designers didn't prohibit assignment syntax for structs and go with something similar to the record syntax. Probably they didn't want to make it too different compared to C#.
As the compiler is probably saying,
A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'
In F#, let creates an immutable variable (i.e. a value). The compiler enforces this by not letting you mutate it. You must write let mutable to get an equivalent variable declaration to what you had in C#.
Note that if Rectangle was a reference type, F# wouldn't complain, because you'd be modifying what is referenced by the value, not the value itself. In the case of a value type (like Mono's Rectangle), the identifier bound to the value is the value itself, so you cannot mutate it.
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