> Am 06.05.2016 um 14:08 schrieb Marc Prud'hommeaux <[email protected]>:
> 
> 
>> I wonder if there is a practical use-case for this.. Is there? Just 
>> curious...
> 
> Without getting too deep into the weeds of our specific data modal, I'll 
> summarize with "yes". If you need to mix classes with enums and don't have 
> the ability to declare the storage class of the variables, then reference 
> cycles can only be avoided by shimming in some other type that does permit 
> the declaration of the storage type. I would be surprised if I was the only 
> person to encounter this issue; anyone else?
> 
> It is analogous to the hoops you would need to jump through to define a 
> recursive enum before the "indirect" keyword. As a matter of fact, it is so 
> similar to that case that I wonder if it would make sense to have 
> weak/unowned keywords be before the case name, as with indirect. E.g.:
> 
> enum ChildGuardianship {
>    unowned case ChildOf(Parent)
>    indirect case GrandChildOf(ChildGuardianship)
>    weak case WardOf(State?)
> }

sorry, that doesn't really convince me. I don't consider a "ChildGuardianship" 
enum a practical use-case. The same for "child", "parent", "daughterOf", 
"sonOf", etc. Or were you programming a kindergarten application to help the 
kindergarten teachers to bill the parents correctly?

The obvious problem with a storage class in value types is that weak references 
are by definition mutable: they zero out as soon as the pointee starts 
deallocating. This means that the ChildGuardianship enum is no longer a real 
value type with value semantics but a value type with partial reference 
semantics.

I'm sure there is a practical use-case for this somewhere, but I doubt that it 
would be generally useful enough to be included into Swift at the language 
level.

-Michael

> 
> The obvious limitation of this would be that all associated types would be 
> pegged to the same storage class, preventing the ability of having one 
> associated type be weak and another be unowned. This limitation of indirect 
> was mentioned at 
> https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20151207/000312.html 
> , but it doesn't seem to have been given much treatment since.
> 
>       -Marc
> 
> 
>> On May 4, 2016, at 12:25 PM, Michael Peternell <[email protected]> 
>> wrote:
>> 
>> I wonder if there is a practical use-case for this.. Is there? Just 
>> curious...
>> 
>> -Michael
>> 
>>> Am 03.05.2016 um 17:07 schrieb Marc Prud'hommeaux via swift-evolution 
>>> <[email protected]>:
>>> 
>>> 
>>> 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

Reply via email to