> On 11 Oct 2016, at 12:59, Jay Abbott <j...@abbott.me.uk> wrote:
> 
> This is interesting. I'm trying to evaluate your statement that "No setter 
> would be needed if a mutation clause is provided" but I can't think exactly 
> what the compiler would do in the case where there is a 'get' and 'mutate', 
> but no 'set'...
> a) when you call a non-mutating function;

This would just call the getter and call the function on the result, exactly 
how it works right now.

> b) when you assign a new value.

A setter would be a special case of a “mutator”, where the starting value of 
the inout parameter is ignored. So the mutate clause would be invoked with `{ 
(x: inout T) in x = newValue }`. Does that make sense?

> c) when get and set aren't implemented with a matching hidden var (i.e. using 
> a bit in an int var or storing in a dictionary).

I’m not sure what you mean by this. The getter and setter are implemented, but 
the mutator isn’t? Could you clarify?

> 
> 
> On Tue, 11 Oct 2016 at 11:26 Tim Vermeulen via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> Just having getters and setters doesn’t allow this (unless the optimiser is 
> really smart about it). All the current API allows is grabbing whatever the 
> `get` clause returns, mutating it, and then passing it into the `set` clause, 
> whatever that does. The `set` clause might not do anything, or what it does 
> could be seemingly unrelated to the `get` clause, so it’s not a trivial task 
> to optimise this.
> 
>> On 11 Oct 2016, at 06:35, Erica Sadun <er...@ericasadun.com 
>> <mailto:er...@ericasadun.com>> wrote:
>> 
>> 
>>> On Oct 10, 2016, at 9:53 PM, Tim Vermeulen via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@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
>> 
>> 
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to