Custom assignment operator

Currently, swift's = operator does not return a value. This seems like a lapse to me, because, if it was othersise, then some usage in function builder would be simpler. But that's okay, since there is the ability to declare a custom one. Right?

infix operator <- : AssignmentPrecedence
@discardableResult
func <- <V>(storage: inout V, value: V) -> V { storage = value }

// I imagined using it like this
View {
     var someView <- SomeView { ... }
     AnotherView(someView.stuff) { ... }
}
// Notice that both views become exposed (returned)

But it produces a bunch of errors, from one suggesting that it is incorrectly used prefix unary func to the other saying to separate statements. All of this obviously indicates that I cannot properly work with lvalues. Can I?

That syntactic position cannot take an arbitrary operator. But more importantly, the operation done by var someView = expression is initialization, not assignment — so even if an arbitrary operator were allowed in that position, what you're trying to do wouldn't be allowed, because it's not okay to bind an inout parameter to an uninitialized variable.

It's also not clear why

var someView = ...
someView
AnotherView(someView.stuff)

or

var stuff = ...
SomeView(stuff) { ... }
AnotherView(stuff) { ... }

aren't both better solutions than introducing a new operator.

1 Like

To be able to reference objects by name in fb closure, rather than putting there ugly stuff, like a bunch of explicit returns. Currently, you have to ...

var view: some View {
     let b = B {}
     HStack {
         b
         A(b.dimensions ... ) { ... } //need to know b dimensions
     }
}

If I could make a custom assignment, then that would become

var view: some View {
     HStack {
         let b <- B { ... }
         A(b.dimensions ... ) { ... } //need to know b dimensions
     }
}

Nice and clean, which is the whole point of this function building stuff, no?


Why so? If there were such thing in swift as customizable assignment operator, then it would be not important if lvalue was initialized, because that what custom = would do.


There are much more applications to a custom assignment. What I have shown is the one among those missed opportunities for clean code simply because of yet another language limit.

What is point than to have a assignment field/property in precedence group declaration?


It can. I made the bad code. Apologise to all harmed.

Please don't tell me that it is there because swift cannot deterministically resolve operators based on argument mutability

infix operator => : DefaultPrecedence
func => <T>(lhs: T, rhs: (inout T) -> ()) -> T {
   var l = lhs
   rhs(&l)
   return l
}
func => <T>(lhs: inout T, rhs: (T) -> (T)) -> T {
   return rhs(lhs)
}
func => <T>(lhs: T, rhs: (T) -> (T)) -> T {
   return rhs(lhs)
}
var a = Int(0) => {
    $0 += 1
}
let a2 = a => { $0 + 1 }

Leads to Ambiguous use of operator '=>

The problem with accepting uninitialized value for inout argument is that the function can READ inout arguments. The function signature says nothing about only writing to the said inout variable.

Mostly because, while being special, = is still an operator. It still needs to interact with other operators when parsing. Also, = is not the only operators of this class, *= and -= are normal operators that have AssignmentPrecedence.

1 Like

It is to make assignment operators work “inside” of optional chaining:

var dictionary = ["cat": 1]
dictionary["cat"]? += 2
dictionary["dog"]? += 2
print(dictionary)  // ["cat": 3]
2 Likes

It could be made such that operators with assignment wouldn't be able to read the value. Problem solved?

It might be better to propose implementing an out parameter which could take uninitialised variables. This could be somewhat useful in other situations like factoring out parts of initialisers. I'm not sure it's useful enough to be implemented, because it's not commonly needed and you can always just return the values instead and move the variables to the LHS, but it would be better than making a weird special case.