tags:

views:

120

answers:

2

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?

+3  A: 

You won't be able to call methods which take byref parameters. This may or may not be a big deal for you.

As to your question about "AND patterns", here's a quick example. However, note that defining your own unary & operator will not affect this behavior one way or the other.

let (|Contains|_|) (s:string) (x:string) =
  if (x.Contains(s)) then Some() else None

match "test" with
| Contains "e" & Contains "s" -> printfn "Success!"
| _ -> ()

Oddly, I only see the warning you mention when defining a binary (&) operator, not the unary (~&) operator.

EDIT

Although I don't see it called out explicitly in the spec, it looks like the binary & operator is used as a synonym for the binary && operator. I would guess that the suggestion not to redefine this operator exists because it is a short-circuiting operator, but your overload cannot be.

kvb
+1 - Great answer, and almost identical to Tomas's. I'm afraid I have to give him the nod for slightly more detail and the cool infix-function trick. Plus I like his book.
Joel Mueller
+4  A: 

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:

// define custom & operator
let (&) a b = a + b

match 2 with
| num1 & num2 -> num1 + num2 // Still works fine

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)

Tomas Petricek
To answer your question about what I'm doing - I'm attempting to write a DSL for HTML generation, and I want to provide a convenient shortcut for something that's pretty common. The prefix version of the operator creates a Text node from a string, and the infix version wraps the Text node in a list, and passes it to the function that is the left-side argument. It's an occasion where I wish F# allowed implicit casting.
Joel Mueller