Re: [swift-evolution] Binding generic types using a metatype parameter

2016-03-25 Thread Joe Groff via swift-evolution

> On Mar 25, 2016, at 12:39 PM, Joanna Carter  
> wrote:
> 
> 
>> You'd need to extend Int to conform to the protocol for the cast to succeed.
> 
> Ah, yes. And there lies the reason behind wanting to be able to extend Any - 
> avoiding having to extend every possible type likely to be used - mutter, 
> mutter ;-)
> 
> Is it worth putting i a formal proposal for the extension of Any, or has that 
> already been done?


You could. For this particular use case, though, I think we really just want a 
more direct way of using *.Type values as types themselves.

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


Re: [swift-evolution] Binding generic types using a metatype parameter

2016-03-25 Thread Joe Groff via swift-evolution

> On Mar 25, 2016, at 3:21 AM, Joanna Carter  
> wrote:
> 
>>> extension PropertyType
>>> {
>>> private static func create() -> Property
>>> {
>>>  typealias SelfType = Self
>>> 
>>>  return Property.init()
>>> }
>>> }
>> 
>> Oops, that's definitely a bug.
> 
> Excellent! I would also say that I have had a different error with…
> 
> private static func create() -> PropertyProtocol
> {
>   return Property() // without the explicit .init
>  ^ Non-associative operator is adjacent to operator of the 
> same precedence
>  ^ No'>' candidates produce the expected contextual result 
> type 'PropertyProtocol'
> }
> 
> So, it would seem that omitting the .init and using Self is interpreted 
> differently to using the .init and using Self. I'd hate you to solve one bug 
> just to find another for a very similar use case :-)
> 
>> Oops, my fault, this one is by design. Since we're calling through a dynamic 
>> type, our type system isn't able to express the result type 
>> `Property`, so we need to abstract it behind the PropertyProtocol.
> 
> Understood and somewhat expected. It's just that the error message is 
> somewhat distant from the error site and seemingly not connected.
> 
>>> Of course, after all this effort, I still have the problem of how to get 
>>> the Any.Type from the SubjectType property of a Mirror into a 
>>> PropertyType.Type.
>> 
>> That one's easy, at least—you can take `Any.Type` and use `as?` to cast it 
>> to `PropertyType.Type`.
> 
> You'd have thought so wouldn't you. But although this works fine…
> 
> let childMirror = Mirror(reflecting: child.value)
> 
> print(child.label, child.value, childMirror.subjectType)
> 
> let subjectType = childMirror.subjectType
> 
> print(subjectType)
> 
> if let propertyType = subjectType as? PropertyType.Type
> {
>   let property = PropertyFactory.createProperty(propertyType)
> 
>   print(property)
> }
> 
> … this doesn't…
> 
>   let intType: Any.Type = Int.self
> 
>   print(intType)
> 
>   if let propertyType = intType as? PropertyType.Type // this cast fails
>   {
> if var property = PropertyFactory.createProperty(propertyType) as? 
> Property
> {
>   property.value = 123
> 
>   print(property)
> }
>   }

You'd need to extend Int to conform to the protocol for the cast to succeed.

-Joe

>>> What would really make life easier here would be the ability to extend Any.
>>> 
>>> Any chance?
>> 
>> I think that'd be cool. Some people fear the power (and ensuing 
>> responsibility) that unleashes, though…
> 
> Of course there will always be abusers of power but, by not permitting it, 
> low level framework code becomes more difficult, onerous and obfuscated to 
> write. Framework writers have always had to bear far more responsibility - 
> think Cocoa ;-)
> 
> Joanna
> 
> --
> Joanna Carter
> Carter Consulting
> 

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


Re: [swift-evolution] Binding generic types using a metatype parameter

2016-03-25 Thread Joanna Carter via swift-evolution
>> extension PropertyType
>> {
>>  private static func create() -> Property
>>  {
>>typealias SelfType = Self
>> 
>>return Property.init()
>>  }
>> }
> 
> Oops, that's definitely a bug.

Excellent! I would also say that I have had a different error with…

  private static func create() -> PropertyProtocol
  {
return Property() // without the explicit .init
   ^ Non-associative operator is adjacent to operator of the 
same precedence
   ^ No'>' candidates produce the expected contextual result 
type 'PropertyProtocol'
  }

So, it would seem that omitting the .init and using Self is interpreted 
differently to using the .init and using Self. I'd hate you to solve one bug 
just to find another for a very similar use case :-)

> Oops, my fault, this one is by design. Since we're calling through a dynamic 
> type, our type system isn't able to express the result type 
> `Property`, so we need to abstract it behind the PropertyProtocol.

Understood and somewhat expected. It's just that the error message is somewhat 
distant from the error site and seemingly not connected.

>> Of course, after all this effort, I still have the problem of how to get the 
>> Any.Type from the SubjectType property of a Mirror into a PropertyType.Type.
> 
> That one's easy, at least—you can take `Any.Type` and use `as?` to cast it to 
> `PropertyType.Type`.

You'd have thought so wouldn't you. But although this works fine…

  let childMirror = Mirror(reflecting: child.value)
  
  print(child.label, child.value, childMirror.subjectType)
  
  let subjectType = childMirror.subjectType
  
  print(subjectType)
  
  if let propertyType = subjectType as? PropertyType.Type
  {
let property = PropertyFactory.createProperty(propertyType)

print(property)
  }

… this doesn't…

let intType: Any.Type = Int.self

print(intType)

if let propertyType = intType as? PropertyType.Type // this cast fails
{
  if var property = PropertyFactory.createProperty(propertyType) as? 
Property
  {
property.value = 123

print(property)
  }
}

>> What would really make life easier here would be the ability to extend Any.
>> 
>> Any chance?
> 
> I think that'd be cool. Some people fear the power (and ensuing 
> responsibility) that unleashes, though…

Of course there will always be abusers of power but, by not permitting it, low 
level framework code becomes more difficult, onerous and obfuscated to write. 
Framework writers have always had to bear far more responsibility - think Cocoa 
;-)

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-evolution] Binding generic types using a metatype parameter

2016-03-24 Thread Joe Groff via swift-evolution


> On Mar 24, 2016, at 4:04 PM, Joanna Carter  > wrote:
> 
> Unfortunately, this doesn't compile…
> 
> extension PropertyType
> {
>  private static func create() -> Property
>  {
>return Property.init()
>^ '>' is not a postfix unary operator
>  }
> }
> 
> Which is why I found it necessary to add a typealias like so…
> 
> extension PropertyType
> {
>  private static func create() -> Property
>  {
>typealias SelfType = Self
> 
>return Property.init()
>  }
> }

Oops, that's definitely a bug.

> This doesn't compile either…
> 
> struct PropertyFactory
> {
>  static func createBoundPropertywithValueType(valueType: PropertyType.Type) 
> -> PropertyProtocol
>  {
>return valueType.create()
>^ Member 'create' cannot be used on value of protocol type 
> 'PropertyType'; use a generic constraint instead
>  }
> }
> 
> For some reason, as soon as you change the PropertyType extension static func 
> to return PropertyProtocol…
> 
> extension PropertyType
> {
>  private static func create() -> PropertyProtocol
>  {
>typealias SelfType = Self
> 
>return Property.init()
>  }
> }
> 
> … then, and only then, the factory's method compiles correctly.

Oops, my fault, this one is by design. Since we're calling through a dynamic 
type, our type system isn't able to express the result type 
`Property`, so we need to abstract it behind the PropertyProtocol.

> Of course, after all this effort, I still have the problem of how to get the 
> Any.Type from the SubjectType property of a Mirror into a PropertyType.Type.

That one's easy, at least—you can take `Any.Type` and use `as?` to cast it to 
`PropertyType.Type`.

> What would really make life easier here would be the ability to extend Any.
> 
> Any chance?

I think that'd be cool. Some people fear the power (and ensuing responsibility) 
that unleashes, though…

-Joe

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


Re: [swift-evolution] Binding generic types using a metatype parameter

2016-03-24 Thread Joanna Carter via swift-evolution
Of course, after all this effort, I still have the problem of how to get the 
Any.Type from the SubjectType property of a Mirror into a PropertyType.Type.

What would really make life easier here would be the ability to extend Any.

Any chance?

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-evolution] Binding generic types using a metatype parameter

2016-03-24 Thread Joanna Carter via swift-evolution
I want to thank you for your "rubber duck" consultancy; I now have a working 
factory mechanism…

protocol PropertyFactory { }

extension PropertyFactory
{
  static func createProperty() -> PropertyProtocol
  {
typealias ValueType = Self

return Property()
  }
}

extension Int : PropertyFactory { }

The key was to typealias Self so that it could then be passed as a type 
parameter to the generic type.

The problem remains that it is still necessary to implement PropertyFactory on 
each and every type that is likely to be used for a property.

I would therefore ask if anything that would make life simpler in this regard 
is a worthwhile candidate for inclusion in the future of Swift?

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-evolution] Binding generic types using a metatype parameter

2016-03-24 Thread Joanna Carter via swift-evolution
Well, I've been playing some more and come up with an idea that seems to be 
thwarted by the compiler…

protocol PropertyFactory
{
  
}

extension PropertyFactory
{
  // what I'd like to do but that doesn't compile
  static func createProperty() -> PropertyProtocol
  {
return Property()
  }
  
// what it seems I have to do to satisfy the compiler
  static func createProperty(valueType: Any.Type) -> PropertyProtocol
  {
switch self // this is a really naff and limited workaround
{
  case is Int.Type:
return Property()
  // ...
  default: fatalError("Unexpected type \(self)")
}
  }
}

extension Int : PropertyFactory
{
  
}

// calling code works fine

let type: PropertyFactory.Type = Int.self

var property = type.createProperty(type) as? Property
  
property?.value = 123
  
print(property?.untypedValue)

… but it does mean that all possible types would have to be extended to 
implement PropertyFactory.

Does this make a case for either :

Extend the generic syntax to allow for something like

struct GenericStruct
{
  func doSomething()
  {
…
  }
}

… or having something like the following that knows how to bind a generic type 
to its parameter types …

protocol AnyGeneric // all generic types implement this protocol
{

}

extension AnyGeneric
{
  static func bindToParameterType(parameterType: Any.Type) -> Any.Type
  {
// return something akin to Self
  }
}

The more I think about it, the latter option seems slightly screwy but I 
include it as a discussion point.

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-evolution] Binding generic types using a metatype parameter

2016-03-23 Thread Joanna Carter via swift-evolution
Hi Joe

> 
> You can accomplish this with Swift today by casting your Any.Type to a 
> Protocol.Type that provides an initializer:
> 
> protocol Deserializable {
>  init(deserializedFrom stream: DeserializationStream)
> }
> 
> func deserializeValue(type type: Any.Type, from stream: 
> DeserializationStream) -> Any? {
>  if let deserializableType = type as? Deserializable.Type {
>return deserializableType.init(deserializedFrom: stream)
>  }
>  return nil
> }

Hmm… I've been playing with this for days now and, as useful as your code is 
for instantiating a given type, what I need to do is instantiate a generic 
type, bound to that given type.

Something along the lines of…

public protocol PropertyProtocol
{
  var untypedValue: Any? { get }
}

public struct Property
{
  public let info: PropertyInfo
  
  public var name: String
  {
return info.name
  }
  
  public var displayName: String
  {
return info.displayName
  }
  
  public var value: PropertyType?
  
  public init()
  {
self.init(propertyInfo: PropertyInfo(), value: nil)
  }
  
  init(propertyInfo: PropertyInfo, value: PropertyType?)
  {
self.value = value

self.info = propertyInfo;
  }
  
  init(propertyInfo: PropertyInfo)
  {
self.init(propertyInfo: propertyInfo, value: nil)
  }
  
  init(other: Property)
  {
self.init(propertyInfo: other.info, value: other.value)
  }
}

struct PropertyFactory
{
  static func createBoundPropertywithValueType(valueType: Any.Type) -> 
PropertyProtocol
  {
return Property.init()
  }
}

Of course, Ive still got a lot of C# cruft in my thinking so I am more than 
willing to admit I may not be approaching this in the right way ;-)

Joanna

--
Joanna Carter
Carter Consulting

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


Re: [swift-evolution] Binding generic types using a metatype parameter

2016-03-23 Thread Joanna Carter via swift-evolution
My apologies. I seem to have managed to get this subject as a reply to another. 
I'm not accustomed to mailing list forums. Could an admin move it if necessary?

Joanna

--
Joanna Carter
Carter Consulting

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