Re: [swift-evolution] namespacing protocols to other types

2017-12-29 Thread Kelvin Ma via swift-evolution
On Fri, Dec 29, 2017 at 11:20 PM, Eneko Alonso 
wrote:

> Modules do more than that. For instance, if two imported modules provide a
> type with the same name, you can distinguish (name-spacing) them by using
> ModuleA.Thing vs ModuleB.Thing.
>
> In regards of Modules being intended to be shipped separately, that is
> incorrect. You might be thinking of packages.
>

> In Swift 4, a package can contain multiple binaries, including executables
> and libraries. These, can be composed of one or many modules.
>
> Swift Package Manager handles this really well, and allows to organize the
> code separating it by features or concerns.
>

the Swift language itself has no concept of packages. packages are a thing
that the SPM creates and manages and downloads for you. the modules inside
a package actually have internal dependencies between each other which is
why you have to write them all out in Package.swift. but you can distribute
a package with modues that are decoupled from one another and another app
or library can import that one module and not all the others (though the
SPM will still download all of them for some reason.)


>
> I understand Xcode does not have very good support for modules yet, other
> than importing frameworks. But it is my understanding this is something the
> new Xcode’s build system will solve, hopefully by Xcode 10.
>
> I’m not against nesting protocol definitions, I can see a few cases where
> it could be nice to have them. But in regards of namespacing, I think using
> nested types is the wrong direction.
>

the Swift standard library (the actual stdlib not Foundation) actually uses
this system like Unicode
 and CommandLine
.


>
> Thank you,
> Eneko Alonso
>
> On Dec 29, 2017, at 19:00, Kelvin Ma  wrote:
>
> Modules in Swift are really designed for code that is intended to be
> shipped separately. as Jon found out modules are pretty heavyweight and
> introduce a lot of unwanted abstraction and complexity when all you want to
> do is write things in a namespace. (Also if you forgot, importing a module
> in Swift dumps all of its symbols into the global namespace so
> Module.Thing is really meaningless.) sometimes this is a good thing
> because no one wants to be writing Glibc.fopen over and over especially
> when you have to #if #endif it out every time with Darwin.fopen if you
> want your library to run on OSX but this feature also makes modules
> ineffective as a namespacing scheme.
>
> On Fri, Dec 29, 2017 at 8:35 PM, Eneko Alonso 
> wrote:
>
>> …all i wanted to do was write Thing:Namespace.Protocol
>>
>>
>> Have you thought of using Swift modules for that? Maybe that would be a
>> better approach than trying to name-space within a module?
>>
>> Regards,
>> Eneko Alonso
>>
>> On Dec 29, 2017, at 16:51, Kelvin Ma via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> …all i wanted to do was write Thing:Namespace.Protocol
>>
>> On Thu, Dec 28, 2017 at 4:43 PM, Adrian Zubarev via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> Well again I don’t think we should disallow capturing the outer generic
>>> type parameter just because you cannot use the protocol inside the outer
>>> type atm., you still can add a type-eraser. To be honest such usage of the
>>> existential is not even a requirement for the outer type. On there other
>>> hand we might want to set the default for the associated type like I showed
>>> in my previous message. The nested protocol could serve a completely
>>> different purpose. Furthermore I still think that Generic.P and
>>> Generic.P should be distinct protocols just like nested generic and
>>> non-generic types are within an outer generic type. Sure there could be
>>> other problems with ambiguity if you think of something like
>>> GenericViewController.Delegate, but the disambiguation when
>>> conforming to such protocols requires a different solution and is a well
>>> known limitation today.
>>>
>>> That said you won’t design such nested types anyways if you know the
>>> existing language limitation. I’d say let’s keep it simple in theory and
>>> just align the nesting behaviour.
>>>
>>> About existentials:
>>>
>>> For that scenario I can only speak for myself. I wouldn’t want to allow
>>> directly the where clause existentials like this. It is far better and
>>> more readable when we force the where clause on typealiases instead. We
>>> could lift that restriction later if we’d like to, but not the other way
>>> around. I think it’s okay if we start with a small restriction first and
>>> see if it adopts well (this is MHO), because this way it shouldn’t harm
>>> anybody.
>>>
>>>
>>>
>>>
>>> Am 28. Dezember 2017 um 21:51:29, Karl Wagner (razie...@gmail.com)
>>> schrieb:
>>>
>>>
>>>
>>> On 28. Dec 2017, at 12:34, Adrian Zubarev 

Re: [swift-evolution] namespacing protocols to other types

2017-12-29 Thread Eneko Alonso via swift-evolution
Modules do more than that. For instance, if two imported modules provide a type 
with the same name, you can distinguish (name-spacing) them by using 
ModuleA.Thing vs ModuleB.Thing. 

In regards of Modules being intended to be shipped separately, that is 
incorrect. You might be thinking of packages. 

In Swift 4, a package can contain multiple binaries, including executables and 
libraries. These, can be composed of one or many modules. 

Swift Package Manager handles this really well, and allows to organize the code 
separating it by features or concerns. 

I understand Xcode does not have very good support for modules yet, other than 
importing frameworks. But it is my understanding this is something the new 
Xcode’s build system will solve, hopefully by Xcode 10. 

I’m not against nesting protocol definitions, I can see a few cases where it 
could be nice to have them. But in regards of namespacing, I think using nested 
types is the wrong direction. 

Thank you,
Eneko Alonso 

> On Dec 29, 2017, at 19:00, Kelvin Ma  wrote:
> 
> Modules in Swift are really designed for code that is intended to be shipped 
> separately. as Jon found out modules are pretty heavyweight and introduce a 
> lot of unwanted abstraction and complexity when all you want to do is write 
> things in a namespace. (Also if you forgot, importing a module in Swift dumps 
> all of its symbols into the global namespace so Module.Thing is really 
> meaningless.) sometimes this is a good thing because no one wants to be 
> writing Glibc.fopen over and over especially when you have to #if #endif it 
> out every time with Darwin.fopen if you want your library to run on OSX but 
> this feature also makes modules ineffective as a namespacing scheme. 
> 
> On Fri, Dec 29, 2017 at 8:35 PM, Eneko Alonso  wrote:
>>> …all i wanted to do was write Thing:Namespace.Protocol
>> 
>> Have you thought of using Swift modules for that? Maybe that would be a 
>> better approach than trying to name-space within a module?
>> 
>> Regards,
>> Eneko Alonso
>> 
>>> On Dec 29, 2017, at 16:51, Kelvin Ma via swift-evolution 
>>>  wrote:
>>> 
>>> …all i wanted to do was write Thing:Namespace.Protocol
>>> 
 On Thu, Dec 28, 2017 at 4:43 PM, Adrian Zubarev via swift-evolution 
  wrote:
 Well again I don’t think we should disallow capturing the outer generic 
 type parameter just because you cannot use the protocol inside the outer 
 type atm., you still can add a type-eraser. To be honest such usage of the 
 existential is not even a requirement for the outer type. On there other 
 hand we might want to set the default for the associated type like I 
 showed in my previous message. The nested protocol could serve a 
 completely different purpose. Furthermore I still think that Generic.P 
 and Generic.P should be distinct protocols just like nested generic and 
 non-generic types are within an outer generic type. Sure there could be 
 other problems with ambiguity if you think of something like 
 GenericViewController.Delegate, but the disambiguation when conforming 
 to such protocols requires a different solution and is a well known 
 limitation today.
 
 That said you won’t design such nested types anyways if you know the 
 existing language limitation. I’d say let’s keep it simple in theory and 
 just align the nesting behaviour.
 
 About existentials:
 
 For that scenario I can only speak for myself. I wouldn’t want to allow 
 directly the where clause existentials like this. It is far better and 
 more readable when we force the where clause on typealiases instead. We 
 could lift that restriction later if we’d like to, but not the other way 
 around. I think it’s okay if we start with a small restriction first and 
 see if it adopts well (this is MHO), because this way it shouldn’t harm 
 anybody.
 
 
 
 
 Am 28. Dezember 2017 um 21:51:29, Karl Wagner (razie...@gmail.com) schrieb:
 
> 
> 
>> On 28. Dec 2017, at 12:34, Adrian Zubarev 
>>  wrote:
>> 
>> I disagree with some of your points. Do begin with, I don’t think we 
>> should disallow capturing the generic type parameter, because I think 
>> there might be a good way to prevent parameterization of nested 
>> protocols.
>> 
>> To me this only feels like a natural consequence of nesting protocols 
>> anyways. To achieve this we have to provide an explicit associated type 
>> which will have a default type that refers to the captured outer generic 
>> type parameter. At this point we discover another issue that we cannot 
>> disambiguate generic type parameter like associated types yet and would 
>> be forced to name the associated type of the protocol differently.
>> 
>> 

Re: [swift-evolution] namespacing protocols to other types

2017-12-29 Thread Kelvin Ma via swift-evolution
Modules in Swift are really designed for code that is intended to be
shipped separately. as Jon found out modules are pretty heavyweight and
introduce a lot of unwanted abstraction and complexity when all you want to
do is write things in a namespace. (Also if you forgot, importing a module
in Swift dumps all of its symbols into the global namespace so Module.Thing
is really meaningless.) sometimes this is a good thing because no one wants
to be writing Glibc.fopen over and over especially when you have to #if
#endif it out every time with Darwin.fopen if you want your library to run
on OSX but this feature also makes modules ineffective as a namespacing
scheme.

On Fri, Dec 29, 2017 at 8:35 PM, Eneko Alonso 
wrote:

> …all i wanted to do was write Thing:Namespace.Protocol
>
>
> Have you thought of using Swift modules for that? Maybe that would be a
> better approach than trying to name-space within a module?
>
> Regards,
> Eneko Alonso
>
> On Dec 29, 2017, at 16:51, Kelvin Ma via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> …all i wanted to do was write Thing:Namespace.Protocol
>
> On Thu, Dec 28, 2017 at 4:43 PM, Adrian Zubarev via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Well again I don’t think we should disallow capturing the outer generic
>> type parameter just because you cannot use the protocol inside the outer
>> type atm., you still can add a type-eraser. To be honest such usage of the
>> existential is not even a requirement for the outer type. On there other
>> hand we might want to set the default for the associated type like I showed
>> in my previous message. The nested protocol could serve a completely
>> different purpose. Furthermore I still think that Generic.P and
>> Generic.P should be distinct protocols just like nested generic and
>> non-generic types are within an outer generic type. Sure there could be
>> other problems with ambiguity if you think of something like
>> GenericViewController.Delegate, but the disambiguation when
>> conforming to such protocols requires a different solution and is a well
>> known limitation today.
>>
>> That said you won’t design such nested types anyways if you know the
>> existing language limitation. I’d say let’s keep it simple in theory and
>> just align the nesting behaviour.
>>
>> About existentials:
>>
>> For that scenario I can only speak for myself. I wouldn’t want to allow
>> directly the where clause existentials like this. It is far better and
>> more readable when we force the where clause on typealiases instead. We
>> could lift that restriction later if we’d like to, but not the other way
>> around. I think it’s okay if we start with a small restriction first and
>> see if it adopts well (this is MHO), because this way it shouldn’t harm
>> anybody.
>>
>>
>>
>>
>> Am 28. Dezember 2017 um 21:51:29, Karl Wagner (razie...@gmail.com)
>> schrieb:
>>
>>
>>
>> On 28. Dec 2017, at 12:34, Adrian Zubarev > om> wrote:
>>
>> I disagree with some of your points. Do begin with, I don’t think we
>> should disallow capturing the generic type parameter, because I think there
>> might be a good way to prevent parameterization of nested protocols.
>>
>> To me this only feels like a natural consequence of nesting protocols
>> anyways. To achieve this we have to provide an explicit associated type
>> which will have a default type that refers to the captured outer generic
>> type parameter. At this point we discover another issue that we cannot
>> disambiguate generic type parameter like associated types yet and would be
>> forced to name the associated type of the protocol differently.
>>
>> struct Generic {
>>   protocol P {
>> associatedtype R = T
>> func f() -> R
>>   }
>> }
>>
>> As you can see I didn’t include the variable in this example, because
>> existential are orthogonal this issue. David Hart and I still want to write
>> a proposal to allow the where clause on typealiases - maybe after the
>> forum officially launches.
>>
>> Above I said that there is an issue and provided an example that would
>> solve that issue with todays syntax, but I’d rather expand this idea.
>> Consider this syntax of a generic type and a protocol with an associated
>> type.
>>
>> protocol Proto {
>>   associatedtype Element
>> }
>>
>> Proto.Element // This is an error like this, but it's still allowed in a 
>> generic context
>>
>> func function(_: P) where P.Element == Int {}
>>
>> protocol OtherProto : Proto where Element == Int {}
>>
>> struct Test {}
>>
>> extension Test where Element == Int {}
>>
>> Test.Element // Can/should we allow this?
>>
>> If we could allow this in Swift then the above example with the nested
>> protocol could be disambiguated nicely.
>>
>> struct Generic {
>>   protocol P {
>> associatedtype T = Generic.T
>> func f() -> T
>>   }
>> }
>>
>> Remember that Generic.T is only the default for P.T if you don’t set it
>> yourself but when you 

Re: [swift-evolution] namespacing protocols to other types

2017-12-29 Thread Kelvin Ma via swift-evolution
…all i wanted to do was write Thing:Namespace.Protocol

On Thu, Dec 28, 2017 at 4:43 PM, Adrian Zubarev via swift-evolution <
swift-evolution@swift.org> wrote:

> Well again I don’t think we should disallow capturing the outer generic
> type parameter just because you cannot use the protocol inside the outer
> type atm., you still can add a type-eraser. To be honest such usage of the
> existential is not even a requirement for the outer type. On there other
> hand we might want to set the default for the associated type like I showed
> in my previous message. The nested protocol could serve a completely
> different purpose. Furthermore I still think that Generic.P and
> Generic.P should be distinct protocols just like nested generic and
> non-generic types are within an outer generic type. Sure there could be
> other problems with ambiguity if you think of something like
> GenericViewController.Delegate, but the disambiguation when conforming
> to such protocols requires a different solution and is a well known
> limitation today.
>
> That said you won’t design such nested types anyways if you know the
> existing language limitation. I’d say let’s keep it simple in theory and
> just align the nesting behaviour.
>
> About existentials:
>
> For that scenario I can only speak for myself. I wouldn’t want to allow
> directly the where clause existentials like this. It is far better and
> more readable when we force the where clause on typealiases instead. We
> could lift that restriction later if we’d like to, but not the other way
> around. I think it’s okay if we start with a small restriction first and
> see if it adopts well (this is MHO), because this way it shouldn’t harm
> anybody.
>
>
>
>
> Am 28. Dezember 2017 um 21:51:29, Karl Wagner (razie...@gmail.com)
> schrieb:
>
>
>
> On 28. Dec 2017, at 12:34, Adrian Zubarev 
> wrote:
>
> I disagree with some of your points. Do begin with, I don’t think we
> should disallow capturing the generic type parameter, because I think there
> might be a good way to prevent parameterization of nested protocols.
>
> To me this only feels like a natural consequence of nesting protocols
> anyways. To achieve this we have to provide an explicit associated type
> which will have a default type that refers to the captured outer generic
> type parameter. At this point we discover another issue that we cannot
> disambiguate generic type parameter like associated types yet and would be
> forced to name the associated type of the protocol differently.
>
> struct Generic {
>   protocol P {
> associatedtype R = T
> func f() -> R
>   }
> }
>
> As you can see I didn’t include the variable in this example, because
> existential are orthogonal this issue. David Hart and I still want to write
> a proposal to allow the where clause on typealiases - maybe after the
> forum officially launches.
>
> Above I said that there is an issue and provided an example that would
> solve that issue with todays syntax, but I’d rather expand this idea.
> Consider this syntax of a generic type and a protocol with an associated
> type.
>
> protocol Proto {
>   associatedtype Element
> }
>
> Proto.Element // This is an error like this, but it's still allowed in a 
> generic context
>
> func function(_: P) where P.Element == Int {}
>
> protocol OtherProto : Proto where Element == Int {}
>
> struct Test {}
>
> extension Test where Element == Int {}
>
> Test.Element // Can/should we allow this?
>
> If we could allow this in Swift then the above example with the nested
> protocol could be disambiguated nicely.
>
> struct Generic {
>   protocol P {
> associatedtype T = Generic.T
> func f() -> T
>   }
> }
>
> Remember that Generic.T is only the default for P.T if you don’t set it
> yourself but when you conform or use that that protocol (in a generic
> context) you can still set it differntly.
>
> This consequence disallows protocol parameterization through nesting in a
> generic types, but still behaves very similar to nested generic types:
>
> struct Test {
>   struct NonGeneric {
> var t: T
>   }
>
>   struct Generic {
> var t: T
> var r: R
>   }
> }
>
> _ = Test.NonGeneric(t: "")
> _ = Test.Generic(t: "邏", r: 42)
>
> ——
>
>
> Yeah, that’s all well and good. I don’t think we should parameterise
> protocols either; it feels like Swift hasn’t been designed with those in
> mind, and that’s fine. You would get in to all kinds of horrible conflicts
> if you tried to conform to both Generic.P and Generic.P,
> because most functions would have the same signature but possibly very
> different implementations. You would likely end up having to separate the
> conformances by using a wrapper struct — in which case, why not just make
> them the same protocol and have the existing duplicate-conformance rules
> take care of it?
>
> An earlier version of the proposal included something like you describe.
> Basically, Generic.P and Generic.P would be the same 

Re: [swift-evolution] namespacing protocols to other types

2017-12-28 Thread Adrian Zubarev via swift-evolution
Well again I don’t think we should disallow capturing the outer generic type 
parameter just because you cannot use the protocol inside the outer type atm., 
you still can add a type-eraser. To be honest such usage of the existential is 
not even a requirement for the outer type. On there other hand we might want to 
set the default for the associated type like I showed in my previous message. 
The nested protocol could serve a completely different purpose. Furthermore I 
still think that Generic.P and Generic.P should be distinct protocols 
just like nested generic and non-generic types are within an outer generic 
type. Sure there could be other problems with ambiguity if you think of 
something like GenericViewController.Delegate, but the disambiguation when 
conforming to such protocols requires a different solution and is a well known 
limitation today.

That said you won’t design such nested types anyways if you know the existing 
language limitation. I’d say let’s keep it simple in theory and just align the 
nesting behaviour.

About existentials:

For that scenario I can only speak for myself. I wouldn’t want to allow 
directly the where clause existentials like this. It is far better and more 
readable when we force the where clause on typealiases instead. We could lift 
that restriction later if we’d like to, but not the other way around. I think 
it’s okay if we start with a small restriction first and see if it adopts well 
(this is MHO), because this way it shouldn’t harm anybody.




Am 28. Dezember 2017 um 21:51:29, Karl Wagner (razie...@gmail.com) schrieb:



On 28. Dec 2017, at 12:34, Adrian Zubarev  
wrote:

I disagree with some of your points. Do begin with, I don’t think we should 
disallow capturing the generic type parameter, because I think there might be a 
good way to prevent parameterization of nested protocols.

To me this only feels like a natural consequence of nesting protocols anyways. 
To achieve this we have to provide an explicit associated type which will have 
a default type that refers to the captured outer generic type parameter. At 
this point we discover another issue that we cannot disambiguate generic type 
parameter like associated types yet and would be forced to name the associated 
type of the protocol differently.

struct Generic {
  protocol P {   
associatedtype R = T   
func f() -> R   
  }
}
As you can see I didn’t include the variable in this example, because 
existential are orthogonal this issue. David Hart and I still want to write a 
proposal to allow the where clause on typealiases - maybe after the forum 
officially launches.

Above I said that there is an issue and provided an example that would solve 
that issue with todays syntax, but I’d rather expand this idea. Consider this 
syntax of a generic type and a protocol with an associated type.

protocol Proto {
  associatedtype Element
}

Proto.Element // This is an error like this, but it's still allowed in a 
generic context

func function(_: P) where P.Element == Int {}

protocol OtherProto : Proto where Element == Int {}

struct Test {}

extension Test where Element == Int {}

Test.Element // Can/should we allow this?
If we could allow this in Swift then the above example with the nested protocol 
could be disambiguated nicely.

struct Generic {
  protocol P {   
associatedtype T = Generic.T   
func f() -> T   
  }
}
Remember that Generic.T is only the default for P.T if you don’t set it 
yourself but when you conform or use that that protocol (in a generic context) 
you can still set it differntly.

This consequence disallows protocol parameterization through nesting in a 
generic types, but still behaves very similar to nested generic types:

struct Test {
  struct NonGeneric {
var t: T
  }

  struct Generic {
var t: T
var r: R
  }
}

_ = Test.NonGeneric(t: "")
_ = Test.Generic(t: "邏", r: 42)
——



Yeah, that’s all well and good. I don’t think we should parameterise protocols 
either; it feels like Swift hasn’t been designed with those in mind, and that’s 
fine. You would get in to all kinds of horrible conflicts if you tried to 
conform to both Generic.P and Generic.P, because most functions 
would have the same signature but possibly very different implementations. You 
would likely end up having to separate the conformances by using a wrapper 
struct — in which case, why not just make them the same protocol and have the 
existing duplicate-conformance rules take care of it?

An earlier version of the proposal included something like you describe. 
Basically, Generic.P and Generic.P would be the same protocol. 
They would have an associated type to represent the parameter from Generic, 
and within Generic, all references to P would be implicitly constrained so 
that P.T == Self.T. You would write conformances to “Generic.P” with a 
constraint for T, as you do today.
And for the existential variable inside Genric it really should 

Re: [swift-evolution] namespacing protocols to other types

2017-12-28 Thread Karl Wagner via swift-evolution


> On 28. Dec 2017, at 12:34, Adrian Zubarev  
> wrote:
> 
> I disagree with some of your points. Do begin with, I don’t think we should 
> disallow capturing the generic type parameter, because I think there might be 
> a good way to prevent parameterization of nested protocols.
> 
> To me this only feels like a natural consequence of nesting protocols 
> anyways. To achieve this we have to provide an explicit associated type which 
> will have a default type that refers to the captured outer generic type 
> parameter. At this point we discover another issue that we cannot 
> disambiguate generic type parameter like associated types yet and would be 
> forced to name the associated type of the protocol differently.
> 
> struct Generic {
>   protocol P {  
> associatedtype R = T  
> func f() -> R  
>   }
> }
> As you can see I didn’t include the variable in this example, because 
> existential are orthogonal this issue. David Hart and I still want to write a 
> proposal to allow the where clause on typealiases - maybe after the forum 
> officially launches.
> 
> Above I said that there is an issue and provided an example that would solve 
> that issue with todays syntax, but I’d rather expand this idea. Consider this 
> syntax of a generic type and a protocol with an associated type.
> 
> protocol Proto {
>   associatedtype Element
> }
> 
> Proto.Element // This is an error like this, but it's still allowed in a 
> generic context
> 
> func function(_: P) where P.Element == Int {}
> 
> protocol OtherProto : Proto where Element == Int {}
> 
> struct Test {}
> 
> extension Test where Element == Int {}
> 
> Test.Element // Can/should we allow this?
> If we could allow this in Swift then the above example with the nested 
> protocol could be disambiguated nicely.
> 
> struct Generic {
>   protocol P {  
> associatedtype T = Generic.T  
> func f() -> T  
>   }
> }
> Remember that Generic.T is only the default for P.T if you don’t set it 
> yourself but when you conform or use that that protocol (in a generic 
> context) you can still set it differntly.
> 
> This consequence disallows protocol parameterization through nesting in a 
> generic types, but still behaves very similar to nested generic types:
> 
> struct Test {
>   struct NonGeneric {
> var t: T
>   }
> 
>   struct Generic {
> var t: T
> var r: R
>   }
> }
> 
> _ = Test.NonGeneric(t: "")
> _ = Test.Generic(t: "邏", r: 42)
> ——
> 
> 

Yeah, that’s all well and good. I don’t think we should parameterise protocols 
either; it feels like Swift hasn’t been designed with those in mind, and that’s 
fine. You would get in to all kinds of horrible conflicts if you tried to 
conform to both Generic.P and Generic.P, because most functions 
would have the same signature but possibly very different implementations. You 
would likely end up having to separate the conformances by using a wrapper 
struct — in which case, why not just make them the same protocol and have the 
existing duplicate-conformance rules take care of it?

An earlier version of the proposal included something like you describe. 
Basically, Generic.P and Generic.P would be the same protocol. 
They would have an associated type to represent the parameter from Generic, 
and within Generic, all references to P would be implicitly constrained so 
that P.T == Self.T. You would write conformances to “Generic.P” with a 
constraint for T, as you do today.
> And for the existential variable inside Genric it really should be something 
> like this (when the where clause is allowed and if we can refer differently 
> to generic type parameters as well):
> 
> struct Generic {
> …
> typealias PConstrainedByT = P where T == Self.T
> var object: PConstrainedByT
> }
> 
If we have that ability, then we can totally do capturing. Forgive me, but I 
understand that as pretty-much the same as generalised existentials (without 
local type binding).
If I can write the type of object as an existential of (generic protocol + 
constraints) via a typealias, then surely I must also be able to do it 
directly? So I could also write:

struct Generic {
var object: P where T == Self.T
}

Anyway, I thought that was not on the table, and in any case I’m convinced that 
it should be a separate proposal. This gets to the heart of the interaction 
between generic types and protocols, and we all know it’s not always a smooth 
transition (hello AnyCollection, AnyHashable, etc...). We can cover the common 
cases (i.e. the Apple frameworks) without requiring capturing - especially 
since it’s apparently not too difficult to implement - and build from there.

- Karl

> 
> 
> 
> Am 27. Dezember 2017 um 19:53:36, Karl Wagner via swift-evolution 
> (swift-evolution@swift.org ) schrieb:
> 
>> Yeah I wrote that proposal. I eventually stripped it down to just disallow 
>> all capturing, but it was still not selected by the core team 

Re: [swift-evolution] namespacing protocols to other types

2017-12-28 Thread Adrian Zubarev via swift-evolution
I disagree with some of your points. Do begin with, I don’t think we should 
disallow capturing the generic type parameter, because I think there might be a 
good way to prevent parameterization of nested protocols.

To me this only feels like a natural consequence of nesting protocols anyways. 
To achieve this we have to provide an explicit associated type which will have 
a default type that refers to the captured outer generic type parameter. At 
this point we discover another issue that we cannot disambiguate generic type 
parameter like associated types yet and would be forced to name the associated 
type of the protocol differently.

struct Generic {
  protocol P {  
associatedtype R = T  
func f() -> R  
  }
}
As you can see I didn’t include the variable in this example, because 
existential are orthogonal this issue. David Hart and I still want to write a 
proposal to allow the where clause on typealiases - maybe after the forum 
officially launches.

Above I said that there is an issue and provided an example that would solve 
that issue with todays syntax, but I’d rather expand this idea. Consider this 
syntax of a generic type and a protocol with an associated type.

protocol Proto {
  associatedtype Element
}

Proto.Element // This is an error like this, but it's still allowed in a 
generic context

func function(_: P) where P.Element == Int {}

protocol OtherProto : Proto where Element == Int {}

struct Test {}

extension Test where Element == Int {}

Test.Element // Can/should we allow this?
If we could allow this in Swift then the above example with the nested protocol 
could be disambiguated nicely.

struct Generic {
  protocol P {  
associatedtype T = Generic.T  
func f() -> T  
  }
}
Remember that Generic.T is only the default for P.T if you don’t set it 
yourself but when you conform or use that that protocol (in a generic context) 
you can still set it differntly.

This consequence disallows protocol parameterization through nesting in a 
generic types, but still behaves very similar to nested generic types:

struct Test {
  struct NonGeneric {
var t: T
  }

  struct Generic {
var t: T
var r: R
  }
}

_ = Test.NonGeneric(t: "")
_ = Test.Generic(t: "邏", r: 42)
——

And for the existential variable inside Genric it really should be something 
like this (when the where clause is allowed and if we can refer differently to 
generic type parameters as well):

struct Generic {
…
typealias PConstrainedByT = P where T == Self.T
var object: PConstrainedByT
}



Am 27. Dezember 2017 um 19:53:36, Karl Wagner via swift-evolution 
(swift-evolution@swift.org) schrieb:

Yeah I wrote that proposal. I eventually stripped it down to just disallow all 
capturing, but it was still not selected by the core team for review ¯\_(ツ)_/¯

As for capturing semantics, once you start working through use-cases, it’s 
becomes clear that it's going to require generalised existentials. Otherwise, 
how would you use a Generic.P?

struct Generic {
    protocol P { func f() -> T }

    var object: P // uh-oh! ‘Generic protocol can only be used as a generic 
parameter constraint'
}

So, you would need to add a generic parameter to actually use P from within 
Generic, which of course limits you to a single concrete type of P:

struct Generic where TypeOfP: Self.P {      // Could this even 
work? What if P captures TypeOfP?
    protocol P { /* … */ }
    var object: TypeOfP
}

Which is just yucky.

Ideally, the type of ‘object’ should be ‘Any’, to express 
that it can be any conforming type with the appropriate constraints. You 
wouldn’t need to write that all out; we could infer that capturing is 
equivalent to a same-type constraint (or perhaps one of these “generalised 
supertype constraints” that were pitched recently). But we can’t express those 
kinds of existentials everywhere in the type-system today, so most examples of 
capturing fall down pretty quickly.

- Karl

On 25. Dec 2017, at 03:56, Slava Pestov via swift-evolution 
 wrote:

There was a proposal to allow protocols to be nested inside types at one point 
but it didn’t move forward.

Basically, if the outer type is a non-generic class, struct or enum, there’s no 
conceptual difficulty at all.

If the outer type is a generic type or another protocol, you have a problem 
where the inner protocol can reference generic parameters or associated types 
of the outer type. This would either have to be banned, or we would need to 
come up with coherent semantics for it:

struct Generic {
 protocol P {
   func f() -> T
 }
}

struct Conforms : Generic.P {
 func f() -> Int { … } // Like this?
}

let c = Conforms()
c is Generic.P // is this false? Ie, are Generic.P and 
Generic.P different protocols?

Slava

On Dec 24, 2017, at 6:53 PM, Kelvin Ma via swift-evolution 
 wrote:

is there a reason why it’s not allowed to nest a protocol declaration inside 
another type?

Re: [swift-evolution] namespacing protocols to other types

2017-12-27 Thread Karl Wagner via swift-evolution
Yeah I wrote that proposal. I eventually stripped it down to just disallow all 
capturing, but it was still not selected by the core team for review ¯\_(ツ)_/¯

As for capturing semantics, once you start working through use-cases, it’s 
becomes clear that it's going to require generalised existentials. Otherwise, 
how would you use a Generic.P?

struct Generic {
protocol P { func f() -> T }

var object: P // uh-oh! ‘Generic protocol can only be used as a generic 
parameter constraint'
}

So, you would need to add a generic parameter to actually use P from within 
Generic, which of course limits you to a single concrete type of P:

struct Generic where TypeOfP: Self.P {  // Could this even 
work? What if P captures TypeOfP?
protocol P { /* … */ }
var object: TypeOfP
}

Which is just yucky.

Ideally, the type of ‘object’ should be ‘Any’, to express 
that it can be any conforming type with the appropriate constraints. You 
wouldn’t need to write that all out; we could infer that capturing is 
equivalent to a same-type constraint (or perhaps one of these “generalised 
supertype constraints” that were pitched recently). But we can’t express those 
kinds of existentials everywhere in the type-system today, so most examples of 
capturing fall down pretty quickly.

- Karl

> On 25. Dec 2017, at 03:56, Slava Pestov via swift-evolution 
>  wrote:
> 
> There was a proposal to allow protocols to be nested inside types at one 
> point but it didn’t move forward.
> 
> Basically, if the outer type is a non-generic class, struct or enum, there’s 
> no conceptual difficulty at all.
> 
> If the outer type is a generic type or another protocol, you have a problem 
> where the inner protocol can reference generic parameters or associated types 
> of the outer type. This would either have to be banned, or we would need to 
> come up with coherent semantics for it:
> 
> struct Generic {
>  protocol P {
>func f() -> T
>  }
> }
> 
> struct Conforms : Generic.P {
>  func f() -> Int { … } // Like this?
> }
> 
> let c = Conforms()
> c is Generic.P // is this false? Ie, are Generic.P and 
> Generic.P different protocols?
> 
> Slava
> 
>> On Dec 24, 2017, at 6:53 PM, Kelvin Ma via swift-evolution 
>>  wrote:
>> 
>> is there a reason why it’s not allowed to nest a protocol declaration inside 
>> another type?
>> ___
>> 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

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


Re: [swift-evolution] namespacing protocols to other types

2017-12-26 Thread Jon Gilbert via swift-evolution
Amen. This seems like an appropriate step towards better name-spacing, and it’s 
one we have sorely missed on one manor project at work. 

We maintain a framework that wraps our various web APIs with convenience 
methods and data model types. Since the APIs are versioned, we have nested most 
things inside a struct or enum that has “_V1”, “_V2” etc. appended. The 
protocols not being able to go inside there is pretty annoying. 

Still, even if protocols could be nested inside non-generic struct and enum 
types, it still doesn’t seem like the best way to name-space in the first 
place, because at that point, we are not making a “name space struct/enum” for 
any other purpose than name-spacing. It just seems like that’s not what those 
types are intended to be used for. 

If you are using a struct/enum/class more than just namespacing, then OK, 
because I can definitely understand wanting to nest a delegate protocol under 
the type whose delegate it will be, for example.

However, name-spacing via a struct/enum just for versioning or just to group 
some things together by domain does not seem like a good style over-all. 
Because then, everything has to be indented one additional level than it really 
should be, and you get all these extraneous extensions everywhere. It’s just 
not pretty.

I’d much rather have an easier way to work with modules and module maps that 
did not involve cluttering up the project in XCode with 30 extra build targets 
that causes 30 sub-frameworks. This seems to have a very negative impact on app 
load times from what our testing has indicated, and this kind of name-spacing 
relies on changes to the XCode project file, making it harder to track in git 
and maintain across multiple project files, etc. Is there currently a better 
workaround?

There must be a compelling reason why we cannot simply namespace by typing 
“namespace MyNameSpace” at the top of each source file. I don’t know what the 
reason is, but I am kind if afraid to ask, since it feels like the kind of 
thing that surely has been debated here ad nauseam in the past... I will 
research list history later.

I have a feeling the ABI Resilience doc talking a lot about the @versioned and 
@available keywords might hint at another option for the use case at my job, 
but it certainly does not seem to replace an easy and clean way to namespace.  

Jon


> On Dec 24, 2017, at 20:36, Howard Lovatt via swift-evolution 
>  wrote:
> 
> I would say yes they are different for the example. Definitely something I 
> miss is nesting types to given a seperate namespace. 
> 
> -- Howard. 
> 
>> On 24 Dec 2017, at 9:56 pm, Slava Pestov via swift-evolution 
>>  wrote:
>> 
>> There was a proposal to allow protocols to be nested inside types at one 
>> point but it didn’t move forward.
>> 
>> Basically, if the outer type is a non-generic class, struct or enum, there’s 
>> no conceptual difficulty at all.
>> 
>> If the outer type is a generic type or another protocol, you have a problem 
>> where the inner protocol can reference generic parameters or associated 
>> types of the outer type. This would either have to be banned, or we would 
>> need to come up with coherent semantics for it:
>> 
>> struct Generic {
>> protocol P {
>>   func f() -> T
>> }
>> }
>> 
>> struct Conforms : Generic.P {
>> func f() -> Int { … } // Like this?
>> }
>> 
>> let c = Conforms()
>> c is Generic.P // is this false? Ie, are Generic.P and 
>> Generic.P different protocols?
>> 
>> Slava
>> 
>>> On Dec 24, 2017, at 6:53 PM, Kelvin Ma via swift-evolution 
>>>  wrote:
>>> 
>>> is there a reason why it’s not allowed to nest a protocol declaration 
>>> inside another type?
>>> ___
>>> 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
> ___
> 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


Re: [swift-evolution] namespacing protocols to other types

2017-12-24 Thread Kelvin Ma via swift-evolution
vv

On Sun, Dec 24, 2017 at 11:36 PM, Howard Lovatt 
wrote:

> I would say yes they are different for the example. Definitely something I
> miss is nesting types to given a seperate namespace.
>
> -- Howard.
>
> > On 24 Dec 2017, at 9:56 pm, Slava Pestov via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> > There was a proposal to allow protocols to be nested inside types at one
> point but it didn’t move forward.
> >
> > Basically, if the outer type is a non-generic class, struct or enum,
> there’s no conceptual difficulty at all.
> >
> > If the outer type is a generic type or another protocol, you have a
> problem where the inner protocol can reference generic parameters or
> associated types of the outer type. This would either have to be banned, or
> we would need to come up with coherent semantics for it:
> >
> > struct Generic {
> >  protocol P {
> >func f() -> T
> >  }
> > }
> >
> > struct Conforms : Generic.P {
> >  func f() -> Int { … } // Like this?
> > }
> >
> > let c = Conforms()
> > c is Generic.P // is this false? Ie, are Generic.P and
> Generic.P different protocols?
> >
> > Slava
> >
> >> On Dec 24, 2017, at 6:53 PM, Kelvin Ma via swift-evolution <
> swift-evolution@swift.org> wrote:
> >>
> >> is there a reason why it’s not allowed to nest a protocol declaration
> inside another type?
> >> ___
> >> 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
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] namespacing protocols to other types

2017-12-24 Thread Howard Lovatt via swift-evolution
I would say yes they are different for the example. Definitely something I miss 
is nesting types to given a seperate namespace. 

-- Howard. 

> On 24 Dec 2017, at 9:56 pm, Slava Pestov via swift-evolution 
>  wrote:
> 
> There was a proposal to allow protocols to be nested inside types at one 
> point but it didn’t move forward.
> 
> Basically, if the outer type is a non-generic class, struct or enum, there’s 
> no conceptual difficulty at all.
> 
> If the outer type is a generic type or another protocol, you have a problem 
> where the inner protocol can reference generic parameters or associated types 
> of the outer type. This would either have to be banned, or we would need to 
> come up with coherent semantics for it:
> 
> struct Generic {
>  protocol P {
>func f() -> T
>  }
> }
> 
> struct Conforms : Generic.P {
>  func f() -> Int { … } // Like this?
> }
> 
> let c = Conforms()
> c is Generic.P // is this false? Ie, are Generic.P and 
> Generic.P different protocols?
> 
> Slava
> 
>> On Dec 24, 2017, at 6:53 PM, Kelvin Ma via swift-evolution 
>>  wrote:
>> 
>> is there a reason why it’s not allowed to nest a protocol declaration inside 
>> another type?
>> ___
>> 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
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] namespacing protocols to other types

2017-12-24 Thread Slava Pestov via swift-evolution
There was a proposal to allow protocols to be nested inside types at one point 
but it didn’t move forward.

Basically, if the outer type is a non-generic class, struct or enum, there’s no 
conceptual difficulty at all.

If the outer type is a generic type or another protocol, you have a problem 
where the inner protocol can reference generic parameters or associated types 
of the outer type. This would either have to be banned, or we would need to 
come up with coherent semantics for it:

struct Generic {
  protocol P {
func f() -> T
  }
}

struct Conforms : Generic.P {
  func f() -> Int { … } // Like this?
}

let c = Conforms()
c is Generic.P // is this false? Ie, are Generic.P and 
Generic.P different protocols?

Slava

> On Dec 24, 2017, at 6:53 PM, Kelvin Ma via swift-evolution 
>  wrote:
> 
> is there a reason why it’s not allowed to nest a protocol declaration inside 
> another type?
> ___
> 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