> This means that the ChildGuardianship enum is no longer a real value type 
> with value semantics but a value type with partial reference semantics.

That's already true of any enum that has an associated reference type.


> On May 6, 2016, at 10:26 AM, Michael Peternell <[email protected]> 
> wrote:
> 
> 
>> 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