Problems with generics - should be fixed for Xcode 9?

Greetings

Old chestnut, sort of partially solved but still problems.

Now we can nest types in generic types, what I want is :

class Event<typeT>
{
  class Args
  {
    public static let empty = Args() // error : Static stored properties not supported in generic types
  }
}

But the static let is not directly in the generic class.

So, I end up doing another convoluted workaround in the shape of :

class Event<typeT>
{
  class Args
  {
    public static var empty: Args
    {
      return Args()
    }
  }
}

The main difference is that I have to create a new instance on every call to Args.empty instead of returning the same one.

Is this an oversight or as intended, with the hope of fixing it in a future version

Joanna

···

--
Joanna Carter
Carter Consulting

I always thought that this was a bug, but I can't find it on bugs.swift.org, so I'd love to know if it's meant to stay this way or not.

···

Le 16 sept. 2017 à 06:32, Joanna Carter via swift-evolution <swift-evolution@swift.org> a écrit :

Greetings

Old chestnut, sort of partially solved but still problems.

Now we can nest types in generic types, what I want is :

class Event<typeT>
{
class Args
{
   public static let empty = Args() // error : Static stored properties not supported in generic types
}
}

But the static let is not directly in the generic class.

So, I end up doing another convoluted workaround in the shape of :

class Event<typeT>
{
class Args
{
   public static var empty: Args
   {
     return Args()
   }
}
}

The main difference is that I have to create a new instance on every call to Args.empty instead of returning the same one.

Is this an oversight or as intended, with the hope of fixing it in a future version

Joanna

--
Joanna Carter
Carter Consulting

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Greetings

Old chestnut, sort of partially solved but still problems.

Now we can nest types in generic types, what I want is :

class Event<typeT>
{
class Args
{
   public static let empty = Args() // error : Static stored properties not supported in generic types
}
}

But the static let is not directly in the generic class.

It's still generic, though, because of the outer generic class, so there is a different static var for each specialization. For example, the following assert would fail:

  assert(Event<Int>.Args.empty === Event<String>.Args.empty)

So, I end up doing another convoluted workaround in the shape of :

class Event<typeT>
{
class Args
{
   public static var empty: Args
   {
     return Args()
   }
}
}

The main difference is that I have to create a new instance on every call to Args.empty instead of returning the same one.

Is this an oversight or as intended, with the hope of fixing it in a future version

I'd say we consider it a bug.

  - Doug

···

Sent from my iPhone

On Sep 16, 2017, at 6:32 AM, Joanna Carter via swift-evolution <swift-evolution@swift.org> wrote:

Joanna

--
Joanna Carter
Carter Consulting

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

1 Like

This IMHO isn't a bug as the behavior is not completely defined. Joanna mentioned that Args is not generic, but it actually is, once you address it from global namespace - as it inherits the T type (while not used anywhere):

NSStringFromClass(Event<NSString>.Args.self)
NSStringFromClass(Event<NSDate>.Args.self)

-->

_TtGCC14__lldb_expr_375Event4ArgsCSo8NSString__
_TtGCC14__lldb_expr_375Event4ArgsCSo6NSDate__

Which is the root of the problem - you are currently not actually using the same class under different event types. It then makes a static property an issue as you are not able to distinguish these two scenarios with current language:

- is the stored property the same for all variations of the Args class?
- or does each type has its own stored property?

I can think of cases for both. And this is (from what I understood is the core of the problem).

@Joanna - in this particular case, I don't see the benefit of Args.empty over Args() as you currently create a new instance all the time. If the arguments are not intended to be generic, much better solution is to do something like:

class EventArgs {
  public static let empty = Args()
}

class Event<T> {
  typealias Args = EventArgs
}

···

On Sep 17, 2017, at 11:59 PM, Félix Cloutier via swift-evolution <swift-evolution@swift.org> wrote:

I always thought that this was a bug, but I can't find it on bugs.swift.org, so I'd love to know if it's meant to stay this way or not.

Le 16 sept. 2017 à 06:32, Joanna Carter via swift-evolution <swift-evolution@swift.org> a écrit :

Greetings

Old chestnut, sort of partially solved but still problems.

Now we can nest types in generic types, what I want is :

class Event<typeT>
{
class Args
{
  public static let empty = Args() // error : Static stored properties not supported in generic types
}
}

But the static let is not directly in the generic class.

So, I end up doing another convoluted workaround in the shape of :

class Event<typeT>
{
class Args
{
  public static var empty: Args
  {
    return Args()
  }
}
}

The main difference is that I have to create a new instance on every call to Args.empty instead of returning the same one.

Is this an oversight or as intended, with the hope of fixing it in a future version

Joanna

--
Joanna Carter
Carter Consulting

_______________________________________________
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

Finally resolved this issue to my satisfaction :

public class EventArgs
{
  public static let empty = EventArgs()
}


public class PropertyChangedEvent : Event<Any, PropertyChangedEvent.Args>
{
  public class Args : EventArgs
  {
    public static let allProperties = PropertyChangedEvent.Args()
    
    public let propertyName: String?
    
    public init(_ propertyName: String? = nil)
    {
      self.propertyName = propertyName
    }
  }
}