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
