Julia parses the command
f = x -> x^2 # (1)
as
f = (x -> x^2) # (2)
This parsing is reasonable, because expression (2) is clearly what any user would mean in a real application.
However, Base.operator_precedence
gives that the =
operator has higher precedence than the ->
operator, so strictly speaking (1) should be parsed as
(f = x) -> x^2 # (3)
As far as I can tell, this is not a well-formed expression.
Question 1: When a literal application of the precedence specified by Base.operator_precedence
leads to an expression that is not well-formed, does Julia always automatically reparse the original expression in a way that leads to a well-formed expression? Or does it sometimes throw an error and require the user to manually parenthesize the expression so that it makes sense? If the former option is correct, then how does Julia do so?
But the plot thickens. Julia actually accepts line (3) as a valid expression without returning an error!
Question 2: Is line (3) a valid command? If so, how does Julia interpret it? If not, why doesn’t it return an error?
Moreover, if we assign
g = ((f = x) -> x^2) # (4)
and try to evaluate g
for any argument (e.g. g(5)
), then we get ERROR: UndefVarError: x not defined
. My first guess was that line (4) would return an error, and my second guess was that calling g(5)
would first assign f = 5
(per the inner parentheses) and then return 5^2
and discard the temporary variable f
. But both guesses are wrong.
Question 3: What is the behavior of the anonymous function g
?
Furthermore, if we instead define
h = ((f = x) -> f^2) # (5)
then the anonymous function h
behaves just like command (1) does, and simply squares its argument!
Question 4: The anonymous functions g
and h
defined in lines (4) and (5) seem equivalent. Why do they behave differently?
Question 5: I believe that commands (3), (4), and (5) are all ill-formed and should return error messages, so the behavior of g
and h
is undefined and the failure to return an error message is a bug in Julia. Am I correct?
The only relevant information I could find online is the comment
Yes,
->
has asymmetric precedence because it is very asymmetric: very few things can go on the left side (basically only a symbol or symbols) but any expression can go on the right side.x -> y = x
is a valid function that contains an assignment.
at Operator precedence for unlisted operators & anonymous functions · Issue #14933 · JuliaLang/julia · GitHub, which doesn’t fully answer my questions.
I’m running version 0.5.0.