Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parsing issues with unary operators followed by ( #26137

Closed
andyferris opened this issue Feb 21, 2018 · 4 comments
Closed

parsing issues with unary operators followed by ( #26137

andyferris opened this issue Feb 21, 2018 · 4 comments
Assignees
Labels
bug Indicates an unexpected problem or unintended behavior parser Language parsing and surface syntax

Comments

@andyferris
Copy link
Member

andyferris commented Feb 21, 2018

I made a typo (-+ instead of .+) and I found the result very surprising:

julia> :(1 -+ (a=1, b=2))
:(1 - ((a = 1) + (b = 2)))

julia> 1 -+ (a=1, b=2)
-2

I don't know where to start... it's just so... so...

(Happens on v0.7 and v0.6. EDIT: to be clear, I really expected the parser to greedily create a NamedTuple before worrying about the operators).

@andyferris andyferris added bug Indicates an unexpected problem or unintended behavior parser Language parsing and surface syntax labels Feb 21, 2018
@andyferris
Copy link
Member Author

We also forgot to treat operators as functions with the "no space between functions and (" rule

julia> + (1, 2)
3

I expect the same behavior as

julia> f (1, 2)
ERROR: syntax: space before "(" not allowed in "f ("

@andyferris andyferris changed the title Parsing issue Parsing issues Feb 21, 2018
@JeffBezanson JeffBezanson self-assigned this Feb 21, 2018
@JeffBezanson
Copy link
Member

Yeah... what's happening is there's an ambiguity between parsing +(x) as a unary operator applied to a parenthesized expression, vs. as a 1-argument prefix function call form. We've been resolving it as the former. I think it would probably be good to switch to the latter, but we need to think through the implications.

@andyferris
Copy link
Member Author

There's a comma in these examples, though - I don't feel these count as "parenthesized expressions" but rather tuple and named tuple literals.

One thing which I find confusing is that +(1, 2) becomes a function call to + with two positional arguments, yet +(a=1, b=2) is not a function call to + with two keyword arguments. I'm struggling to find what the unifying logic here is.

In the former scheme maybe there should also be a difference between + (x) and + (x,) (note the space). The former working out as calling + with x and the latter with calling + with a tuple, (x,). Without the space it is ambiguous, I have less of a strong opinion here except to point out that if deleting that space changes behavior that could be surprising, and if adding brackets around + changes behaviour that could also be surprising, so I have no idea:

(+)(1, 2)  # Function call - call `+` with two arguments, `1` and `2`
+ (1, 2)   # Unary operator on a tuple - call `+` with one argument, `(1, 2)`
+(1, 2)    # Could be either, or a parsing ambiguity error

Also, the last one is a valid way of defining a method on (the function) +.

Parsing issues get confusing, fast...

@JeffBezanson
Copy link
Member

See #12771. The tricky case is -(x)^y, which should parse like -(x^y). That means -(x) can't be interpreted as function call syntax, since then it would have higher precedence than ^.

Applying a unary operator to a tuple is not useful, so I don't see it helping to parse +(2,) that way.

We can patch up +(a=1, b=2) to call + with keyword arguments. But there are still other weird cases (discussed in the linked issue) like +((1,2)).

I'll try to come up with something. I think we should prefer to treat +( ... ) as prefix function call syntax, unless it's followed by ^ and the ( ) part is just a parenthesized expression (no commas).

@JeffBezanson JeffBezanson changed the title Parsing issues parsing issues with unary operators followed by ( Feb 21, 2018
JeffBezanson added a commit that referenced this issue Feb 27, 2018
RFC: fix #26137, change parsing of unary ops on parenthesized expressions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior parser Language parsing and surface syntax
Projects
None yet
Development

No branches or pull requests

2 participants