On Thu, Oct 20, 2016 at 4:02 PM, Brent Royal-Gordon via swift-evolution < [email protected]> wrote:
> > On Oct 20, 2016, at 12:25 PM, Jonathan Hull via swift-evolution < > [email protected]> wrote: > > > > These can be used as identifiers unless they have been defined as an > operator somewhere within the project, at which point they switch to being > only usable as operators. > > Imagine you're the compiler and you've been handed this source file: > > let party = ππ > prefix operator π > > You're going to see a keyword "let", an identifier "party", an "=" > operator, and then the sequence "ππ". How will you interpret that > sequence? There are a few possibilities: > > 1. A two-character variable named "ππ". > 2. A prefix "π" operator followed by a one-character variable name "π". > 3. A two-character operator "ππ" with an operand to follow on the next > line. > 4. A one-character variable name "π" followed by a postfix "π" operator. > > The operator declaration on the next line will make all of this clearβbut > we can't understand the next line until we've parsed this line (see #3). > Nope. There is no scenario in which any of this is clarified by an operator declaration, and certainly one that is not in the lexical scope. What would happen is this: 1. At the LEXICAL level, the sequences ππ will be handled according to the tokenization rules. If emojis are admitted in Swift, they are definitely in the identifier space, so both of these are "normal" identifiers. 2. At the parse level, no operator is in scope when you encounter the ππ, so it's simply an identifier. 3. At symbol resolution, no binding is found for that identifier, and an error is raised. Now let's consider real examples: let c = a +++ b /// +++ is a user infix operator Fails, because +++ is not defined in the lexical scope. func +++ (a, b) -> int { ...} ... let c = a +++ b fails because this tokenizes as LET ident = ident ident ident, which is a parse error. So how about: func +++ (a, b) -> int { ...} ... let c = +++(a, b) succeeds. Tokenizes as LET ident = ident ( ident, ident), which is a function call. OK. Now how about; infix operator +++ : *SomePrecedence* ... let c = a +++ b builds a parse tree in which +++ is bound in the lexical contour of operator symbols, but fails because +++ is *not* bound in the lexical contour of identifiers. What was needed was func +++(a, b) -> int { ... } infix operator +++ : *SomePrecedence* ... let c = a +++ b THIS works. Builds an operator expression parse tree because +++ is bound in the lexical contour of operator reserved words. Identifier resolution then succeeds because +++ is *also* bound in the lexical contour of identifiers. But this would be very strange in Swift, which is otherwise completely > insensitive to the order of statements in a declaration scope. And it leads > to a strange two-phase behavior when parsing multiple files: You would need > to parse each file through the end of its operator declarations before > parsing any other code in any of the other files. If I understand the language reference correctly, what you say is true within a class definition, but not at file or local scope. Normal scopes follow the normal rules for lexical contours. Member scopes have something like the behavior you suggest, but the rules there are more complex than you are describing. Jonathan
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
