There have been many instances where unexpected bad performance was caused by
the interplay between getters, setters, mutations and the copy-on-write
mechanism. For example:
struct Foo {
private var _array: [Int] = [1, 2, 3, 4, 5]
var array: [Int] {
get { return _array }
set { _array = newValue }
}
}
var foo = Foo()
foo.array.append(6) // an O(n) operation
I propose a `mutate` clause which provides a `mutate` function with a single
inout parameter (similar to how `set` provides `newValue`), which can be used
instead of a setter:
var array: [Int] {
get { return _array }
mutate { mutate(&_array) }
}
The compiler could then translate each mutation of `foo.array` to a closure
with an inout parameter, which is then passed into the `mutate` clause (which
in turn is executed with `_array` as its argument, as per the snippet above).
For example, for `foo.array.append(6)`, the compiler would internally generate
the closure `{ (arr: inout [Int]) in arr.append(6) }` and pass it into the
`mutate` clause, `_array` is then passed as its parameter and the array is
updated in constant time.
I apologise if that was too hard to follow.
No setter would be needed if a mutation clause is provided, but I see no good
reason to do away with setters altogether, so this proposal would be purely
additive.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution