Re: [swift-evolution] [swift-evolution-announce] [REVIEW] SE-0193 - Cross-module inlining and specialization

2017-12-28 Thread Chris Lattner via swift-evolution

> On Dec 23, 2017, at 2:59 PM, Chris Lattner  wrote:
> 
>>> 
>>> I'm quite sure that the reason you inverted your "abiPublic" example is 
>>> because of the same issue. Intuitively, you would want to mark something as 
>>> "available" in version N and then maybe some special kind of "available" in 
>>> version N+1 (which @available(inlinable) would be). But 
>>> @available(linkerSymbol), as you spell it, suffers from a similar problem 
>>> to that of @available(unavailable): it's _not_ a special kind of API 
>>> availability, but rather indicates that something is less-than-available. 
>>> That is, you would use it to indicate that something is available as ABI 
>>> but not as API. In that sense, it extends the "mess" we have with 
>>> @available(unavailable).
>> 
>> I don’t think it’s quite the same thing as @available(unavailable). An 
>> @available(abiPublic) symbol would still be declared to have internal 
>> visibility, so in this case the @available attribute makes it strictly more 
>> visible than it would be without. We’re not going to spell it as 
>> ‘@available(abiPublic) public’, which indeed would be confusing because the 
>> symbol is not actually public at the source level.
> 
> Right.  The bug here is with @available(unavailable).  Its design is clearly 
> broken and oxymoronic.  That doesn’t make all of @available broken.

Random thought: I think this all would make more sense if we rename @available 
-> @availability and unavailable -> removed.

-Chris

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


Re: [swift-evolution] Enums and Source Compatibility

2017-12-28 Thread Wallacy via swift-evolution
Actually this make much more sense than original proposal.

Good call!

Just to check...

Its not better this?

public enum HomeworkExcuse {
  case eatenByPet
  default case thoughtItWasDueNextWeek}


If i understood correctly, if the enum is not exhaustible, must be
considered as this default value after a new case be introduced in a new
version of the lib right?

And for this one:

public enum HomeworkExcuse {
  case eatenByPet
  case thoughtItWasDueNextWeek
  fallback unknown // any word of course right?}


In this case fallback is the same as default right? But has as explicit new
label/case?

So, this is not enough?

public enum HomeworkExcuse {
  case eatenByPet
  fallback case thoughtItWasDueNextWeek}


If the dev wants to do make a default/fallback just use them for a regular
case, if not, if he wants to make a totally different case for a fallback
just declare another one to be the default/fallback (like unknown).

I understood your idea correctly?

Em qui, 21 de dez de 2017 às 20:48, Andrew Bennett via swift-evolution <
swift-evolution@swift.org> escreveu:

> Can you go into more detail about why the core team didn't like this?
>
> public enum HomeworkExcuse {
>   case eatenByPet
>   case thoughtItWasDueNextWeek
>   default // NEW}
>
>
> To me this is very close to an ideal solution, it fixes ABI concerns, it
> has sensible defaults. If it was changed a little bit:
>
> public enum HomeworkExcuse {
>   case eatenByPet
>   case thoughtItWasDueNextWeek
>   fallback unknown // NEW}
>
>
> Then I believe you would be able to have an exhaustive switch like this:
>
> switch thing {
>   case eatenByPet: break
>   case thoughtItWasDueNextWeek: break
>   case unknown: break}
>
>
> Which would *still allow compile-time errors if new cases are introduced*,
> while providing a concise way to show something is not exhaustible.
>
> This would also *support existing enums with "unknown" equivalent cases*
> would be able to explicitly label those fields as fallback without needing
> to make large code changes.
>
> I see no reason why you shouldn't be able to use ".unknown", which *should
> still allow this to be testable*.
>
> Thanks,
> Andrew
>
> On Tue, Oct 3, 2017 at 8:10 AM, Jordan Rose via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> I don't think I have anything to say on this topic that I haven't already
>> said:
>>
>> - Switching exhaustively over non-exhaustive enums is uncommon.
>> - It's more important for a library to build without errors when its
>> dependencies change than it is to get an error. (This doesn't apply to
>> warnings, though.)
>> - Untestable code is dangerous, so having a language feature inherently
>> for untestable code seems bad.
>>
>> None of that negates your points; it just affects the weighting of
>> whether or not 'future' or 'switch!' is worth it. However, I've added a
>> link to your email in the proposal proper so that the Core Team and wider
>> review audience have a chance to decide differently.
>>
>> Jordan
>>
>>
>> On Oct 2, 2017, at 08:25, Vladimir.S via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>
>> Sorry to bother, but I still can't understand how the proposed change
>> *without* a 'future' case in switch will change our life and what would be
>> our steps to support our code and to not make our code buggy.
>> If I misunderstand something - sorry, please point me on this and I hope
>> this also help some one like me to understand the subject better.
>>
>> For example. I use OAuth2 framework, built by Carthage. Did add the
>> OAuth2.framework to my project.
>>
>> Currently OAuth2 exports 'public enum OAuth2Error'. I do have a place in
>> my code where I switch on each case of such error instance to do my best
>> with error: generate detailed description for user, other additional steps
>> depending on error.
>>
>> Will/should author of OAuth2 make OAuth2Error 'exhaustive' ? No.
>> Will new cases be added to that enum in future: Most likely Yes.
>> Do I need to switch on each case in my code? Yes.
>> Can I currently rely on compiler to keep my error processing in sync with
>> error cases defined in framework? Yes.
>> Can new cases appear in *run-time* of my app: NO, framework in embedded.
>> Will I be able to rely on compiler after the proposed change? No?!
>> What should I do to keep my switch in sync with OAuth2Error cases after
>> each update of OAuth2 library(framework)? Manually check if new cases are
>> added?! Configure lint/other tools to help me with this?!
>>
>> What I, as a developer, as a consumer of framework, need - is a way to
>> exhaustively switch on *some* external non-exhaustive enums *at the moment
>> of compilation*. And we can accomplish this only(AFAICT) with 'future' case
>> in 'switch'.
>> In case we'll have 'future' case my life will not be *worse* for this
>> project : I'll add it to my switch and still can receive help from compiler
>> to keep switch exhaustive.
>>
>> I don't support the opinion that we can't int

Re: [swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums

2017-12-28 Thread Jean-Daniel via swift-evolution


> Le 28 déc. 2017 à 21:17, Eneko Alonso via swift-evolution 
>  a écrit :
> 
> Hello everyone, 
> 
> My name is Eneko Alonso, iOS developer, new here on the list.
> 
> Is there a good summary anywhere that condenses the pros and cons of this new 
> feature that have been discussed so far?
> 
> It is not clear to me why non-exhaustive would be the default, requiring 
> adding `@exhaustive` otherwise. Has anyone discussed doing it the other way 
> around, this is, defaulting to exhaustive (no changes with prior Swift 
> versions) and adding a `@nonExhaustive` tag instead as needed?

IIUC, this is to help binary stability.
If a library developer write an enum without knowing about « @exhaustive », it 
can safely add another enum in a v2 of the library without breaking all the 
clients.


> 
> Apologies if this has been covered already.
> 
> Regards and thank you everyone for making Swift better!
> Eneko
> 
> 
>> On Dec 27, 2017, at 10:26 PM, Riley Testut via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Actually, from the other email thread about this same topic (thank god 
>> forums are almost here), I see the proposed syntax “final switch” for what I 
>> referred to as “switch!”, which I prefer.
>> 
>> On Dec 28, 2017, at 12:17 AM, Riley Testut via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> -1.
>>> 
>>> I agree this is a problem, but I think this is the wrong solution. I think 
>>> the solution should be on the client side, not on the framework author’s 
>>> side.
>>> 
>>> I would be fine if enums from imported modules are non-exhaustive, as long 
>>> as I can choose to treat them as exhaustive if I want to. And in that case, 
>>> if a new case is introduced, I think a fatal error is a reasonable result.
>>> 
>>> The proposed “switch!” command would do just this, and I think that is the 
>>> better answer for this. Adding an @exhaustive attribute doesn’t actually 
>>> prevent someone from adding a case anyway, which I think is a big (and not 
>>> really solvable) issue 🤷‍♂️
>>> 
>>> I know much has been said about this, but it’s just my 2c.
>>> 
>>> On Dec 27, 2017, at 9:42 AM, Thorsten Seitz via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
 
 
> The proposal is available here:
> https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
>  
> 
> What is your evaluation of the proposal?
> 
 
 -1
 
 I would much prefer the solution proposed by Andrew Bennett in another 
 thread which solves all problems very nicely including the testability of 
 future cases by giving them a placeholder name:
 
 From Andrew’s mail:
> public enum HomeworkExcuse {
>   case eatenByPet
>   case thoughtItWasDueNextWeek
>   fallback unknown // NEW
> }
> 
> Then I believe you would be able to have an exhaustive switch like this:
> 
> switch thing {
>   case eatenByPet: break
>   case thoughtItWasDueNextWeek: break
>   case unknown: break
> }
> 
> Which would still allow compile-time errors if new cases are introduced, 
> while providing a concise way to show something is not exhaustible.
> 
> This would also support existing enums with "unknown" equivalent cases 
> would be able to explicitly label those fields as fallback without 
> needing to make large code changes.
> 
> I see no reason why you shouldn't be able to use ".unknown", which should 
> still allow this to be testable.
 
 i.e. Andrew’s idea is to introduce a placeholder case instead of marking 
 the enum as exhaustive/non-exhaustive. This gives the future cases a 
 handle to be switched on and to be tested against. Very elegant.
 
> Is the problem being addressed significant enough to warrant a change to 
> Swift?
> 
 Yes, but the proposed solution is not as good as it should be, neglecting 
 to provide compile-time errors if new cases are introduced.
> Does this proposal fit well with the feel and direction of Swift?
> 
 No, due to its shortcomings.
> If you have used other languages or libraries with a similar feature, how 
> do you feel that this proposal compares to those?
> 
 None, but see Andrew Bennett’s idea above.
> How much effort did you put into your review? A glance, a quick reading, 
> or an in-depth study?
> 
 Followed most of the discussion and review threads.
 
 -Thorsten
 ___
 swift-evolution mailing list
 swift-evolution@swift.org 
 https://lists.swift.org/mailman/listinfo/swift-evolution 
 
>>> ___
>>> swift-evol

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 be something 
like this (when the

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 for review 
>> ¯\_(ツ)_/¯
>> 
>> A

Re: [swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums

2017-12-28 Thread Eneko Alonso via swift-evolution
Hello everyone, 

My name is Eneko Alonso, iOS developer, new here on the list.

Is there a good summary anywhere that condenses the pros and cons of this new 
feature that have been discussed so far?

It is not clear to me why non-exhaustive would be the default, requiring adding 
`@exhaustive` otherwise. Has anyone discussed doing it the other way around, 
this is, defaulting to exhaustive (no changes with prior Swift versions) and 
adding a `@nonExhaustive` tag instead as needed?

Apologies if this has been covered already.

Regards and thank you everyone for making Swift better!
Eneko


> On Dec 27, 2017, at 10:26 PM, Riley Testut via swift-evolution 
>  wrote:
> 
> Actually, from the other email thread about this same topic (thank god forums 
> are almost here), I see the proposed syntax “final switch” for what I 
> referred to as “switch!”, which I prefer.
> 
> On Dec 28, 2017, at 12:17 AM, Riley Testut via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> -1.
>> 
>> I agree this is a problem, but I think this is the wrong solution. I think 
>> the solution should be on the client side, not on the framework author’s 
>> side.
>> 
>> I would be fine if enums from imported modules are non-exhaustive, as long 
>> as I can choose to treat them as exhaustive if I want to. And in that case, 
>> if a new case is introduced, I think a fatal error is a reasonable result.
>> 
>> The proposed “switch!” command would do just this, and I think that is the 
>> better answer for this. Adding an @exhaustive attribute doesn’t actually 
>> prevent someone from adding a case anyway, which I think is a big (and not 
>> really solvable) issue 🤷‍♂️
>> 
>> I know much has been said about this, but it’s just my 2c.
>> 
>> On Dec 27, 2017, at 9:42 AM, Thorsten Seitz via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> 
 The proposal is available here:
 https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
  
 
 What is your evaluation of the proposal?
 
>>> 
>>> -1
>>> 
>>> I would much prefer the solution proposed by Andrew Bennett in another 
>>> thread which solves all problems very nicely including the testability of 
>>> future cases by giving them a placeholder name:
>>> 
>>> From Andrew’s mail:
 public enum HomeworkExcuse {
   case eatenByPet
   case thoughtItWasDueNextWeek
   fallback unknown // NEW
 }
 
 Then I believe you would be able to have an exhaustive switch like this:
 
 switch thing {
   case eatenByPet: break
   case thoughtItWasDueNextWeek: break
   case unknown: break
 }
 
 Which would still allow compile-time errors if new cases are introduced, 
 while providing a concise way to show something is not exhaustible.
 
 This would also support existing enums with "unknown" equivalent cases 
 would be able to explicitly label those fields as fallback without needing 
 to make large code changes.
 
 I see no reason why you shouldn't be able to use ".unknown", which should 
 still allow this to be testable.
>>> 
>>> i.e. Andrew’s idea is to introduce a placeholder case instead of marking 
>>> the enum as exhaustive/non-exhaustive. This gives the future cases a handle 
>>> to be switched on and to be tested against. Very elegant.
>>> 
 Is the problem being addressed significant enough to warrant a change to 
 Swift?
 
>>> Yes, but the proposed solution is not as good as it should be, neglecting 
>>> to provide compile-time errors if new cases are introduced.
 Does this proposal fit well with the feel and direction of Swift?
 
>>> No, due to its shortcomings.
 If you have used other languages or libraries with a similar feature, how 
 do you feel that this proposal compares to those?
 
>>> None, but see Andrew Bennett’s idea above.
 How much effort did you put into your review? A glance, a quick reading, 
 or an in-depth study?
 
>>> Followed most of the discussion and review threads.
>>> 
>>> -Thorsten
>>> ___
>>> 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

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?
___
swift-evolution maili