[swift-evolution] [Pitch] Adding a `mutate` clause to computed properties and subscripts

Erica Sadun erica at ericasadun.com
Mon Oct 10 23:35:37 CDT 2016

> On Oct 10, 2016, at 9:53 PM, Tim Vermeulen via swift-evolution <swift-evolution at swift.org> wrote:
> 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.

If this is computationally better, why is it not the default behavior rather than an API change?

-- E

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161010/70744190/attachment.html>

More information about the swift-evolution mailing list