Joe-
I hadn't seen that proposal; it would make sense to harmonize with enum cases.
Instead of the trailing "behavior unowned" syntax, perhaps your proposed
bracket syntax could be used:
enum ChildGuardianship {
case [unowned] ChildOf(Parent)
case [indirect] GrandChildOf(ChildGuardianship)
case [weak] WardOf(State?)
}
Or maybe inline with the :
enum ChildGuardianship {
case ChildOf([unowned] Parent)
case GrandChildOf([indirect] ChildGuardianship)
case WardOf([weak] State?)
case SharedCustodyOf([unowned] parent: Parent, [indirect] guardian:
ChildGuardianship, [weak] ward: State?)
}
If that is amenable, how would one go about proposing it as an amendment to
#0030?
-Marc
> On May 6, 2016, at 11:47 AM, Joe Groff <[email protected]> wrote:
>
> Another way to address this might be by allowing property behaviors, a
> feature proposed in
> https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md
> to allow for factoring out property implementations, could also apply to
> `case` declarations. "Weak" and "unowned" could be considered to be property
> behaviors once we have them, so you'd write something like:
>
> class Foo {
> var parent: Foo?
> behavior weak
> }
>
> to define a property with "weak" behavior. We could potentially allow you to
> apply behaviors to 'case' associated values too:
>
> enum ParentChild {
> case Parent(Parent) behavior unowned
> case Child(Parent) behavior unowned
> }
>
> -Joe
>
>> On May 3, 2016, at 8:07 AM, Marc Prud'hommeaux via swift-evolution
>> <[email protected]> wrote:
>>
>>
>> The following code currently has a retain cycle and memory leak:
>>
>> enum ParentChild {
>> case SonOf(Parent)
>> case DaughterOf(Parent)
>> }
>>
>> class Parent {
>> lazy var son: Child = Child(parentChild: .SonOf(self))
>> lazy var daughter: Child = Child(parentChild: .DaughterOf(self))
>> deinit { print("deinit Parent") }
>> }
>>
>> class Child {
>> var parentChild: ParentChild
>> init(parentChild: ParentChild) {
>> self.parentChild = parentChild
>> }
>> deinit { print("deinit Child") }
>> }
>>
>>
>> do {
>> let parent = Parent()
>> parent.son
>> parent.daughter
>> }
>>
>>
>> Child.parentChild cannot be declared unowned because ParentChild is a value
>> type. I propose adding the ability to declare the reference storage class
>> for an enum's associated value, like so:
>>
>> enum ParentChild {
>> case SonOf(unowned Parent)
>> case DaughterOf(unowned Parent)
>> }
>>
>> The only current alternative is to have some intermediate reference type
>> that itself holds the reference, akin to the old "Box" type that we used to
>> use to work around enum limitations. E.g., this is our current cumbersome
>> work-around:
>>
>> /// An unowned reference to a value, which is useful for maintaining
>> parent-child relations through value types like enums
>> public struct UnownedRef<T: AnyObject> {
>> public unowned let value: T
>> public init(_ value: T) { self.value = value }
>> }
>>
>> enum ParentChild {
>> case SonOf(UnownedRef<Parent>)
>> case DaughterOf(UnownedRef<Parent>)
>> }
>>
>>
>> class Parent {
>> lazy var son: Child = Child(parentChild: .SonOf(UnownedRef(self)))
>> lazy var daughter: Child = Child(parentChild:
>> .DaughterOf(UnownedRef(self)))
>> deinit { print("deinit Foo") }
>> }
>>
>> class Child {
>> var parentChild: ParentChild
>> init(parentChild: ParentChild) {
>> self.parentChild = parentChild
>> }
>>
>> deinit { print("deinit Child") }
>> }
>>
>> The storage type of an enum would, of course, be limited to reference types,
>> and when the storage class is weak, it would require that the stored type be
>> Optional, just like when declaring a weak variable.
>>
>> What do people think?
>>
>> -Marc
>>
>> _______________________________________________
>> 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