Skip to content

Associativity and precedence of symbolic operator @ is unspecified in F# Language Specification #3566

@21c-HK

Description

@21c-HK

I was trying to use @ and other user-defined symbolic operators beginning with @ (e.g. @!) to achieve the same semantic as |> (‘forward pipe operator’) and similar operations. It seems that @ and user-defined symbolic operators beginning with @ are right-associative (determined by testing, see code example below), but this is neither specified in the F# Language Specification, nor mentioned anywhere in the official documentation (‘Symbol and Operator Reference’). I still don't know anything about the precedence of ‘@’ because I was not able to find any information on that.

According to The F# 4.0 Language Specification (latest, PDF), @ is a ‘symbolic operator’ (§3.7), it is not a ‘symbolic keyword’ (§3.6), but it is not mentioned in the ‘Operators and Precedence’ (§4.4) and its associativity and precedence is not specified in ‘Precedence of Symbolic Operators and Pattern/Expression Constructs’ (§4.4.2). These sections are unchanged from the The F# 3.1 Language Specification (final version, PDF) with regards to this issue.

I would like to get answers to the following questions before this is fixed in the F# Language Specification:

  1. What does the compiler currently decide with regards to the associativity and precedence of @ as symbolic operator?
  2. Can its associativity and precedence of @ still be changed as it is was not specified so far?

Repro steps

Try the following in F# Interactive (should be reproducable in any version):

    let inline (@) x f = f x // same semantic as `|>`, which is left-associative because of `|`
    let inline (^) x f = f x // also the same as `|>`, but `^` is right-associative
    let f x = x * 1 //just some function to test `@`  and `^` as infix-operators
    let g x = x * 2 //another function  to test `@`  and `^` as infix-operators
    let y = 1 @ f @ g // shows a type mismatch error
    let y = 1 ^ f ^ g // shows the same type mismatch error as `1 @ f @ g` (due to right-associativity)
    let y = (1 @ f) @ g // works because left-to-right evaluation is enforced

Expected behavior

Did not know what to expect as its behavior is not specified. But it would be cool if @ was left-associative if it can be changed. I do know that @ is ordinarily used for list concatenation (inherited from OCaml) and implementing it as an inline static member shows the following warning: “The name (@) should not be used as a member name because it is given a standard definition in the F# library over fixed types” (whatever the cryptic part after “because” is supposed to mean), but @ is a valid ‘symbolic operator’, so that should not be a problem.

Actual behavior

The example code indicates that @ is right-associative, but as explained above, this is not specified anywhere and its precedence is still not known.

Related information

Tested with F# Interactive version 12.0.30815.0 (F# 3.1) in Visual Studio 2013.
Tested with F# Interactive version 14.0.23413.0 (F# 4.0) in Visual Studio 2015 (and Visual Studio Code).

Edit: Changed Visual Studio 2015 (which was typo) to 2013 for F# Interactive version 12.0.30815.0 (F# 3.1).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions