# Precedencegroup's assignment

when it set true or false, what is the difference of precedence? write a demo to descripte it

``````infix operator +-: AdditionPrecedence
precedencegroup myPrecedence {
lowerThan: MultiplicationPrecedence
assignment:false // I don't find the difference of true and false
associativity: left
}

struct Vector2D {
var x = 0.0, y = 0.0
}

extension Vector2D {
static func +- (left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y - right.y)
}
}

let firstVector:Vector2D? = Vector2D(x: 1, y: 2)
let secondVector =  Vector2D(x: 3, y: 4)
let plusMinus = firstVector! +- secondVector // the assignment doesn't affect the ! likely

``````

The meaning and effect of â€śassignmentâ€ť in precedence groups was explained in the core teamâ€™s decision notes when they returned the first version of SE-0077 â€śImproved operator declarationsâ€ť for revision:

This proposal quietly drops the assignment modifier that exists on operators today. This modifier had one important functionâ€“an operator marked assignment gets folded into an optional chain, allowing foo?.bar += 2 to work as foo?(.bar += 2) instead of failing to type-check as (foo?.bar) += 2. In practice, all Swift operators currently marked assignment are at the equivalent of the Assignment precedence level, so the core team recommends making this optional chaining interaction a special feature of the Assignment precedence group.

I changed the demo above to below, it doesn't work

``````infix operator +-=: AdditionPrecedence
precedencegroup myPrecedence {
lowerThan: MultiplicationPrecedence
assignment:true
associativity: left
}

struct Vector2D {
var x:Double = 0.0, y:Double = 0.0
}

extension Double {
static func +-= (left: inout Double, right: Double) {
left = left + right / 2
}
}

var firstVector:Vector2D? = Vector2D(x: 1, y: 2)
let secondVector =  Vector2D(x: 3, y: 4)
firstVector?y +-= 3 // Error: '?' must be followed by a call, member lookup, or subscript

``````

Is that supposed to be `.y` at the end of your chain? Because the error is just pointing out that it isnâ€™t.

1 Like

oh, It was a stupid mistakeâ€¦â€¦
It should be like below:

``````infix operator +-=: AdditionPrecedence
precedencegroup myPrecedence {
lowerThan: MultiplicationPrecedence
assignment:true
associativity: left
}

struct Vector2D {
var x:Double = 0.0, y:Double = 0.0
}

extension Double {
static func +-= (left: inout Double, right: Double) {
left = left + right / 2
}
}

var firstVector:Vector2D? = Vector2D(x: 1, y: 2)
let secondVector =  Vector2D(x: 3, y: 4)
firstVector?.y +-= 3 // It should be like @Nevin says that  ` foo?(.bar += 2) `, but it doesn't
``````

`?` is not a binary operator; it doesn't interact with precedence that way. `?` is a postfix unary operator (except when forming part of the ternary `? :` operator), and unary operators always parse inside of binary operators.

You gave your custom operator `AdditionPrecedence`, which has `assignment: false`.

1 Like

the right answer is that as below:

``````infix operator +-=: myPrecedence
precedencegroup myPrecedence {
lowerThan: MultiplicationPrecedence
assignment:true
associativity: left
}

struct Vector2D {
var x:Double = 0.0, y:Double = 0.0
}

extension Double {
static func +-= (left: inout Double, right: Double) {
left = left + right / 2
}
}

var firstVector:Vector2D? = Vector2D(x: 1, y: 2)
let secondVector =  Vector2D(x: 3, y: 4)
firstVector?.y +-= 3
``````

or like that

``````infix operator +-=: myPrecedence
precedencegroup myPrecedence {
lowerThan: MultiplicationPrecedence
assignment:true
associativity: left
}

struct Vector2D {
var x:Double = 0.0, y:Double = 0.0
}

extension Vector2D {
static func +-= (left: inout Vector2D, right: Vector2D) {
left = Vector2D(x: left.x + right.x, y: left.y - right.y)
}
}

var firstVector:Vector2D? = nil
let secondVector =  Vector2D(x: 3, y: 4)
firstVector? +-= secondVector // I can't believe it works,amazing

``````
1 Like