If you have an Array which is declared as mutable variable all contents are implicitly mutable. This is unfortunate especially in case of value types.
Consider this code example:
struct Person { var name: String }
var array = [Person(name: "Smith")]
// all persons are implicitly mutable
array[0].name = "Sam"
So I propose a language feature which addresses this issue:
var array: [let Person] = [Person(name: "Smith")]
// all persons are immutable
array[0].name = "Sam" // error
// but still allowing to add and remove persons
array[0] = Person(name: "Sam")
For clarification: The semantics are the same as if you've wrapped the struct in a class with a "let" property:
class ConstantWrapper<T> {
let value: T
init(_ value: T) { self.value = value }
}
var array = [ConstantWrapper(Person(name: "Smith"))]
// all persons are "indirect" immutable
array[0].value.name = "Sam" // error
This model would allow for more immutability in mutable contexts which ultimately leads to less bugs.
##Possible Extensions:
We could also allow a "var" declaration:
let array: [var Person] = ...
The array models a fixed length array which is highly suggested by some people but you cannot assign a new "Person" to a specific index which is unfortunate. Although this could be solved by tweaking the current model.
This model would allow for more immutability in mutable contexts which ultimately leads to less bugs.
What bugs does this prevent? If the array is mutable, that means you can replace any element in it with another element, which in a value type is exactly equivalent to changing the existing value's properties.
This wouldn't change anything with value types. Even if you're not allowed to say:
array[0].name = "Sam"
You can still say:
array[0] = Person(name: "Sam")
which is equivalent; you're just making it less convenient and harder to optimize. Piecewise mutation of value types is a feature, not a bug, and doesn't have most of the pitfalls of shared mutable reference types.
-Joe
···
On Jan 30, 2016, at 7:27 AM, Maximilian Hünenberger via swift-evolution <swift-evolution@swift.org> wrote:
Hi all,
If you have an Array which is declared as mutable variable all contents are implicitly mutable. This is unfortunate especially in case of value types.
Consider this code example:
struct Person { var name: String }
var array = [Person(name: "Smith")]
// all persons are implicitly mutable
array[0].name = "Sam"
So I propose a language feature which addresses this issue:
var array: [let Person] = [Person(name: "Smith")]
// all persons are immutable
array[0].name = "Sam" // error
// but still allowing to add and remove persons
array[0] = Person(name: "Sam")
For clarification: The semantics are the same as if you've wrapped the struct in a class with a "let" property:
class ConstantWrapper<T> {
let value: T
init(_ value: T) { self.value = value }
}
var array = [ConstantWrapper(Person(name: "Smith"))]
// all persons are "indirect" immutable
array[0].value.name = "Sam" // error
This model would allow for more immutability in mutable contexts which ultimately leads to less bugs.
##Possible Extensions:
We could also allow a "var" declaration:
let array: [var Person] = ...
The array models a fixed length array which is highly suggested by some people but you cannot assign a new "Person" to a specific index which is unfortunate. Although this could be solved by tweaking the current model.
Oh ok I see. I'm sorry to hold you off more important topics.
- Maximilian
···
Am 30.01.2016 um 19:21 schrieb Joe Groff <jgroff@apple.com>:
This wouldn't change anything with value types. Even if you're not allowed to say:
array[0].name = "Sam"
You can still say:
array[0] = Person(name: "Sam")
which is equivalent; you're just making it less convenient and harder to optimize. Piecewise mutation of value types is a feature, not a bug, and doesn't have most of the pitfalls of shared mutable reference types.
-Joe
On Jan 30, 2016, at 7:27 AM, Maximilian Hünenberger via swift-evolution <swift-evolution@swift.org> wrote:
Hi all,
If you have an Array which is declared as mutable variable all contents are implicitly mutable. This is unfortunate especially in case of value types.
Consider this code example:
struct Person { var name: String }
var array = [Person(name: "Smith")]
// all persons are implicitly mutable
array[0].name = "Sam"
So I propose a language feature which addresses this issue:
var array: [let Person] = [Person(name: "Smith")]
// all persons are immutable
array[0].name = "Sam" // error
// but still allowing to add and remove persons
array[0] = Person(name: "Sam")
For clarification: The semantics are the same as if you've wrapped the struct in a class with a "let" property:
class ConstantWrapper<T> {
let value: T
init(_ value: T) { self.value = value }
}
var array = [ConstantWrapper(Person(name: "Smith"))]
// all persons are "indirect" immutable
array[0].value.name = "Sam" // error
This model would allow for more immutability in mutable contexts which ultimately leads to less bugs.
##Possible Extensions:
We could also allow a "var" declaration:
let array: [var Person] = ...
The array models a fixed length array which is highly suggested by some people but you cannot assign a new "Person" to a specific index which is unfortunate. Although this could be solved by tweaking the current model.