What is the point of FunctionArrowPrecedence?

I guess looking at function types naively makes them look like binary expressions: (A) -> B.
But that went out the window when error handling was introduced: (A) throws -> B.
And they can also be attributed, which normal binary expressions can't: @convention(c) (A) -> B.

They can't even be mixed with other expressions freely. AFAIU, they can only be used as expressions inside (…).self.

So, what is FunctionArrayPrecedence for? Maybe someone could shed a light on what you could do with it.

They can, as part of a cast, declaration, default value for an associated type or a same-type constraint. I suppose FunctionArrowPrecedence is used to evaluate patterns like the following, together with AssignmentPrecedence and CastingPrecedence:

if let bar = baz as? () -> Int { ... }

let foo: () -> Int = { return 0 }
2 Likes

Okay, a cast is an expression, but its right-hand side side is not. It only allows types, and so do those other examples. Even if you have an operator with a different precedence, it will never be able to interact (or compete) with ->, because operators only operate on expressions, not on types. The -> "operator" operates only on types.

It seems to me the precedence of -> is just baked into the grammar, just like the precedence of the lookup . or the key path \.

1 Like

Yes, it is an implementation detail. The compiler even has an ArrowExpr type, probably to streamline and keep algorithms that fold sequences of binary expressions into trees or compute the positioning of parentheses to be inserted consistent.