9

I have a desire to satisfy compiler warning level 5. So I have 32 warnings in one file FS0052 The value has been copied to ensure the original is not mutated by this operation

I've followed the only SO post that seems to be related to this warning, but since my type is being type provider generated by Microsoft I can't just go mark the field mutable to quiet the warning. plus making something mutable that actually shouldn't ever be mutated seems like a hack not a fix.

examples:

  1. Nullable .GetValueOrDefault()
  2. Nullable .ToString()
  3. Guid .toString()
  4. struct method calls of any sort I believe

What is the recommended way to deal with this warning from a proper functional perspective?

Community
  • 1
  • 1
Maslow
  • 18,464
  • 20
  • 106
  • 193

2 Answers2

6

Not sure if you're still interested.

It seems to me that the compiler emits the warning when it is unsure whether the method call is going to destroy the state of original instance (this should mostly come from any library outside F#).

Explicit copy the value into a variable is, in my case, often mitigate the warning. For example:

open System

// generate the warning due to "ToString()"
let DirSeparator = Path.DirectorySeparatorChar.ToString()  

// no warning
let ExplicitCopy = let x = Path.DirectorySeparatorChar in x.ToString()  

let Alternative = sprintf "%c" Path.DirectorySeparatorChar
Ruxo
  • 359
  • 4
  • 13
0

What is the recommended way to deal with this warning from a proper functional perspective?

I found many questions about the issue, but this particular question I found nowhere else. After having fixed many such warnings, this is my conclusion.

I believe there is no single solution. (Unless you want to resort to silencing the warning all over the place with a compiler directive or something, and I certainly don't want to do that. I have a feeling you agree with me on that, having bumped up the warning level to 5.)

First option

There is frequently another way to code, without having to resort to intermediate values or other complex expressions.

For example, to silence the warning in this case

myStruct.someField <- myRecord.SomeField.ToString()

simply change it to

myStruct.someField <- string myRecord.SomeField

Second option

If you do not find a function or some way to easily rewrite your way out of it, and it is a particular case that repeats frequently in your source, then there is the possibility to create a function or functions that you can use in these cases in order to silence the warning.

For example, I use this function instead of GetValueOrDefault.

let valueOrDefault (v: 'a Nullable) = if v.HasValue then v.Value else Unchecked.defaultof<'a>

Third option

If you have only a single particular case or barely a handful of similar cases, then using an intermediate value is possibly the easiest way to silence the warning. I tend to comment the reason for the verbosity in these cases.

Bent Tranberg
  • 3,445
  • 26
  • 35
  • I have to admit FS0052 has been annoying me enormously since I wrote this, and I had to resort to silencing it on the project level in one project. It is the only warning I know of that is more a nuisance than a help. I wish somebody could change the compiler to better analyze whether the warning is justified or not. – Bent Tranberg Apr 13 '17 at 10:42