Any proposal that seeks to add private conformances needs to answer to the 
dynamic side of Swift, most importantly: What does this return:

let f = Foo()
f is Bar

If the answer is “it depends”, it needs to be explicitly stated where and how.

> On Mar 30, 2017, at 1:07 PM, Ross O'Brien via swift-evolution 
> <[email protected]> wrote:
> 
> This idea was had during the SE-0159 Review regarding removing fileprivate  
> and I'm creating a new discussion thread for its consideration. It's neither 
> in favour of nor against keeping fileprivate, but is intended to address an 
> idiom which has led to some resentment against fileprivate.
> 
> Copy-pasting from my original post on this:
> 
> When we declare a type, we declare properties and functions which that type 
> has.
> When we extend a type, we add functions to the type. (I'm including computed 
> properties in this.)
> It has become an idiom of Swift to declare an extension to a type for each 
> protocol we want it to conform to, for reasons of code organisation and 
> readability. This can be true even if conformance to the protocol was a 
> primary intent of creating the type in the first place.
> 
> The intent of the scoped access level (one use of the current private 
> keyword) is to allow programmers to create properties and functions which are 
> limited to the scope of their declaration. A protocol conformance can be 
> written, with the aid of helper functions, in the confidence that the helper 
> functions are not visible outside the extension, minimising their impact on 
> other components of the module.
> However, some protocol conformances require the type to have a specific 
> property, which the extension cannot facilitate. Some protocol conformances 
> don't require a property, but it would be really useful to have one, and 
> again an extension can't facilitate.
> 
> Example: we want to be able to write this, but we can't:
> 
> private protocol Bar
> {
>   var integer : Int { get }
>   func increment()
> }
> 
> struct Foo
> {
> }
> 
> extension Foo : Bar
> {
>   var integer : Int
> 
>   private var counter : Int
>   func increment()
>   {
>     counter += 1
>   }
> }
> 
> This leads to a workaround: that properties are added to the original type, 
> and declared as fileprivate. They're not intended to be visible to any scope 
> other than the conforming extension - not even, really, to the type's 
> original scope.
> 
> Continuing the example: we've compromised and written this:
> 
> struct Foo
> {
>   fileprivate var integer : Int
>   fileprivate var counter : Int
> }
> 
> extension Foo : Bar
> {
>   func increment()
>   {
>     counter += 1
>   }
> }
> 
> This is not a fault of fileprivate (though it's a clunky name), or private. 
> Renaming these levels does not solve the problem. Removing private, such that 
> everything becomes fileprivate, does not solve the problem. The problem is in 
> the extension system.
> 
> Proposal:
> Suppose we approached extensions differently.
> 
> Suppose we created a 'conformance region' inside a type declaration - a scope 
> nested within the type declaration scope - and that this conformance region 
> had its own access level. It's inside the type declaration, not separate from 
> it like an extension, so we can declare properties inside it. But literally 
> the only properties and functions declared inside the region but visible 
> anywhere outside of it, would be properties and functions declared in the 
> named protocol being conformed to.
> 
> So, visually it might look like this:
> 
> struct Foo
> {
>   conformance Bar // or conformance Foo : Bar, but since the region is inside 
> Foo that's redundant
>   {
>     var integer : Int // visible because Foo : Bar, at Bar's access level
> 
>     var counter : Int = 0 // only visible inside the conformance scope, 
> because not declared in Bar
> 
>     func increment() // visible because Foo : Bar, at Bar's access level
>     {
>       counter += 1
>     }
>   }
> }
> 
> I've introduced a new keyword for this example, conformance, though it may be 
> clear enough to keep using extension. As the extension is inside the type 
> there's no need to redeclare the type being extended. From this example, Foo 
> conforms to Bar, in the same file; it's just been written inside Foo's type 
> declaration, and indented one level, instead of after it.
> 
> Aspects worth considering (some already pointed out by others):
> The original idea for this is that the conformance region exists only to 
> allow the type to conform to a protocol (though possibly more than one), and 
> that only properties and functions declared in those protocols would be 
> accessible outside of the region, at whatever access level the protocol(s) 
> originally declared.
> Existing access terms (internal, fileprivate, etc.) could be used to increase 
> the visibility (to a maximum of the visibility of the declared type, e.g. a 
> public property in a conformance region of an internal type conforming to a 
> fileprivate protocol would be an internally visible property). This would 
> introduce no new keywords.
> However, as this defines a new default level within a region of the language, 
> an explicit keyword might be preferred and a default level of internal might 
> be more intuitive.
> 
> This idea presently assumes that conformance regions do not nest. An inner 
> nested type would be able to declare conformance regions in its declaration, 
> and cannot be extended inside another conformance region of the outer type. 
> However, there might be different thoughts on this?
> 
> We might consider conformance regions in generic types where the associated 
> type meets certain conditions.
> 
> This is an additive pitch. It doesn't affect extensions which 'retroactively' 
> conform types to protocols; it just more visibly identifies active 
> conformances from retroactive conformances.
> The pitch is intended to better express the intent of an existing idiom, 
> which may reduce the frustration users have with fileprivate. It's not a 
> replacement to fileprivate. It may be worth postponing SE-0159's resolution 
> until the effect of this on Swift is seen.
> 
> I've likely missed things from the comments of others since I posted this 
> earlier this week. But I welcome your thoughts.
> 
> Ross
> _______________________________________________
> 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