When defining a custom operator from the limited set of single-character operators that can be both infix and prefix operators (+ - % &) I decided to use the ampersand, since it’s the only one of those operators that I have not so far had occasion to use in my F# code. I reasoned that since & seems to have fairly limited use in F#, redefining it would be least confusing to people using my library.
However, when I do so, I get a compiler warning:
The ‘&’ operator should not normally be redefined. Consider using a different operator name.
My question is, why does this seemingly-rare operator generate this warning message, while commonly-used operators like plus and minus do not? Also, how seriously should I take this warning?
When creating a custom operator, I generally prefer finding a simple combination of symbols that doesn’t conflict with any existing F# operator. The true is that the symbol set is very limited, so this isn’t always possible. However you can for example define something like
-&-and you can often pick some combination that reflects the meaning of the operator. Just out of curiosity, what will the meaning your operator be?Anyway, when I cannot find a good operator name, then I consider it as a sign that maybe I shouldn’t use a custom operator (afterall, many languages live without them quite easily). I think the main use of custom operators is probably some specialized mathematical stuff. You can often replace operator (e.g.
a -&- b) by a functiong used with pipelining (e.g.a |> connectTo b). There is also a neat trick that allows you to use functions as infix operators.In case of
&, I think it is a pretty reasonable option to ignore the warning if you have a good use for the operator and the behavior of the operator you want to define somehow corresponds with the intuition about the&symbol.EDIT Defining your own
&operator will not break the other use of the&symbol (in pattern matching). Here is an example of the and pattern:The and pattern allows you to match a single value agains multiple patterns in a single pattern (in the example above, we just bind it to two distinct values)