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