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
> <[email protected]> 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 ([email protected])
> 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
>> <[email protected]> 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
>>> ([email protected]) 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
>>>>> <[email protected]> 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
>>>>> [email protected]
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> [email protected]
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected]
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution