Mutation is more or less modeled as reassignment in Swift, there is no 
difference between a variable that can be mutated and one that can be 
reassigned (right?). There are however differences between inout's real 
behaviour and what some might expect; some might expect that it is modified at 
the same time (and as many times) as if the function was inlined.

struct F {
    var a : Int {
        didSet {
            print("set \(a)")
        }
    }
}

func setTimes(a: inout Int, times: Int) {
    for _ in 1...times {
        a += 1
    }
}

var foo = F(a: 0)

// prints set 1 … set 10
for _ in 1...10 {
    foo.a += 1
}

setTimes(a: &foo.a, times: 10) // only prints set 20


However, your generalization is already possible, just change the function head 
to:

func foo<E:P>(_ p: inout E)

which, if we add a member to the protocol and something meaningful for the 
function to do becomes something like this:

protocol P { var a : Int {get set} }

func foo<E:P>(_ p: inout E) {
    p.a += 1
}

struct F : P { var a : Int }

var f = F(a: 0)

foo(&f)
print(f)

Was there some other problem you were trying to solve that can't be solved by 
doing this?

/Magnus

> 11 Dec. 2017 03:49 Adrian Zubarev via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> I see, that makes totally sense. I thought about `inout` only in terms of 
> mutation not reassignment from within the scope itself.
> 
> 
> Am 10. Dezember 2017 um 17:56:56, Jonathan Keller (jkeller...@icloud.com) 
> schrieb:
> 
>> No, inout should *not* be covariant, since foo can assign any subtype of P 
>> to its parameter, not just F:
>> 
>> protocol P {}
>> struct F: P {}
>> struct G: P {}
>> 
>> func foo(_ p: inout P) {
>>     p = G()
>> }
>> 
>> var f = F()
>> foo(&f) // assigns a value of type G to a variable of type F
>> 
>> From Jonathan
>> 
>> On Dec 10, 2017, at 12:51 AM, Adrian Zubarev via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>>> Hello Matthew, I have more more question about the generalized supertype 
>>> constraints. Does the generalization also covers inout? I found a really 
>>> annoying case with inout.
>>> 
>>> protocol P {}
>>> 
>>> func foo(_ p: inout P) {
>>>     print(p)
>>> }
>>> 
>>> struct F : P {}
>>> 
>>> var f = F()
>>> 
>>> foo(&f) // won't compile until we explicitly write `var f: P = F()`
>>> 
>>> Shouldn’t we allow inout to have subtypes as well, like inout F : inout P?
>>> 
>>> This is actually one of the pain points with the generic version of the 
>>> print function. We cannot pass an arbitrary TextOutputStream to it without 
>>> sacrificing the type. I doubt the generic print function is justified, 
>>> because TextOuputStream does not have associated types nor a Self 
>>> constraint. Furthermore it forces you to create a custom type-erased 
>>> wrapper that can hold an arbitrary TextOutputSteram.
>>> 
>>> If this is part of a totally different topic, I’ll move it in it’s own 
>>> thread.
>>> 
>>> 
>>> 
>>> Am 2. Dezember 2017 um 19:03:24, Matthew Johnson via swift-evolution 
>>> (swift-evolution@swift.org) schrieb:
>>> 
>>>> This thread received very light, but positive feedback.  I would really 
>>>> like to see this feature added and am willing to draft and official 
>>>> proposal but am not able to implement it.  If anyone is interested in 
>>>> collaborating just let me know.
>>>> 
>>>> 
>>>>> On Nov 24, 2017, at 5:03 PM, Matthew Johnson via swift-evolution 
>>>>> <swift-evolution@swift.org> wrote:
>>>>> 
>>>>> One of the most frequent frustrations I encounter when writing generic 
>>>>> code in Swift is the requirement that supertype constraints be concrete.  
>>>>> When I mentioned this on Twitter 
>>>>> (https://twitter.com/anandabits/status/929958479598534656) Doug Gregor 
>>>>> mentioned that this feature is smaller and mostly straightforward to 
>>>>> design and implement 
>>>>> (https://twitter.com/dgregor79/status/929975472779288576).
>>>>> 
>>>>> I currently have a PR open to add the high-level description of this 
>>>>> feature found below to the generics manifesto 
>>>>> (https://github.com/apple/swift/pull/13012):
>>>>> 
>>>>> Currently, supertype constraints may only be specified using a concrete 
>>>>> class or protocol type.  This prevents us from abstracting over the 
>>>>> supertype.
>>>>> 
>>>>> ```swift
>>>>> protocol P {
>>>>>   associatedtype Base
>>>>>   associatedtype Derived: Base
>>>>> }
>>>>> ```
>>>>> 
>>>>> In the above example `Base` may be any type.  `Derived` may be the same 
>>>>> as `Base` or may be _any_ subtype of `Base`.  All subtype relationships 
>>>>> supported by Swift should be supported in this context including, but not 
>>>>> limited to, classes and subclasses, existentials and conforming concrete 
>>>>> types or refining existentials, `T?` and  `T`, `((Base) -> Void)` and 
>>>>> `((Derived) -> Void)`, etc.
>>>>> 
>>>>> Generalized supertype constraints would be accepted in all syntactic 
>>>>> locations where generic constraints are accepted.
>>>>> 
>>>>> I would like to see generalized supertype constraints make it into Swift 
>>>>> 5 if possible.  I am not an implementer so I will not be able to bring a 
>>>>> proposal forward alone but am interested in collaborating with anyone 
>>>>> interested in working on implementation.
>>>>> 
>>>>> I am also interested in hearing general feedback on this feature from the 
>>>>> community at large.  Have you also found this limitation frustrating?  In 
>>>>> what contexts?  Does anyone have reservations about introducing this 
>>>>> capability?  If so, what are they?
>>>>> 
>>>>> Matthew
>>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution@swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> 
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> 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