7

$ is allowed in a custom operator, but if you try to use $$, <$> or for instance ~$% as operator name you will receive the following error:

error FS0035: This construct is deprecated: '$' is not permitted as a character in operator names and is reserved for future use

$ clearly also has the '$' in the name, but works, why? I.e.:

let inline ( $ ) f y = f y

// using it works just fine:
let test = 
    let add x = x + 1
    add $ 12

I see $ a lot in online examples and apparently as a particular kind of operator. What is this spcial treatment or role for $ (i.e. in Haskell or OCaml) and what should <$> do if it were allowed (edit)?

Trying to fool the system by creating a function like op_DollarDollar, doesn't fly, syntax check is done on the call site as well. Though as an example, this trick does work with other (legal) operators:

// works
let inline op_BarQmark f y = f y
let test = 
    let add x = x + 1
    add |? 12

// also works:
let inline op_Dollar f y = f y
let test = 
    let add x = seq { yield x + 1 }
    add $ 12
Abel
  • 56,041
  • 24
  • 146
  • 247
  • Yes, it's a same we can't define the standard ``<$>`` operator in F#. We should submit a request to allow these operators. – Gus Dec 23 '16 at 19:31
  • 1
    `:` is also on the list. [`$`](https://github.com/Microsoft/visualfsharp/blob/6afc4f9776a5dba903ca6b11965a206fb8bc23d8/src/fsharp/lex.fsl#L117) and [`:`](https://github.com/Microsoft/visualfsharp/blob/6afc4f9776a5dba903ca6b11965a206fb8bc23d8/src/fsharp/lex.fsl#L115) – Guy Coder Dec 23 '16 at 19:37
  • @guy, for `:` I understand it somewhat, since `:>` and `:?>` should probably not be overridable. I could say the same for `::`, but since `@` is overridable and `..` is too (surprising, but true), I would only assume `::` isn't because of the colon-related protected operators. – Abel Dec 23 '16 at 20:11
  • @guy, what is the "standard" `<$>` operator, what standard? – Abel Dec 23 '16 at 20:15
  • This is a question I am waiting for [kvb](http://stackoverflow.com/users/82959/kvb) to answer – Guy Coder Dec 23 '16 at 20:20
  • In Haskell, `<$>` is an infix synonym for `fmap`. – Mark Seemann Dec 23 '16 at 20:37
  • @MarkSeemann yes, also in other languages and it would be nice to be able to define it in F#. In [FSharpPlus](https://github.com/gmpl/FSharpPlus/blob/590ef4d0b1b843141f62b9d951e3b9fdb044d771/FSharpPlus/Operators.fs#L35) and other libraries it was defined like ``<!>`` due of this limitation. – Gus Dec 24 '16 at 00:13
  • @GuyCoder - your wish is my command :) – kvb Dec 24 '16 at 14:05

1 Answers1

5

There's some inconsistency in the F# specification around this point. Section 3.7 of the F# spec defines symbolic operators as

regexp first-op-char = !%&*+-./<=>@^|~ 
regexp op-char       = first-op-char | ? 

token quote-op-left  =
    |  <@ <@@  

token quote-op-right  =
    |  @> @@>  

token symbolic-op  =
    | ?
    | ?<-
    | first-op-char op-char*
    | quote-op-left
    | quote-op-right

(and $ also doesn't appear as a symbolic keyword in section 3.6), which would indicate that it's wrong for the compiler to accept ( $ ) as an operator.

However, section 4.4 (which covers operator precedence) includes these definitions:

infix-or-prefix-op :=
    +,  -, +., -., %, &, && 

prefix-op :=
    infix-or-prefix-op
    ~ ~~ ~~~             (and any repetitions of ~)
    !OP                  (except !=) 

infix-op :=
    infix-or-prefix-op  
    -OP +OP || <OP >OP = |OP &OP ^OP *OP /OP %OP !=  
                         (or any of these preceded by one or more ‘.’) 
    := 
    :: 
    $ 
    or 
    ?

and the following table of precedence and associativity does contain $ (but no indication that $ can appear as one character in any longer symbolic operator). Consider filing a bug so that the spec can be made consistent one way or the other.

kvb
  • 54,864
  • 2
  • 91
  • 133