The first definition below produces the warning in the title when compiled with f# 3.0 and the warning level set to 5. The second definition compiles cleanly. I wondered if someone could please explain just what the compiler worries I might accidentally mutate, or how would splitting the expression with a let clause help avoid that. Many thanks.
let ticks_with_warning () : int64 =
System.DateTime.Now.Ticks
let ticks_clean () : int64 =
let t = System.DateTime.Now
t.Ticks
I cannot really explain why the compiler emits this warning in your particular case – I agree with @ildjarn that you can safely ignore it, because the compiler is probably just being overly cautious.
However, I can give you an example where the warning might actually give you a useful hint that something might not go as you would expect. If we had a mutable
structlike this:Now, the
Incmethod mutates the struct (and you can also access the mutable fieldticks). We can try writing a function that creates aTestvalue and mutates it:We did not mark the local value
tasmutable, so the compiler tries to make sure the value is not mutated when we callInc. It does not know whetherIncmutates the value or not, so the only safe thing is to create a copy – and thusfooreturns the valueTest(1L).If we mark
tasmutable, then the compiler does not have to worry about mutating it as a result of a call and so it does not give the warning (and the function returnsTest(2L)):I’m not really sure what is causing the warning in your example though. Perhaps the compiler thinks (as a result of some intermediate representation) that
Ticksoperation could mutate the left-hand-side value (System.DateTime.Nowandtrespectively) and it wants to prevent that.The odd thing is that if you write your own
DateTimestruct in F#, you get a warning in both cases unless you mark the variabletasmutable(which is what I’d expect), but the behaviour with standardDateTimeis different. So perhaps the compiler knows something about the standard type that I’m missing…