Re: [swift-users] Workaround for generics not currently supporting conditional conformance to a protocol

2016-11-16 Thread David Sweeris via swift-users

> On Nov 16, 2016, at 16:35, Jordan Rose  wrote:
> 
> 
>>> On Nov 16, 2016, at 7:35, David Sweeris via swift-users 
>>>  wrote:
>>> 
>>> 
>>> On Nov 15, 2016, at 11:55 PM, Howard Lovatt  wrote:
>>> 
>>> @Dave,
>>> 
>>> How do I write that though.
>>> 
>>> I can't write:
>>> 
>>> extension Array: Equatable {
>>> static func ==(lhs: Array, rhs: Array) -> Bool {
>>> let size = lhs.count
>>> precondition(rhs.count == size, "The arrays must be the same 
>>> length")
>>> for i in 0 ..< size {
>>> if (lhs[i] as! Equatable) != (rhs[i] as! Equatable) {
>>> return false
>>> }
>>> }
>>> return true
>>> }
>>> }
>>> 
>>> Because I can't cast to an Equatable, because Equatable uses Self.
>>> 
>>> Am I missing something?
>>> 
>>>  -- Howard.
>>> 
>>>   -- Howard.
>>> 
 On 16 November 2016 at 16:35, David Sweeris  wrote:
 
 > On Nov 15, 2016, at 21:39, Howard Lovatt via swift-users 
 >  wrote:
 >
 > Hi All,
 >
 > Does anyone have a good workaround for generics not currently supporting 
 > conditional conformance to a protocol. As stated in the Generics 
 > Manifesto something like this would be nice:
 >
 >   extension Array: Equatable where Element: Equatable {
 > static func ==(lhs: Array, rhs: Array) -> Bool { ... }
 > }
 >
 > But I would currently write a wrapper, something like:
 >
 > struct ArrayE {
 > var elements: [T]
 > }
 > extension ArrayE: Equatable {
 > static func ==(lhs: ArrayE, rhs: ArrayE) -> Bool { ...  }
 > }
 >
 > This can get unwieldy when there are a lot of conditional protocol 
 > extensions required, i.e. wrappers round wrappers.
 >
 > Is there a better way?
 >
 > Thanks for any tips,
 >
 >   -- Howard.
 > ___
 > swift-users mailing list
 > swift-users@swift.org
 > https://lists.swift.org/mailman/listinfo/swift-users
 
 Can you make Array conform to Equatable for any T and then in the == 
 function, if T conforms to Equatable loop the Arrays to check if they're 
 equal, and if it doesn't conform just return false?
 
 I mean, it's still "wrong", but at least you won't get any false positives.
 
 - Dave Sweeris
>>> 
>> 
>> You are correct. The work-around is to use two extensions and overload the 
>> == operator:
>> 
>> extension Array: Equatable {
>> public static func == (lhs: Array, rhs: Array) -> Bool {
>> return false
>> }
>> }
>> extension Array where Element : Equatable {
>> public static func == (lhs: Array, rhs: Array) -> Bool {
>> return lhs.count == rhs.count && {
>> for i in 0..> if lhs[i] != rhs[i] {
>> return false
>> }
>> }
>> return true
>> }()
>> }
>> }
>> 
>> It works in playgrounds (Xcode 8.1 (8B62)), but I haven’t tested it outside 
>> a few trivial cases.
> 
> This does not work. The == dispatch for Arrays is static in this case, not 
> dynamic. You can test this by writing something generic on Equatable.
> 
> func same(_ x: T, _ y: T) -> Bool { return x == y }
> print(same([1], [2]))
> 
> Rule of thumb: overloads are resolved statically, protocol requirements are 
> invoked dynamically. You cannot get dynamic behavior out of just overloads, 
> ever.
> 
> I don't think there's a way to get this behavior today, unfortunately.

Aw, nuts! I forgot to try adding another level of, um... genericititty?

Yeah, I think you're right... On the plus side, when conditional conformance 
hits the wrapper structs can be backed out just by searching your project for 
their name and replacing it with "Array" (or "Set", etc), right?

- Dave Sweeris___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


Re: [swift-users] Workaround for generics not currently supporting conditional conformance to a protocol

2016-11-16 Thread Howard Lovatt via swift-users
Pity nothing else works, looks like I am stuck with multiple wrappers.

I will echo Dave's, Tim's, and Jordan's thoughts, roll on Conditional
Conformance.

Thanks for your help.

  -- Howard.

On 17 November 2016 at 09:35, Jordan Rose  wrote:

>
> On Nov 16, 2016, at 7:35, David Sweeris via swift-users <
> swift-users@swift.org> wrote:
>
>
> On Nov 15, 2016, at 11:55 PM, Howard Lovatt 
> wrote:
>
> @Dave,
>
> How do I write that though.
>
> I can't write:
>
> extension Array: Equatable {
> static func ==(lhs: Array, rhs: Array) -> Bool {
> let size = lhs.count
> precondition(rhs.count == size, "The arrays must be the same
> length")
> for i in 0 ..< size {
> if (lhs[i] as! Equatable) != (rhs[i] as! Equatable) {
> return false
> }
> }
> return true
> }
> }
>
> Because I can't cast to an Equatable, because Equatable uses Self.
>
> Am I missing something?
>
>  -- Howard.
>
>   -- Howard.
>
> On 16 November 2016 at 16:35, David Sweeris  wrote:
>
>>
>> > On Nov 15, 2016, at 21:39, Howard Lovatt via swift-users <
>> swift-users@swift.org> wrote:
>> >
>> > Hi All,
>> >
>> > Does anyone have a good workaround for generics not currently
>> supporting conditional conformance to a protocol. As stated in the Generics
>> Manifesto something like this would be nice:
>> >
>> >   extension Array: Equatable where Element: Equatable {
>> > static func ==(lhs: Array, rhs: Array) -> Bool { ... }
>> > }
>> >
>> > But I would currently write a wrapper, something like:
>> >
>> > struct ArrayE {
>> > var elements: [T]
>> > }
>> > extension ArrayE: Equatable {
>> > static func ==(lhs: ArrayE, rhs: ArrayE) -> Bool { ...  }
>> > }
>> >
>> > This can get unwieldy when there are a lot of conditional protocol
>> extensions required, i.e. wrappers round wrappers.
>> >
>> > Is there a better way?
>> >
>> > Thanks for any tips,
>> >
>> >   -- Howard.
>> > ___
>> > swift-users mailing list
>> > swift-users@swift.org
>> > https://lists.swift.org/mailman/listinfo/swift-users
>>
>> Can you make Array conform to Equatable for any T and then in the ==
>> function, if T conforms to Equatable loop the Arrays to check if they're
>> equal, and if it doesn't conform just return false?
>>
>> I mean, it's still "wrong", but at least you won't get any false
>> positives.
>>
>> - Dave Sweeris
>
>
>
> You are correct. The work-around is to use two extensions and overload the
> == operator:
>
> extension Array: Equatable {
> public static func == (lhs: Array, rhs: Array) -> Bool {
> return false
> }
> }
> extension Array where Element : Equatable {
> public static func == (lhs: Array, rhs: Array) -> Bool {
> return lhs.count == rhs.count && {
> for i in 0.. if lhs[i] != rhs[i] {
> return false
> }
> }
> return true
> }()
> }
> }
>
> It works in playgrounds (Xcode 8.1 (8B62)), but I haven’t tested it
> outside a few trivial cases.
>
>
> This does not work. The == dispatch for Arrays is static in this case, not
> dynamic. You can test this by writing something generic on Equatable.
>
> func same(_ x: T, _ y: T) -> Bool { return x == y }
> print(same([1], [2]))
>
>
> Rule of thumb: overloads are resolved statically, protocol requirements
> are invoked dynamically. You cannot get dynamic behavior out of just
> overloads, ever.
>
> I don't think there's a way to get this behavior today, unfortunately.
>
> Jordan
>
___
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


[swift-users] Workaround for generics not currently supporting conditional conformance to a protocol

2016-11-15 Thread Howard Lovatt via swift-users
Hi All,

Does anyone have a good workaround for generics not currently supporting
conditional conformance to a protocol. As stated in the Generics Manifesto
something like this would be nice:

  extension Array: Equatable where Element: Equatable {
static func ==(lhs: Array, rhs: Array) -> Bool { ... }
}

But I would currently write a wrapper, something like:

struct ArrayE {
var elements: [T]
}
extension ArrayE: Equatable {
static func ==(lhs: ArrayE, rhs: ArrayE) -> Bool { ...  }
}

This can get unwieldy when there are a lot of conditional protocol
extensions required, i.e. wrappers round wrappers.

Is there a better way?

Thanks for any tips,

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