Inline
On 17.08.2016 21:36, Charles Srstka wrote:
On Aug 17, 2016, at 12:02 PM, Vladimir.S via swift-evolution
<[email protected] <mailto:[email protected]>> 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
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution