> On Apr 5, 2017, at 10:30 AM, Chris Lattner via swift-evolution 
> <[email protected]> wrote:
> 
> On Apr 5, 2017, at 5:13 AM, Michel Fortin <[email protected] 
> <mailto:[email protected]>> wrote:
>> 
>>> Le 5 avr. 2017 à 0:02, Chris Lattner via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> a écrit :
>>> 
>>>  - fileprivate should really become much more rare, which makes it more 
>>> meaningful and significant where it occurs.  This was the original idea and 
>>> intent behind SE-0025.
>> 
>> I think this will end up being a flawed assumption, just like last time.
> 
> I’m curious to know why you state this, you seem to agree with it below.
> 
>> Granted: there will be less need for `fileprivate` with this.
> 
> Right, glad to hear that you agree it will become more rare.
> 
>> Files that implement a type will not need `fileprivate` regardless of how 
>> many extensions they use to implement the type. But note that if there is 
>> only one type defined in that file (as is often the case), `private` has 
>> absolutely the same meaning as `fileprivate`.
> 
> Agreed on both points.
> 
>> Files that extend multiple types for the purpose of implementing a 
>> particular feature will still require `fileprivate` if those extensions want 
>> to share some implementation details.
> 
> Right.  That’s the part that makes fileprivate more meaningful.  This was 
> exactly the *purpose* of having fileprivate in the first place.  We want to 
> enable this sort of sharing of private implementation details, but we want to 
> make it explicit at the point of declaration when something like that is 
> going on.

Thanks for jumping in to this thread Chris!  It’s always interesting to hear 
your perspective.

This makes sharing across types within the file more explicit, but it also 
makes state that should be tightly encapsulated less explicit unless you create 
a wrapper type for that state. 

One pattern I have used to good effect is placing this kind of state and the 
basis operations that manipulate it inside the type declaration and placing 
operations defined in terms of the basis operations in extensions on the type 
in the same file.  This pattern no longer works as intended under this 
proposal.  In order to migrate code written this way it is necessary to 
introduce a new type that encapsulates the state and provides the basis 
operations.  This would obviously be a manual migration.  I don’t know how many 
people have adopted styles in Swift 3 that will require manual migration to 
preserve semantics but it is greater than zero.  This is churn that matters and 
shouldn’t be ignored.

I suppose a reasonable argument can be made that requiring encapsulation of 
this kind of state in its own type is a good pattern to that should be 
encouraged.  It certainly calls more attention than the distinction between 
`private` and `fileprivate` by requiring some boilerplate.  The current 
proposal makes sense to me if you assume that this pattern is worth the 
boilerplate because it really stands out.  It means we encourage the “right” 
pattern (again, if you agree this pattern is good) and it means we also call 
special attention to cross-type sharing via `fileprivate` (because as you note 
it will be more rarely used).

On the other hand, if you disagree with the argument that we should have to 
create a new type for this kind of encapsulation then most important question 
becomes whether it is more important to highlight cross-type sharing within the 
file or have the convenience of encapsulating fragile state and highlighting it 
as such without the need to create a new type.  IMO highlighting and tightly 
encapsulating fragile state is a more important concern.

Do we (the community and the core team) want to encourage programmers to create 
new types when this kind of encapsulation is needed rather than requiring on 
lexically scoped access control (that does not cross same-file, same-type 
extension boundaries)?  If yes, then do we think encouraging this and gaining 
the benefit of highlighting same-file, cross-type interactions are big enough 
benefits to offset the “hybrid” (type and scope) access control model and 
another change to the meaning of `private`?

I like the elegance of a purely scope-based access control model and the tight 
encapsulation of lexically scoped access control but I can also see some merit 
in the arguments for this change.  I’m interested in hearing any reactions to 
the lines of reasoning for and against the proposal I have outlined above.

> 
>> 
>>>  - Similarly, this simplifies access control for most people.  Most people 
>>> will now only care about private/internal/public.  fileprivate will become 
>>> an expert feature used in specific cases to solve a specific class of 
>>> problems.  Progressive disclosure of complexity is important.
>> 
>> People who only care about private/internal/public and ignore `fileprivate` 
>> will thus be restricted when it comes to using extensions on multiple types 
>> at the same time. If using `fileprivate`indeed  becomes rare or discouraged, 
>> this will shape the language away from such patterns.
> 
> Again, this is about progressive level of disclosure.  It looks like our QoI 
> isn’t good enough right now, but the expected flow is that you write the 
> invalid code (silly example here):
> 
> struct MyType {
>   private var innards : T
> }
> 
> extension String {
>   func myHelper(x : MyType) {
>      use(x.innards)
>   }
> }
> 
> You get the standard “innards is inaccessible due to private protection 
> level” error message, but that message should have a note w/FixIt attached to 
> it, offering to upgrade innards to fileprivate.
> 
> This approach is exactly why most people won’t have to care about it … until 
> they need it.  At which point, the compiler provides an automatic onramp for 
> them.
> 
>>>  - This design is true to the existing design of Swift: we want to 
>>> encourage the implementation of types to be freely broken into extensions.  
>>> This alignment with extension oriented programming was the one important 
>>> virtue of the Swift 1/2 access control design that Swift 3 lost.
>> 
>> This cut both ways. We want to encourage the implementation of types being 
>> freely broken into extensions. Great!. But do we want to discourage features 
>> implemented as extensions that spans across multiple types?
> 
> We don’t want to discourage them, we want to make them more explicit.  This 
> was the intent of SE-0025, and I think the intent was good.
> 
> -Chris
> 
> 
> _______________________________________________
> 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