Thanks, I understand all what you said, but I still doubt if it's the right behavior. I think my confusion can be boiled down to a simple question: is it OK to modify a value in a non-mutating method in Swift? I thought it shouldn't, based on the following statement in SE-0176:
We should add a rule to Swift that two accesses to the same variable are not allowed to overlap unless both accesses are reads. By "variable", we mean any kind of mutable memory: global variables, local variables, class and struct properties, and so on.
but the examples show that it's OK and hence my confusion.
The above statement contains an important detail about the definition of the "variable" in the document. If I understand it correctly, it basically means memory location. I think that's the part that makes SE-1076 a bit hard to understand for app developers, because we don't deal with memory directly in Swift. Instead we deal with value copy when doing read-only access or "copy in, copy out" when doing write access. And it's a bit hard to determine which is considered as "accessing same memory location" and which isn't.
For example, I just need to modify my example a bit (not using closure) and it violates SE-0176 immediately:
struct Foo {
var x: Int = 0
- func modifyX(_ foo: inout Foo) {
+ mutating func modifyX(_ foo: inout Foo) {
foo.x = 1
print("In modifyX(): \(self.x)")
print("In modifyX(): \(foo.x)")
}
}
var foo = Foo()
foo.modifyX(&foo)
print("After modifyX(): \(foo.x)")
While I like SE-0176 (it's a good constraint helping to write robust code), it's an artificial constraint. I mean, if we wrote the same code in c it could work. Also, I guess the same code might work in earlier versions of Swift before SE-0176 was added. So, just because the example works doesn't necessarily mean it should. That's the reason I raised the question.
Background: why I try to understnad SE-0176
At first I tried to understand SE-0176 because I ran into compilation or runtime errors caused by it. I passed that stage soon, but I found another issue: I often misunderstood it. I thought some code were invalid but they weren't. Confusion like this makes it hard for me to program with value types because it's not clear what's allowed and what isn't. That's the reason why I started the thread.