Sent from my iPad

> On Feb 11, 2017, at 12:38 PM, Adrian Zubarev via swift-evolution 
> <[email protected]> wrote:
> 
> That makes actually sense to me if we think of it that we never will get any 
> sub-typing for enums. I’m still undecided on that sub-typing topic about 
> value types. Just out of curiosity it would be interesting to hear from the 
> core team if this would be a future direction for Swift or not, be it in 
> Swift 20 or whatever. :)
> 
The core team has indicated support for value subtyping.  It's unclear when 
this might happen though.

I am working on writing up some ideas related to this right now.  I hope that 
helps you to see how value subtyping fits into the hypothetical Swift with 
`closed` as an access modifier I am proposing.  This will be more of a 
"manifesto" style document than a proposal.  It will lay out the landscape a 
bunch of related ideas, some of which may have ABI impact (and this be relevant 
for consideration now) and others will be left for future consideration.

> Back on the original topic: If the community feels we need something like 
> closed, then so be it, I don’t mind having flexibility because it makes the 
> language more powerful.
> 
We definitely need it for enums.  The only question is how we spell it and 
whether the semantics have a clear and consistent relationship with how we 
treat classes, protocols and the `open` access modifier.  My proposal is that 
we do it in a way that is clear and consistent.

> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 11. Februar 2017 um 19:31:10, Xiaodi Wu ([email protected]) schrieb:
> 
>> I think Matthew's point (with which I agree) is that, as enums are sum 
>> types, adding or removing cases is akin to subclassing. You can extend a 
>> public enum by adding methods just like you can extend a public class. But 
>> just as you cannot subclass a public class, you should not be able to add or 
>> remove cases from a public enum.
>> 
>> 
>>> On Sat, Feb 11, 2017 at 8:37 AM, Adrian Zubarev via swift-evolution 
>>> <[email protected]> wrote:
>>> I have to correct myself here and there.
>>> 
>>> … which would be extensible if that feature might be added to swift one day.
>>> 
>>> Again, I see open only as a contract to allow sub-typing, conformances and 
>>> overriding to the client, where extensibility of a type a story of it’s own.
>>> 
>>> 
>>> -- 
>>> Adrian Zubarev
>>> Sent with Airmail
>>> 
>>> Am 11. Februar 2017 um 15:33:17, Adrian Zubarev 
>>> ([email protected]) schrieb:
>>> 
>>>> It wasn’t my intention to drive to far way off topic with this. The major 
>>>> point of my last bike shedding was that I have to disagree with you about 
>>>> the potential future open enum vs. public enum and closed enum.
>>>> 
>>>> public today does not add any guarantee to prevent the client from 
>>>> extending your type. For instance:
>>>> 
>>>> // Module A
>>>> public class A { public init() {} }
>>>> 
>>>> // Module B
>>>> extension A {
>>>>        
>>>>     convenience init(foo: Int) {
>>>>         print(foo)
>>>>         self.init()
>>>>     }
>>>> }
>>>> That also implies to me that open as an access modifier does not prevent 
>>>> extensibility.
>>>> 
>>>> Speaking of opened enums, we really do not mean open enum to allow 
>>>> extensibility where closed enum would mean the opposite. closed or @closed 
>>>> by all the definitions I’ve read so far is what the current public means 
>>>> for enums. If this is going to be fixed to closed enum (@closed public 
>>>> enum) than what we’re currently speaking of is nothing else than public 
>>>> enum, which would be extensible if that future might be added to swift one 
>>>> day.
>>>> 
>>>> Again, I see open only as a contract to prevent sub-typing, conformances 
>>>> and overriding, where extensibility of a type a story of it’s own.
>>>> 
>>>> Quickly compared to protocols: public-but-not-open protocol from module A 
>>>> should remain extensible in module B. Consistently that would mean that 
>>>> public enum is the enum when we’re talking about future extensibility of 
>>>> that enum from the clients side outside your module. You simply should be 
>>>> able to add new cases directly to your enum if it’s not annotated as 
>>>> closed. open enum on the other hand makes only sense when we’d speak about 
>>>> sub-typing on enums or value types in general.
>>>> 
>>>> 
>>>> 
>>>> -- 
>>>> Adrian Zubarev
>>>> Sent with Airmail
>>>> 
>>>> Am 11. Februar 2017 um 14:08:02, Matthew Johnson ([email protected]) 
>>>> schrieb:
>>>> 
>>>>> 
>>>>> 
>>>>> Sent from my iPad
>>>>> 
>>>>> On Feb 11, 2017, at 4:25 AM, Adrian Zubarev via swift-evolution 
>>>>> <[email protected]> wrote:
>>>>> 
>>>>>> I’m probably better describing things with some bikeshedding code, but 
>>>>>> feel free to criticize it as much as you’d like.
>>>>>> 
>>>>>> //===========--------- Module A ---------===========//
>>>>>> @closed public enum A {
>>>>>>     case a
>>>>>> }
>>>>>> 
>>>>>> extension A {
>>>>>>     case aa // error, because enum is closed
>>>>>> }
>>>>> This is an error because you can't add cases in an extension.  I imagine 
>>>>> this is how cases would be added outside the module if we allow `open 
>>>>> enum` in the future.  But whether or not this is allowed *within* the 
>>>>> module is a separate question that is orthogonal to `closed` and `open`.
>>>>> 
>>>>> 
>>>>>> 
>>>>>> public func foo(a: A) {
>>>>>>     switch a {
>>>>>>     case .a:
>>>>>>         print("done")
>>>>>>     }
>>>>>> }
>>>>>> 
>>>>>> public enum B {
>>>>>>     case b
>>>>>> }
>>>>>> 
>>>>>> extension B {
>>>>>>     case bb // fine, because not-closed enums are extensible
>>>>>> }
>>>>> As noted above, whether this is allowed or not *within* the module is 
>>>>> orthogonal to `closed`.  *Outside* the module it would only be possible 
>>>>> for enum declared `open` (if we add this feature in the future).
>>>>> 
>>>>>> 
>>>>>> public func bar(b: B) {
>>>>>>     switch b {
>>>>>>     case .b:
>>>>>>         print("b")
>>>>>> 
>>>>>>     default: // always needed
>>>>>>         print("some other case")
>>>>>>     }
>>>>>> }
>>>>>> 
>>>>>> // Sub-enum relationships
>>>>>> 
>>>>>> // Possible even the enum A is closed, because `@closed` only     
>>>>>> // closes the extensibility of an enum
>>>>>> enum SubA : A {
>>>>>>     case aa
>>>>>> }
>>>>>> 
>>>>> Now you're talking about value subtypes.  That is orthogonal.  Also, this 
>>>>> syntax already has a meaning (the raw value of the enum is A) so we 
>>>>> wouldn't be able to use it the way you are intending here.  Finally, it 
>>>>> is misleading syntax because what you mean here is "A is a subtype of 
>>>>> SubA" which is exactly the opposite of what the syntax implies.
>>>>> 
>>>>> All values of A are valid values of SubA, but SubA has values that are 
>>>>> not valid values of A.
>>>>> 
>>>>>> // The following enum can have a sub-enum in the clients module
>>>>>> open enum C {
>>>>>>     case c
>>>>>> }
>>>>>> public func cool(c: C) {
>>>>>>     switch c {
>>>>>>     case .c:
>>>>>>         print("c")
>>>>>> 
>>>>>>     default: // always needed
>>>>>>         print("some other case")
>>>>>>     }
>>>>>> }
>>>>>> 
>>>>>> @closed open enum D {
>>>>>>     case d
>>>>>> }
>>>>>> 
>>>>>> public func doo(d: D) {
>>>>>>     switch b {
>>>>>>     case .b:
>>>>>>         print("b")
>>>>>>     }
>>>>>> }
>>>>>> 
>>>>>> // The enum case is always known at any point, no matter     
>>>>>> // where the instance comes from, right?
>>>>>> 
>>>>>> let subA = SubA.aa
>>>>>> let otherSubA = SubA.a // Inherited case
>>>>>> 
>>>>>> let a: A = subA        // error, downgrade the sub-enum to A first
>>>>>> let a: A = otherSubA   // okay
>>>>>> 
>>>>>> foo(a: subA)           // error, downgrade the sub-enum to A first
>>>>>> foo(a: otherSubA)      // okay
>>>>>> 
>>>>>> //===========--------- Module B ---------===========//
>>>>>> 
>>>>>> // Totally fine     
>>>>>> switch A.a {
>>>>>> case .a:
>>>>>>     print("done")
>>>>>> }
>>>>>> 
>>>>>> extension A {
>>>>>>     case aa // not allowed because the enum is closed
>>>>>> }
>>>>>> 
>>>>>> extension B {
>>>>>>     case bbb
>>>>>> }
>>>>>> 
>>>>>> switch B.b {
>>>>>> case .b:
>>>>>>     print("b")
>>>>>> default:     
>>>>>>     print("somethine else")
>>>>>> }
>>>>>> 
>>>>>> bar(b: B.bbb) // fine, because the switch statement on enums without     
>>>>>> // `@closed` has always`default`
>>>>>> 
>>>>>> // Allowed because `C` is open, and open allows sub-typing, conforming   
>>>>>>   
>>>>>> // and overriding to the client
>>>>>> enum SubC : C {
>>>>>>     case cc
>>>>>> }
>>>>>> 
>>>>>> let subC = SubC.cc
>>>>>> 
>>>>>> cool(c: subC) // okay
>>>>>> 
>>>>>> enum SubD : D {
>>>>>>     case dd
>>>>>> }
>>>>>> 
>>>>>> doo(d: D.dd)// error, downgrade sub-enum to D first
>>>>>> My point here is, that we should not think of (possible) open enums as 
>>>>>> enums that the client is allowed to extend. That way we’re only creating 
>>>>>> another inconsistent case for the open access modifier. As far as I can 
>>>>>> tell, open as for today means “the client is allowed to 
>>>>>> subclass/override things from a different module”.
>>>>>> 
>>>>> Yes, but subclasses are analogous to enum cases.  A subtype of an enum 
>>>>> would remove cases.  I think you are misunderstanding the relationship of 
>>>>> enums to classes and protocols.
>>>>> 
>>>>>> And I already said it hundred of times that we should extend this to 
>>>>>> make open a true access modifier in Swift. That said the meaning of open 
>>>>>> should become:
>>>>>> 
>>>>>> The client is allowed to sub-type (currently only classes are supported).
>>>>>> The client is allowed to conform to open protocols
>>>>>> The client is allowed to override open type members
>>>>>> This also means that extensibility is still allowed to public types. 
>>>>>> Public-but-not-open classes are still extensible today, which is the 
>>>>>> correct behavior. Extending an enum which is not closed could or 
>>>>>> probably should be made possible through extensions, because I cannot 
>>>>>> think of anther elegant way for the client to do so.
>>>>>> 
>>>>> This is what `open enum` would allow.  It is the proper enum analogue of 
>>>>> open classes.
>>>>> 
>>>>>> That will leave us the possibility to think of sub-typing enums in the 
>>>>>> future (I sketched it out a little above).
>>>>>> 
>>>>> Value subtyping is very interesting.  I have been working on some ideas 
>>>>> around this but I want to keep this thread focused.
>>>>> 
>>>>>> If I’m not mistaken, every enum case is known at compile time,
>>>>>> 
>>>>> This is true today but will not always be true in the future.  That is in 
>>>>> large part what this thread is about.
>>>>> 
>>>>>> which means to me that we can safely check the case before allowing to 
>>>>>> assign or pass an instance of a sub-enum to some of its super-enum. 
>>>>>> (Downgrading an enum case means that you will have to write some code 
>>>>>> that either mutates your current instance or creates a new one which 
>>>>>> matches one of the super-enum cases.) Furthermore that allows a clear 
>>>>>> distinction of what open access modifier does and how @closed behaves.
>>>>>> 
>>>>> I'm not going to comment on the rest because it is premised on a 
>>>>> misunderstanding of what value subtyping is.  I'm going to share some 
>>>>> ideas around value subtyping in a new thread as soon as I have a chance 
>>>>> to finish putting them together.
>>>>> 
>>>>>> To summarize:
>>>>>> 
>>>>>> @closed enum - you’re not allowed to add new cases to the enum in your 
>>>>>> lib + (you’re allowed to create sub-enums)
>>>>>> @closed public enum - you and the client are not allowed to add new 
>>>>>> cases (+ the client is not allowed to create sub-enums)
>>>>>> @closed open enum - you and the client are not allowed to add new cases 
>>>>>> (+ the client might create new sub-enums)
>>>>>> enum - you’re allowed to add new cases (default is needed in switch 
>>>>>> statements) (+ you can create new sub-enums)
>>>>>> public enum - you and the client are allowed to add new cases (+ only 
>>>>>> you are allowed to create new sub-enums)
>>>>>> open enum - you and the client are allowed to add new cases (everyone 
>>>>>> can create new sub-enums)
>>>>>> This is a lot of bike shedding of mine, and the idea might not even see 
>>>>>> any light in Swift at all, but I’d like to share my ideas with the 
>>>>>> community. Feel free to criticize them or flesh something out into 
>>>>>> something real. :)
>>>>>> 
>>>>>> P.S.: If we had something like this:
>>>>>> 
>>>>>> @closed enum X {
>>>>>>     case x, y
>>>>>>     func foo() {
>>>>>>      switch self {
>>>>>>         case .x, .y:
>>>>>>             print("swift")
>>>>>>     }
>>>>>> }
>>>>>> 
>>>>>> enum Z : X {
>>>>>>     case z, zz
>>>>>>     override func foo() {
>>>>>>         // Iff `self` is `z` or `zz` then calling super will result in 
>>>>>> an error.
>>>>>>         // Possible solution: always tell the client to downgrade 
>>>>>> explicitly the     
>>>>>>         // case first if there is an attempt to call super (if 
>>>>>> mutating),     
>>>>>>         // or handle all cases
>>>>>> 
>>>>>>         switch self {
>>>>>>         case .z, .zz:
>>>>>>             print("custom work")
>>>>>>         default: // or all super-enum cases
>>>>>>             super.foo()
>>>>>>         }
>>>>>>     }
>>>>>> }
>>>>>> 
>>>>>> 
>>>>>> -- 
>>>>>> Adrian Zubarev
>>>>>> Sent with Airmail
>>>>>> 
>>>>>> Am 11. Februar 2017 um 04:49:11, Xiaodi Wu via swift-evolution 
>>>>>> ([email protected]) schrieb:
>>>>>> 
>>>>>>> On Wed, Feb 8, 2017 at 5:05 PM, Matthew Johnson via swift-evolution 
>>>>>>> <[email protected]> wrote:
>>>>>>>> I’ve been thinking a lot about our public access modifier story lately 
>>>>>>>> in the context of both protocols and enums.  I believe we should move 
>>>>>>>> further in the direction we took when introducing the `open` keyword.  
>>>>>>>> I have identified what I think is a promising direction and am 
>>>>>>>> interested in feedback from the community.  If community feedback is 
>>>>>>>> positive I will flesh this out into a more complete proposal draft.
>>>>>>>> 
>>>>>>>> 
>>>>>>>> Background and Motivation:
>>>>>>>> 
>>>>>>>> In Swift 3 we had an extended debate regarding whether or not to allow 
>>>>>>>> inheritance of public classes by default or to require an annotation 
>>>>>>>> for classes that could be subclassed outside the module.  The decision 
>>>>>>>> we reached was to avoid having a default at all, and instead make 
>>>>>>>> `open` an access modifier.  The result is library authors are required 
>>>>>>>> to consider the behavior they wish for each class.  Both behaviors are 
>>>>>>>> equally convenient (neither is penalized by requiring an additional 
>>>>>>>> boilerplate-y annotation).
>>>>>>>> 
>>>>>>>> A recent thread 
>>>>>>>> (https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170206/031566.html)
>>>>>>>>  discussed a similar tradeoff regarding whether public enums should 
>>>>>>>> commit to a fixed set of cases by default or not.  The current 
>>>>>>>> behavior is that they *do* commit to a fixed set of cases and there is 
>>>>>>>> no option (afaik) to modify that behavior.  The Library Evolution 
>>>>>>>> document 
>>>>>>>> (https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst#enums)
>>>>>>>>  suggests a desire to change this before locking down ABI such that 
>>>>>>>> public enums *do not* make this commitment by default, and are 
>>>>>>>> required to opt-in to this behavior using an `@closed` annotation.
>>>>>>>> 
>>>>>>>> In the previous discussion I stated a strong preference that closed 
>>>>>>>> enums *not* be penalized with an additional annotation.  This is 
>>>>>>>> because I feel pretty strongly that it is a design smell to: 1) expose 
>>>>>>>> cases publicly if consumers of the API are not expected to switch on 
>>>>>>>> them and 2) require users to handle unknown future cases if they are 
>>>>>>>> likely to switch over the cases in correct use of the API.
>>>>>>>> 
>>>>>>>> The conclusion I came to in that thread is that we should adopt the 
>>>>>>>> same strategy as we did with classes: there should not be a default.
>>>>>>>> 
>>>>>>>> There have also been several discussions both on the list and via 
>>>>>>>> Twitter regarding whether or not we should allow closed protocols.  In 
>>>>>>>> a recent Twitter discussion Joe Groff suggested that we don’t need 
>>>>>>>> them because we should use an enum when there is a fixed set of 
>>>>>>>> conforming types.  There are at least two  reasons why I still think 
>>>>>>>> we *should* add support for closed protocols.
>>>>>>>> 
>>>>>>>> As noted above (and in the previous thread in more detail), if the set 
>>>>>>>> of types (cases) isn’t intended to be fixed (i.e. the library may add 
>>>>>>>> new types in the future) an enum is likely not a good choice.  Using a 
>>>>>>>> closed protocol discourages the user from switching and prevents the 
>>>>>>>> user from adding conformances that are not desired.
>>>>>>>> 
>>>>>>>> Another use case supported by closed protocols is a design where users 
>>>>>>>> are not allowed to conform directly to a protocol, but instead are 
>>>>>>>> required to conform to one of several protocols which refine the 
>>>>>>>> closed protocol.  Enums are not a substitute for this use case.  The 
>>>>>>>> only option is to resort to documentation and runtime checks.
>>>>>>>> 
>>>>>>>> 
>>>>>>>> Proposal:
>>>>>>>> 
>>>>>>>> This proposal introduces the new access modifier `closed` as well as 
>>>>>>>> clarifying the meaning of `public` and expanding the use of `open`.  
>>>>>>>> This provides consistent capabilities and semantics across enums, 
>>>>>>>> classes and protocols.
>>>>>>>> 
>>>>>>>> `open` is the most permissive modifier.  The symbol is visible outside 
>>>>>>>> the module and both users and future versions of the library are 
>>>>>>>> allowed to add new cases, subclasses or conformances.  (Note: this 
>>>>>>>> proposal does not introduce user-extensible `open` enums, but provides 
>>>>>>>> the syntax that would be used if they are added to the language)
>>>>>>>> 
>>>>>>>> `public` makes the symbol visible without allowing the user to add new 
>>>>>>>> cases, subclasses or conformances.  The library reserves the right to 
>>>>>>>> add new cases, subclasses or conformances in a future version.
>>>>>>>> 
>>>>>>>> `closed` is the most restrictive modifier.  The symbol is visible 
>>>>>>>> publicly with the commitment that future versions of the library are 
>>>>>>>> *also* prohibited from adding new cases, subclasses or conformances.  
>>>>>>>> Additionally, all cases, subclasses or conformances must be visible 
>>>>>>>> outside the module.
>>>>>>>> 
>>>>>>>> Note: the `closed` modifier only applies to *direct* subclasses or 
>>>>>>>> conformances.  A subclass of a `closed` class need not be `closed`, in 
>>>>>>>> fact it may be `open` if the design of the library requires that.  A 
>>>>>>>> class that conforms to a `closed` protocol also need not be `closed`.  
>>>>>>>> It may also be `open`.  Finally, a protocol that refines a `closed` 
>>>>>>>> protocol need not be `closed`.  It may also be `open`.
>>>>>>>> 
>>>>>>>> This proposal is consistent with the principle that libraries should 
>>>>>>>> opt-in to all public API contracts without taking a position on what 
>>>>>>>> that contract should be.  It does this in a way that offers 
>>>>>>>> semantically consistent choices for API contract across classes, enums 
>>>>>>>> and protocols.  The result is that the language allows us to choose 
>>>>>>>> the best tool for the job without restricting the designs we might 
>>>>>>>> consider because some kinds of types are limited with respect to the 
>>>>>>>> `open`, `public` and `closed` semantics a design might require.
>>>>>>>> 
>>>>>>>> 
>>>>>>>> Source compatibility:
>>>>>>>> 
>>>>>>>> This proposal affects both public enums and public protocols.  The 
>>>>>>>> current behavior of enums is equivalent to a `closed` enum under this 
>>>>>>>> proposal and the current behavior of protocols is equivalent to an 
>>>>>>>> `open` protocol under this proposal.  Both changes allow for a simple 
>>>>>>>> mechanical migration, but that may not be sufficient given the source 
>>>>>>>> compatibility promise made for Swift 4.  We may need to identify a 
>>>>>>>> multi-release strategy for adopting this proposal.
>>>>>>>> 
>>>>>>>> Brent Royal-Gordon suggested such a strategy in a discussion regarding 
>>>>>>>> closed protocols on Twitter:
>>>>>>>> 
>>>>>>>> * In Swift 4: all unannotated public protocols receive a warning, 
>>>>>>>> possibly with a fix-it to change the annotation to `open`.
>>>>>>>> * Also in Swift 4: an annotation is introduced to opt-in to the new 
>>>>>>>> `public` behavior.  Brent suggested `@closed`, but as this proposal 
>>>>>>>> distinguishes `public` and `closed` we would need to identify 
>>>>>>>> something else.  I will use `@annotation` as a placeholder.
>>>>>>>> * Also In Swift 4: the `closed` modifier is introduced.
>>>>>>>> 
>>>>>>>> * In Swift 5 the warning becomes a compiler error.  `public protocol` 
>>>>>>>> is not allowed.  Users must use `@annotation public protocol`.
>>>>>>>> * In Swift 6 `public protocol` is allowed again, now with the new 
>>>>>>>> semantics.  `@annotation public protocol` is also allowed, now with a 
>>>>>>>> warning and a fix-it to remove the warning.
>>>>>>>> * In Swift 7 `@annotation public protocol` is no longer allowed.
>>>>>>>> 
>>>>>>>> A similar mult-release strategy would work for migrating public enums.
>>>>>>> 
>>>>>>> A different line of feedback here:
>>>>>>> 
>>>>>>> As per previous reply, I now think if we clarify the mental model of 
>>>>>>> the access modifier hierarchy you're proposing and adopt or reject with 
>>>>>>> that clarity, we'll be fine whether we go with `closed` or with 
>>>>>>> `@closed`. But I don't think the source compatibility strategy you list 
>>>>>>> is the most simple or the most easy to understand for end users.
>>>>>>> 
>>>>>>> - I'll leave aside closed protocols, which as per Jordan Rose's 
>>>>>>> feedback may or may not have sufficient interestingness.
>>>>>>> - With respect to enums, I don't think we need such a drastic whiplash 
>>>>>>> in terms of what will compile in future versions. Instead, we could 
>>>>>>> take a more pragmatic approach:
>>>>>>> 
>>>>>>> 1. In Swift 4, remove the warning (or is it error?) about `default` 
>>>>>>> cases in switch statements over public enums. Simultaneously, add 
>>>>>>> `closed` or `@closed` (whatever is the approved spelling) and start 
>>>>>>> annotating standard library APIs. The annotation will be purely 
>>>>>>> future-proofing and have no functional effect (i.e. the compiler will 
>>>>>>> do nothing differently for a `closed enum` or `@closed public enum` (as 
>>>>>>> the case may be) versus a plain `public enum`).
>>>>>>> 2. In Swift 4.1, _warn_ if switch statements over public enums don't 
>>>>>>> have a `default` statement: offer a fix-it to insert `default: 
>>>>>>> fatalError()` and, if the enum is in the same project, offer a fix-it 
>>>>>>> to insert `closed` or `@closed`.
>>>>>>> 3. In Swift 5, upgrade the warning to an error for non-exhaustiveness 
>>>>>>> if a switch statement over a public enum doesn't have a `default` 
>>>>>>> statement. Now, new syntax to extend an `open enum` can be introduced 
>>>>>>> and the compiler can treat closed and public enums differently.
>>>>>>> 
>>>>>>> _______________________________________________
>>>>>>> swift-evolution mailing list
>>>>>>> [email protected]
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>> 
>>>>>> _______________________________________________
>>>>>> swift-evolution mailing list
>>>>>> [email protected]
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> 
>>> 
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected]
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>> 
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to