> On Jun 29, 2016, at 08:49, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> On Tue, Jun 28, 2016 at 9:06 PM, Jordan Rose via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>> On Jun 28, 2016, at 19:03, Matthew Judge <matthew.ju...@gmail.com 
>> <mailto:matthew.ju...@gmail.com>> wrote:
>> 
>> Comments inline.
>> 
>> On Jun 28, 2016, at 04:14, David Hart via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> Hello everybody,
>>> 
>>> I tried using the access rules defined in SE-0025 in some code of mine to 
>>> see what effect it would have. I came out of the experiment more 
>>> disappointed than I thought. Here are several reasons:
>>> 
>>> 1) The new rules make `private` more prominent compared to `fileprivate` 
>>> (the latter has a somewhat worse name). But at the same time, the Swift 
>>> community has developed a style of coding where a type is defined through a 
>>> set of extensions. To hide members from other types, but have access to 
>>> them inside the type extensions, we have often used `private` and placed 
>>> the type and its extensions in the same file. Because `private` is scoped, 
>>> we are forced into using `fileprivate` pervasively (which is uglier), using 
>>> `internal` instead (which is less safe) or moving the extension code into 
>>> the type's scope (which is against the way Swift code is being written 
>>> today). All of these options look worse to be than before SE-0025.
>> 
>> If I understand SE-0025 (even with the amendment) you can still spell the 
>> access modifier to types as 'private' and get the same characteristics as 
>> the pre-SE-0025 meaning or private, so I'm not sure I understand the concern 
>> here. However (continued below)
>>> 
>>> 2) The new amended rules look complicated to me. I think they have the risk 
>>> of being confusing in practice, but we’ll have to see.
>>> 
>> 
>> I definitely agree that the amended rules look complicated. It seems to me 
>> that the amended set of rules is favoring simplifying the implementation 
>> over simplifying the mental model.
>> 
>> My impression of what SE-0025 decided was that 'private' meant private to 
>> the enclosing scope. If the access modifying 'private' was applied to a type 
>> at the file scope, then it was synonymous with fileprivate and the default 
>> access of members of that type should be fileprivate.
>> 
>> If a inner type was declared private, than the default access of members of 
>> that inner type should be private to the Outer type, not fileprivate. There 
>> is currently no way of expressing this access explicitly, but it does not 
>> seem like an especially useful thing to need to spell.
>> 
>> Said in code, my impression of SE-0025 is that 
>> 
>> private class Outer { // exactly equivalent to fileprivate
>>     var myVar = 0 // default: fileprivate
>>     private class Inner { // private to Outer
>>         var hiddenVar = 0 // default: private to Outer
>>         private var reallyHiddenVar = 0 // default private to Inner
>>     }
>> }
> 
> This is definitely one of the considered alternatives. Both Brent and I 
> didn’t like the idea of an access level that you couldn’t actually spell, and 
> even if we got past that, we’d still need a way to refer to it in 
> documentation and diagnostics. I would count that as a larger change than 
> just allowing ‘fileprivate’ in places that previously would have been called 
> redundant.
> 
> I'm late to the party here, but I share the feeling that perhaps the 
> amendment introduces a complicated mental model. But a lightbulb went off 
> reading the amendment, specifically this parenthetical statement:
> 
> "(The members [defaulting to fileprivate inside a private type] still cannot 
> be accessed outside the enclosing lexical scope because the type itself is 
> still private, i.e. outside code will never encounter a value of that type.)"
> 
> Given that this is the case, wouldn't the same problem be entirely obviated 
> by the following change to the formal rules:
> The default level of access control within any type (public, internal, 
> fileprivate, or private) is `internal`.
> 
> In the case of fileprivate or private types, the `internal` members still 
> cannot be accessed where the containing type cannot be accessed.

That does seem simpler at first, but it doesn’t remove any of the later, more 
complicated rules about minimum access, and when you can use a less accessible 
type in a (formally but not in practice) more-accessible declaration. Once 
those are in place, it seems better to use fileprivate, as the next level up, 
so that we can still warn about mistaken uses of ‘internal’, and so that we 
don’t have to special-case code later on in the pipeline that uses visibility 
to optimize.

(Alternately, I don’t think that’s the part of the mental model people are 
having trouble with.)

Jordan

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

Reply via email to