Feedback for SE-0004: Remove the ++ and -- operators


(David Zarzycki) #1

Hi Chris,

An observation about SE-0004: Remove the ++ and — operators:

Given that the above is accepted, the only remaining postfix operator in the language is ‘!’ — and that is implemented by the compiler. Please consider just removing user-defined postfix operators entirely. Doing so would define away a type checking ambiguity where “let f : T -> T = someOperatorIdentifier” is ambiguous when both prefix and postfix operators exist.

Cheers,
Dave


(David Zarzycki) #2

It is just simplification that opens the door to further simplicity and self-consistency within the language. In addition to not needing the above workaround, one could remove the fixity keywords/attributes altogether, because they’d be inferable from context.

If one wants to go deep down the rabbit hole, one could let developers avoid nested parenthesis and the “spiral call syntax problem” by allowing the language to use the same unary operator in either prefix or postfix positions. For example, instead of “(^(-(~x).a).b).c”, one could write “x~.a-.b^.c” to accomplish the same goal.

Dave

···

On Dec 6, 2015, at 00:04, Chris Lattner <clattner@apple.com> wrote:

On Dec 5, 2015, at 11:26 AM, David Zarzycki <zarzycki@icloud.com> wrote:

Hi Chris,

An observation about SE-0004: Remove the ++ and — operators:

Given that the above is accepted, the only remaining postfix operator in the language is ‘!’ — and that is implemented by the compiler. Please consider just removing user-defined postfix operators entirely.

Hi Dave!

That is definitely an interesting idea. In practice, we won’t be able to remove ++/— from the compiler until the ~Spring 2017 release, since Swift 3 will want to parse the old code and reject it with a fixit hint.

Doing so would define away a type checking ambiguity where “let f = T -> T = someOperatorIdentifier” is ambiguous when both prefix and postfix operators exist.

Besides the general simplification potential for the language, is this a theoretical concern or an actual one? You can currently do something like “let f = T->T = {$0^}” or “{^$0}” to disambiguate the prefix/postfix forms.


(David Zarzycki) #3

Hi Jonathan,

This is really cool. Thanks for sharing! As I responded to Chris later in the thread (and to use different words), I do agree that postfix syntax is really useful, and arguably better than prefix syntax. What I was ultimately suggesting was that if Swift only had “unary” operators, then one can freely use them in either postfix or prefix positions. Just use whatever is natural for your code. The only downside of what I was suggesting is that one cannot have *different* behavior for a given operator just based on its prefix or postfix position.

Cheers,
Dave

···

On Dec 6, 2015, at 10:40, Jonathan Hull <jhull@gbis.com> wrote:

TL;DR: Please don’t remove custom postfix operators.

I actually rely on the custom postfix operators a great deal.

My first real swift project was to write a PEG parser where you define the grammar rules in swift itself (which allows the rules and code to be intermixed freely… which is super useful). I can call functions or execute a block upon a match.

The grammar uses a bunch of custom operators including several postfix ones. Here is a snippet of rules for a grammar which allows complex math equations (This is swift code in a rules() method)

rule("mathFunc") <- word & ( %"mathFuncParams" | %"mathEmptyParams")
rule("mathFuncParams") <~ "("¡ ~ %"mathExpr" ~ (","¡ ~ %"mathExpr")* ~ ")"¡
rule("mathEmptyParams") <~ "("¡ ~ ")"¡

The only reason this works at all is that there are several overloaded operators
<- Define rule
<~ Define rule ignoring whitespace
& Sequence
~ Same as &, but ignore whitespace
> Ordered Choice
postfix * Repeat 0 or more times
postfix ¡ Discard token
prefix % Reference to rule

As mentioned above, this is useful because I can intermix swift code and PEG rules:

rule("boolCompare") <~ %"mathExpr" ~ %"boolCompareType" ~ %"mathExpr"=^{s in
    let rhs = s.stack.popMath()!
    let comp = s.stack.popStr()!
    let lhs = s.stack.popMath()!
    s.stack.push(Token.boolExpr(ComparisonExpr(lhs:lhs,rhs:rhs,comparison:comp)))
}
        
(Above: Whenever the rhs mathExpr matches, it runs code which pops the tokens off the stack and replaces them with a token representing the comparison)

I have several projects which depend on this code, which I wouldn’t be able to do without custom operators (and postfix operators make it a lot closer to the standard PEG notation)

Please don’t remove custom postfix operators.

Thanks,
Jon

On Dec 5, 2015, at 11:26 AM, David Zarzycki via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hi Chris,

An observation about SE-0004: Remove the ++ and — operators:

Given that the above is accepted, the only remaining postfix operator in the language is ‘!’ — and that is implemented by the compiler. Please consider just removing user-defined postfix operators entirely. Doing so would define away a type checking ambiguity where “let f : T -> T = someOperatorIdentifier” is ambiguous when both prefix and postfix operators exist.

Cheers, Dave _____________________________________________ swift-evolution mailing list swift-evolution@swift.org <mailto:swift-evolution@swift.org> https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris Lattner) #4

Ok, we can consider this when work on the Spring 2017 release is active.

-Chris

···

On Dec 6, 2015, at 6:22 AM, David Zarzycki <zarzycki@icloud.com> wrote:

That is definitely an interesting idea. In practice, we won’t be able to remove ++/— from the compiler until the ~Spring 2017 release, since Swift 3 will want to parse the old code and reject it with a fixit hint.

Doing so would define away a type checking ambiguity where “let f = T -> T = someOperatorIdentifier” is ambiguous when both prefix and postfix operators exist.

Besides the general simplification potential for the language, is this a theoretical concern or an actual one? You can currently do something like “let f = T->T = {$0^}” or “{^$0}” to disambiguate the prefix/postfix forms.

It is just simplification that opens the door to further simplicity and self-consistency within the language. In addition to not needing the above workaround, one could remove the fixity keywords/attributes altogether, because they’d be inferable from context.

If one wants to go deep down the rabbit hole, one could let developers avoid nested parenthesis and the “spiral call syntax problem” by allowing the language to use the same unary operator in either prefix or postfix positions. For example, instead of “(^(-(~x).a).b).c”, one could write “x~.a-.b^.c” to accomplish the same goal.