[swift-evolution] PITCH: New :== operator for generic constraints

Vladimir.S svabox at gmail.com
Wed Aug 17 16:32:26 CDT 2016


On 17.08.2016 21:36, Charles Srstka wrote:
>> On Aug 17, 2016, at 12:02 PM, Vladimir.S via swift-evolution
>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> On 17.08.2016 13:00, Boris Wang via swift-evolution wrote:
>>> The problem is that:
>>> protocol should not be a type, but it is a type sometime and not type
>>> sometime now.
>>> for exam:
>>> P.Type not same as T.Type
>>> But you can declare a variable of type P.
>>> Protocol should be a contract only, no instances of it.
>> I'm also confused about this. Tried to follow the whole discussion of
>> experienced(as I understand) developer Charles and a member of core team,
>> and saw that even experienced developer had some troubles to understand
>> all the catches of protocols in Swift.
>> How we want to make less experienced developers to understand Swift's
>> model of protocols&conformance&generic&existentials&etc.. While problems
>> begins with the most used Equatable/Hashable protocols..
>> Also I believe the syntax of generic constraints in 'where' part is
>> confusing. I'm about this:
>> func pick<PepperType:Sequence>(peppers: PepperType) where
>> PepperType.Iterator.Element == Pepper
>> If '== Proto' means *exactly* typed as such protocol("let arr : [Proto] =
>> .."), so IMO ': Proto' should means *typed* as exactly this protocol or
>> any derived protocol("let arr : [ProtocolDerivedFromProto] = .."). Just
>> in symmetry with class types in 'where' clause here.
>> Currently, how to specify 'protocol Proto or its derived protocols" ?
> Basically, the issue is that as things currently stand, there is no way to
> specify that. Your options basically boil down to: 1) implement the method
> twice, 2) force the caller to cast to the protocol first, or 3) just use an
> array.

Yes, we can force the caller to cast to "array of the protocol" first, and 
this is probably the best workaround here(if we want to keep sequence in 
our function):

func pick<PepperType:Sequence>(peppers: PepperType) where 
PepperType.Iterator.Element == Pepper {...}

let peck: [Pepper] = [PepperClass(), PepperClass()]
pick(peppers: peck) // no need to cast

let pickled = [PickledPepper()]
pick(peppers: pickled as [Pepper]) // cast here

>> I suggest to discuss changing the rules for 'where' generic filter for
>> protocols:
>> 1. Don't allow syntax ': P' or '== P' for protocols. Such syntax should
>> be allowed only for classes, structs & other value types.
>> 2. For protocol introduce 'is P' syntax, which should mean 'typed exactly
>> as P, or its derived protocol, or as concrete type conformed to P'. I.e.:
>> func pick<PepperType:Sequence>(peppers: PepperType) where
>> PepperType.Iterator.Element is Pepper
>> 3. If it is hard to implement (2) today in the "right" way, implement it
>> with two copies of the same function, one with ":P" and one with
>> "==P"(was discussed earlier in thread)
> This looks identical to my pitch, only with the operator named “is” instead
> of “:==“. Unfortunately, we now have Word of God that the Swift team wants
> to avoid cloning functions à la C++ templates, so it may be a bit of a
> non-starter.

Well, yes, but also I believe we should disallow ': P' and '== P' syntax 
for protocols in 'where' for generic constants totally, as this syntax IMO 
is confusing for protocols and not in symmetry with what it means if class 
is specified as constraint instead of protocol.

I.e. if you want to specify a protocol in generic constants you can write 
only 'where T is P', which will mean "typed as P protocol, as derived from 
P protocol or as type conformed to protocol", I believe exactly this 
meaning is expected when one use protocol in constraints.

And about cloning the function. It is implementation detail and I believe 
core team can find better solution, but *at least* we see such naive 
implementation of this. So, probably, this could be done in such way and 
then later improved in right way with 'is P' syntax introduced.

> Charles

More information about the swift-evolution mailing list