Idea: Public Access Modifier Respected in Type Definition

Trust me, I'm the last person who wants to rehash access levels in Swift
again. But that's not what's happening here, IMO, and fixing bugs is not
just "a change for the sake of changing."

The current behavior of "private extension" is *incorrect*, because it's
entirely inconsistent with how access levels on extensions are documented
to behave and it's inconsistent with how other access levels apply to
extensions.

Can anyone think of a reason鈥攐ther than "it's too late to change it"鈥攚hy
"private extension" and "fileprivate extension" should behave the same, and
why "X extension { decl }" should be identical to "extension { X decl }"
for all X *except* "private"?

Yes, it's absolutely unfortunate that this oversight was not addressed when
the other access level changes were made. But we shouldn't have to live
with bugs in the language because we're afraid of some unknown amount of
churn among code that is already written incorrectly. Nor is fixing this
bug declaring open season on other, unrelated access level debates. Do you
have data that shows that the amount of code broken because it's using
"private" when it really should be saying "fileprivate" is high enough that
we should just leave the bug there?

路路路

On Wed, Oct 4, 2017 at 9:51 PM Jose Cheyo Jimenez via swift-evolution < swift-evolution@swift.org> wrote:

There was a high bar for breaking changes in swift 4 and is even higher
for swift 5. se-110 was approved and implemented on the premises that it
was not a big change but it was breaking code so it got reverted. Sure the
migrator was making this easier but the result was a usability regression.
I think this is a change just for the sake of changing. This will cause
unnecessary churn. Let鈥檚 leave ACLs alone for the next few versions of
swift unless we have a way better system.

https://lists.swift.org/pipermail/swift-evolution-announce/2017-June/000386.html

On Oct 4, 2017, at 8:47 PM, BJ Homer <bjhomer@gmail.com> wrote:

It certainly could break *some* code. But it only breaks code written by
an author who wrote 鈥榩rivate extension鈥 knowing that 鈥榝ileprivate
extension鈥 was also an option, but still intended it to be shared with the
whole file. (If that code was from Swift 2, it would have already been
migrated to 鈥榝ileprivate extension鈥 by the 2->3 migrator.)

So existing code that says 鈥榩rivate extension鈥 was written in a Swift 3 or
4 era when 鈥榝ileprivate鈥 was an option. If the goal was specifically to
share it with the whole file, it seems likely that most authors would have
used 鈥榝ileprivate extension鈥 instead of 鈥榩rivate extension鈥, as that better
communicates the intention. Regardless, though, we could check against the
Swift source compatibility test suite to see how widespread that is.

Regardless, I think this change makes Swift a better language, and I鈥檓 in
favor of it.

-BJ

On Oct 4, 2017, at 9:10 PM, Jose Cheyo Jimenez via swift-evolution < > swift-evolution@swift.org> wrote:

On Oct 2, 2017, at 9:59 PM, David Hart via swift-evolution < > swift-evolution@swift.org> wrote:

On 3 Oct 2017, at 05:12, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org> wrote:

On Mon, Oct 2, 2017 at 9:16 PM, Matthew Johnson via swift-evolution < > swift-evolution@swift.org> wrote:

Sent from my iPad

On Oct 2, 2017, at 7:33 PM, Jordan Rose via swift-evolution < >> swift-evolution@swift.org> wrote:

On Oct 2, 2017, at 03:25, Vladimir.S via swift-evolution < >> swift-evolution@swift.org> wrote:

On 01.10.2017 1:18, Chris Lattner wrote:

On Sep 29, 2017, at 10:42 AM, Xiaodi Wu via swift-evolution < >> swift-evolution@swift.org> wrote:

Vladimir, I agree with you on that change, but it鈥檚 a separate topic from
this one.

Tony is absolutely correct that this topic has already been discussed. It
is a deliberate design decision that public types do not automatically
expose members without explicit access modifiers; this has been brought up
on this list, and it is clearly not in scope for discussion as no new
insight can arise this late in the game. The inconsistency with public
extensions was brought up, the proposed solution was to remove modifiers
for extensions, but this proposal was rejected. So, the final design is
what we have.

Agreed. The core team would only consider a refinement or change to
access control if there were something actively broken that mattered for
ABI stability.

So we have to live with *protected* extension inconsistency for very long
time just because core team don't want to even discuss _this particular_
inconsistency(when access level in *private extension* must be private, not
fileprivate)?

Yes, we decided that access level for extension will mean a default and
top most access level for nested methods, OK. But even in this rule, which
already differ from access modifiers for types, we have another one special
case for 'private extension'.

Don't you think this is not normal situation and actually there IMO can't
be any reason to keep this bug-producing inconsistency in Swift?
(especially given Swift 5 seems like is a last moment to fix this)

I hate to say it but I'm inclined to agree with Vladimir on this.
"private extension" has a useful meaning now distinct from "fileprivate
extension", and it was an oversight that SE-0169
<https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md> didn't
include a fix here. On this *very narrow, very specific *access control
issue I think it would still be worth discussing; like Xiaodi said it's not
related to James' original thread-starter.

I agree with this in principle but would not want to see it become a
slippery slope back into extremely long access control discussions.

As I've said elsewhere, I too agree with this in principle. I agree with
Jordan that the current state of things is justifiable but the alternative
would be somewhat superior, agree that in a vacuum this very narrow and
specific discussion might be warranted, and agree also that this could be a
very slippery slide down a very steep slope.

Same here. It鈥檚 the only grudge I have left with the current access
control situation. I remember Doug Gregor and John McCall discussing this
during the last access control proposal. And I wouldn鈥檛 mind having a very
narrow discussion about only this.

I organize my types into extensions for each conformance and for each
access control. I can currently implicitly apply public or fileprivate to
all members of an extension but I have no way of doing the same for
private. That鈥檚 why I think it should be fixed.

This will break a bunch of code because `private extension` has *always*
meant `fileprivate extension`. Even Swift 3 had this same behavior. Lowering
the access level of the extension members will hide a bunch of code that
was visible to the file.

169 was not a breaking change but this 鈥渇ix鈥 would have made it a breaking
change. I doubt 169 would had been accepted if it was a breaking change. I
don鈥檛 think it鈥檚 worth it.

https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md

(I maintain that the current model does *not* include a special case; it
simply means the 'private' is resolved at the level of the extension rather
than the level of its members. But that isn't what people expect and it's
not as useful.)

I agree that changing the behavior of *all* access modifiers on
extensions is out of scope. (I also agree that it is a bad idea. Sorry,
James, but wanting 'pubic' here indicates that your mental model of
extensions does not match what Swift is actually doing, and that could get
you into trouble.)

Jordan

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

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

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

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

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

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

I appreciate the enthusiasm but this is not a bug. This was a deliberate change in swift 3 to make `private extension` usable. If this was a bug then during swift 3 we should have disallowed `private extension` and only allowed `fileprivate extension` but that is not what happened. `private extension` has worked the same since swift 1. I鈥檝e always used `private extension` when I want to add methods to String or other build in types.

private is different because it is scoped so because of that it is also different when dealing with extensions. Top level private is always the same as fileprivate thanks to its scoped nature.

Making private the scope ACL was a mistake but that ship has sailed and so has this one imo.

路路路

On Oct 4, 2017, at 10:05 PM, Tony Allevato <tony.allevato@gmail.com> wrote:

Trust me, I'm the last person who wants to rehash access levels in Swift again. But that's not what's happening here, IMO, and fixing bugs is not just "a change for the sake of changing."

The current behavior of "private extension" is *incorrect*, because it's entirely inconsistent with how access levels on extensions are documented to behave and it's inconsistent with how other access levels apply to extensions.

Can anyone think of a reason鈥攐ther than "it's too late to change it"鈥攚hy "private extension" and "fileprivate extension" should behave the same, and why "X extension { decl }" should be identical to "extension { X decl }" for all X *except* "private"?

Yes, it's absolutely unfortunate that this oversight was not addressed when the other access level changes were made. But we shouldn't have to live with bugs in the language because we're afraid of some unknown amount of churn among code that is already written incorrectly. Nor is fixing this bug declaring open season on other, unrelated access level debates. Do you have data that shows that the amount of code broken because it's using "private" when it really should be saying "fileprivate" is high enough that we should just leave the bug there?

On Wed, Oct 4, 2017 at 9:51 PM Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org> wrote:
There was a high bar for breaking changes in swift 4 and is even higher for swift 5. se-110 was approved and implemented on the premises that it was not a big change but it was breaking code so it got reverted. Sure the migrator was making this easier but the result was a usability regression. I think this is a change just for the sake of changing. This will cause unnecessary churn. Let鈥檚 leave ACLs alone for the next few versions of swift unless we have a way better system.

https://lists.swift.org/pipermail/swift-evolution-announce/2017-June/000386.html

On Oct 4, 2017, at 8:47 PM, BJ Homer <bjhomer@gmail.com> wrote:

It certainly could break *some* code. But it only breaks code written by an author who wrote 鈥榩rivate extension鈥 knowing that 鈥榝ileprivate extension鈥 was also an option, but still intended it to be shared with the whole file. (If that code was from Swift 2, it would have already been migrated to 鈥榝ileprivate extension鈥 by the 2->3 migrator.)

So existing code that says 鈥榩rivate extension鈥 was written in a Swift 3 or 4 era when 鈥榝ileprivate鈥 was an option. If the goal was specifically to share it with the whole file, it seems likely that most authors would have used 鈥榝ileprivate extension鈥 instead of 鈥榩rivate extension鈥, as that better communicates the intention. Regardless, though, we could check against the Swift source compatibility test suite to see how widespread that is.

Regardless, I think this change makes Swift a better language, and I鈥檓 in favor of it.

-BJ

On Oct 4, 2017, at 9:10 PM, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org> wrote:

On Oct 2, 2017, at 9:59 PM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

On 3 Oct 2017, at 05:12, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

On Mon, Oct 2, 2017 at 9:16 PM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

Sent from my iPad

On Oct 2, 2017, at 7:33 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

On Oct 2, 2017, at 03:25, Vladimir.S via swift-evolution <swift-evolution@swift.org> wrote:

On 01.10.2017 1:18, Chris Lattner wrote:

On Sep 29, 2017, at 10:42 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

Vladimir, I agree with you on that change, but it鈥檚 a separate topic from this one.

Tony is absolutely correct that this topic has already been discussed. It is a deliberate design decision that public types do not automatically expose members without explicit access modifiers; this has been brought up on this list, and it is clearly not in scope for discussion as no new insight can arise this late in the game. The inconsistency with public extensions was brought up, the proposed solution was to remove modifiers for extensions, but this proposal was rejected. So, the final design is what we have.

Agreed. The core team would only consider a refinement or change to access control if there were something actively broken that mattered for ABI stability.

So we have to live with *protected* extension inconsistency for very long time just because core team don't want to even discuss _this particular_ inconsistency(when access level in *private extension* must be private, not fileprivate)?

Yes, we decided that access level for extension will mean a default and top most access level for nested methods, OK. But even in this rule, which already differ from access modifiers for types, we have another one special case for 'private extension'.

Don't you think this is not normal situation and actually there IMO can't be any reason to keep this bug-producing inconsistency in Swift? (especially given Swift 5 seems like is a last moment to fix this)

I hate to say it but I'm inclined to agree with Vladimir on this. "private extension" has a useful meaning now distinct from "fileprivate extension", and it was an oversight that SE-0169 didn't include a fix here. On this very narrow, very specific access control issue I think it would still be worth discussing; like Xiaodi said it's not related to James' original thread-starter.

I agree with this in principle but would not want to see it become a slippery slope back into extremely long access control discussions.

As I've said elsewhere, I too agree with this in principle. I agree with Jordan that the current state of things is justifiable but the alternative would be somewhat superior, agree that in a vacuum this very narrow and specific discussion might be warranted, and agree also that this could be a very slippery slide down a very steep slope.

Same here. It鈥檚 the only grudge I have left with the current access control situation. I remember Doug Gregor and John McCall discussing this during the last access control proposal. And I wouldn鈥檛 mind having a very narrow discussion about only this.

I organize my types into extensions for each conformance and for each access control. I can currently implicitly apply public or fileprivate to all members of an extension but I have no way of doing the same for private. That鈥檚 why I think it should be fixed.

This will break a bunch of code because `private extension` has always meant `fileprivate extension`. Even Swift 3 had this same behavior. Lowering the access level of the extension members will hide a bunch of code that was visible to the file.

169 was not a breaking change but this 鈥渇ix鈥 would have made it a breaking change. I doubt 169 would had been accepted if it was a breaking change. I don鈥檛 think it鈥檚 worth it.

https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md

(I maintain that the current model does not include a special case; it simply means the 'private' is resolved at the level of the extension rather than the level of its members. But that isn't what people expect and it's not as useful.)

I agree that changing the behavior of all access modifiers on extensions is out of scope. (I also agree that it is a bad idea. Sorry, James, but wanting 'pubic' here indicates that your mental model of extensions does not match what Swift is actually doing, and that could get you into trouble.)

Jordan

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

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

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

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

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

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

Yes, you're right about the history of "private extension"鈥擨 was forgetting
some of the details of what transpired during those proposals. Thanks for
the reminder.

That being said, I would still argue that it would be a shame if we decided
that the language should propagate a known inconsistency indefinitely
simply because it was overlooked during a proposal that could have fixed
it. I'd weigh the reduction of future user confusion as more valuable than
the cost for existing code to do a one-time migration, but that might be
easy for me to say because I don't use access levels on extensions at all
in my own code so I don't have any skin in the game. :slight_smile:

路路路

On Wed, Oct 4, 2017 at 10:33 PM Jose Cheyo Jimenez <cheyo@masters3d.com> wrote:

I appreciate the enthusiasm but this is not a bug. This was a deliberate
change in swift 3 to make `private extension` usable. If this was a bug
then during swift 3 we should have disallowed `private extension` and only
allowed `fileprivate extension` but that is not what happened. `private
extension` has worked the same since swift 1. I鈥檝e always used `private
extension` when I want to add methods to String or other build in types.

private is different because it is scoped so because of that it is also
different when dealing with extensions. Top level private is always the
same as fileprivate thanks to its scoped nature.

Making private the scope ACL was a mistake but that ship has sailed and so
has this one imo.

On Oct 4, 2017, at 10:05 PM, Tony Allevato <tony.allevato@gmail.com> > wrote:

Trust me, I'm the last person who wants to rehash access levels in Swift
again. But that's not what's happening here, IMO, and fixing bugs is not
just "a change for the sake of changing."

The current behavior of "private extension" is *incorrect*, because it's
entirely inconsistent with how access levels on extensions are documented
to behave and it's inconsistent with how other access levels apply to
extensions.

Can anyone think of a reason鈥攐ther than "it's too late to change it"鈥攚hy
"private extension" and "fileprivate extension" should behave the same, and
why "X extension { decl }" should be identical to "extension { X decl }"
for all X *except* "private"?

Yes, it's absolutely unfortunate that this oversight was not addressed
when the other access level changes were made. But we shouldn't have to
live with bugs in the language because we're afraid of some unknown amount
of churn among code that is already written incorrectly. Nor is fixing this
bug declaring open season on other, unrelated access level debates. Do you
have data that shows that the amount of code broken because it's using
"private" when it really should be saying "fileprivate" is high enough that
we should just leave the bug there?

On Wed, Oct 4, 2017 at 9:51 PM Jose Cheyo Jimenez via swift-evolution < > swift-evolution@swift.org> wrote:

There was a high bar for breaking changes in swift 4 and is even higher
for swift 5. se-110 was approved and implemented on the premises that it
was not a big change but it was breaking code so it got reverted. Sure the
migrator was making this easier but the result was a usability regression.
I think this is a change just for the sake of changing. This will cause
unnecessary churn. Let鈥檚 leave ACLs alone for the next few versions of
swift unless we have a way better system.

https://lists.swift.org/pipermail/swift-evolution-announce/2017-June/000386.html

On Oct 4, 2017, at 8:47 PM, BJ Homer <bjhomer@gmail.com> wrote:

It certainly could break *some* code. But it only breaks code written by
an author who wrote 鈥榩rivate extension鈥 knowing that 鈥榝ileprivate
extension鈥 was also an option, but still intended it to be shared with the
whole file. (If that code was from Swift 2, it would have already been
migrated to 鈥榝ileprivate extension鈥 by the 2->3 migrator.)

So existing code that says 鈥榩rivate extension鈥 was written in a Swift 3
or 4 era when 鈥榝ileprivate鈥 was an option. If the goal was specifically to
share it with the whole file, it seems likely that most authors would have
used 鈥榝ileprivate extension鈥 instead of 鈥榩rivate extension鈥, as that better
communicates the intention. Regardless, though, we could check against the
Swift source compatibility test suite to see how widespread that is.

Regardless, I think this change makes Swift a better language, and I鈥檓 in
favor of it.

-BJ

On Oct 4, 2017, at 9:10 PM, Jose Cheyo Jimenez via swift-evolution < >> swift-evolution@swift.org> wrote:

On Oct 2, 2017, at 9:59 PM, David Hart via swift-evolution < >> swift-evolution@swift.org> wrote:

On 3 Oct 2017, at 05:12, Xiaodi Wu via swift-evolution < >> swift-evolution@swift.org> wrote:

On Mon, Oct 2, 2017 at 9:16 PM, Matthew Johnson via swift-evolution < >> swift-evolution@swift.org> wrote:

Sent from my iPad

On Oct 2, 2017, at 7:33 PM, Jordan Rose via swift-evolution < >>> swift-evolution@swift.org> wrote:

On Oct 2, 2017, at 03:25, Vladimir.S via swift-evolution < >>> swift-evolution@swift.org> wrote:

On 01.10.2017 1:18, Chris Lattner wrote:

On Sep 29, 2017, at 10:42 AM, Xiaodi Wu via swift-evolution < >>> swift-evolution@swift.org> wrote:

Vladimir, I agree with you on that change, but it鈥檚 a separate topic
from this one.

Tony is absolutely correct that this topic has already been discussed.
It is a deliberate design decision that public types do not automatically
expose members without explicit access modifiers; this has been brought up
on this list, and it is clearly not in scope for discussion as no new
insight can arise this late in the game. The inconsistency with public
extensions was brought up, the proposed solution was to remove modifiers
for extensions, but this proposal was rejected. So, the final design is
what we have.

Agreed. The core team would only consider a refinement or change to
access control if there were something actively broken that mattered for
ABI stability.

So we have to live with *protected* extension inconsistency for very
long time just because core team don't want to even discuss _this
particular_ inconsistency(when access level in *private extension* must be
private, not fileprivate)?

Yes, we decided that access level for extension will mean a default and
top most access level for nested methods, OK. But even in this rule, which
already differ from access modifiers for types, we have another one special
case for 'private extension'.

Don't you think this is not normal situation and actually there IMO
can't be any reason to keep this bug-producing inconsistency in Swift?
(especially given Swift 5 seems like is a last moment to fix this)

I hate to say it but I'm inclined to agree with Vladimir on this.
"private extension" has a useful meaning now distinct from "fileprivate
extension", and it was an oversight that SE-0169
<https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md> didn't
include a fix here. On this *very narrow, very specific *access control
issue I think it would still be worth discussing; like Xiaodi said it's not
related to James' original thread-starter.

I agree with this in principle but would not want to see it become a
slippery slope back into extremely long access control discussions.

As I've said elsewhere, I too agree with this in principle. I agree with
Jordan that the current state of things is justifiable but the alternative
would be somewhat superior, agree that in a vacuum this very narrow and
specific discussion might be warranted, and agree also that this could be a
very slippery slide down a very steep slope.

Same here. It鈥檚 the only grudge I have left with the current access
control situation. I remember Doug Gregor and John McCall discussing this
during the last access control proposal. And I wouldn鈥檛 mind having a very
narrow discussion about only this.

I organize my types into extensions for each conformance and for each
access control. I can currently implicitly apply public or fileprivate to
all members of an extension but I have no way of doing the same for
private. That鈥檚 why I think it should be fixed.

This will break a bunch of code because `private extension` has *always*
meant `fileprivate extension`. Even Swift 3 had this same behavior. Lowering
the access level of the extension members will hide a bunch of code that
was visible to the file.

169 was not a breaking change but this 鈥渇ix鈥 would have made it a
breaking change. I doubt 169 would had been accepted if it was a breaking
change. I don鈥檛 think it鈥檚 worth it.

https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md

(I maintain that the current model does *not* include a special case;
it simply means the 'private' is resolved at the level of the extension
rather than the level of its members. But that isn't what people expect and
it's not as useful.)

I agree that changing the behavior of *all* access modifiers on
extensions is out of scope. (I also agree that it is a bad idea. Sorry,
James, but wanting 'pubic' here indicates that your mental model of
extensions does not match what Swift is actually doing, and that could get
you into trouble.)

Jordan

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

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

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

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

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

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

I appreciate the enthusiasm but this is not a bug. This was a deliberate change in swift 3 to make `private extension` usable. If this was a bug then during swift 3 we should have disallowed `private extension` and only allowed `fileprivate extension` but that is not what happened. `private extension` has worked the same since swift 1. I鈥檝e always used `private extension` when I want to add methods to String or other build in types.

It鈥檚 not a bug, but its unfortunate the behaviour wasn鈥檛 changed at the same time as SE-0169, and it now is very inconsistent. I also don鈥檛 have to rehash previous discussions, but if a Core Team member (Chris) is okay with going ahead with this, perhaps we should consider it.

路路路

On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org> wrote:

private is different because it is scoped so because of that it is also different when dealing with extensions. Top level private is always the same as fileprivate thanks to its scoped nature.

Making private the scope ACL was a mistake but that ship has sailed and so has this one imo.

On Oct 4, 2017, at 10:05 PM, Tony Allevato <tony.allevato@gmail.com <mailto:tony.allevato@gmail.com>> wrote:

Trust me, I'm the last person who wants to rehash access levels in Swift again. But that's not what's happening here, IMO, and fixing bugs is not just "a change for the sake of changing."

The current behavior of "private extension" is *incorrect*, because it's entirely inconsistent with how access levels on extensions are documented to behave and it's inconsistent with how other access levels apply to extensions.

Can anyone think of a reason鈥攐ther than "it's too late to change it"鈥攚hy "private extension" and "fileprivate extension" should behave the same, and why "X extension { decl }" should be identical to "extension { X decl }" for all X *except* "private"?

Yes, it's absolutely unfortunate that this oversight was not addressed when the other access level changes were made. But we shouldn't have to live with bugs in the language because we're afraid of some unknown amount of churn among code that is already written incorrectly. Nor is fixing this bug declaring open season on other, unrelated access level debates. Do you have data that shows that the amount of code broken because it's using "private" when it really should be saying "fileprivate" is high enough that we should just leave the bug there?

On Wed, Oct 4, 2017 at 9:51 PM Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
There was a high bar for breaking changes in swift 4 and is even higher for swift 5. se-110 was approved and implemented on the premises that it was not a big change but it was breaking code so it got reverted. Sure the migrator was making this easier but the result was a usability regression. I think this is a change just for the sake of changing. This will cause unnecessary churn. Let鈥檚 leave ACLs alone for the next few versions of swift unless we have a way better system.

https://lists.swift.org/pipermail/swift-evolution-announce/2017-June/000386.html

On Oct 4, 2017, at 8:47 PM, BJ Homer <bjhomer@gmail.com <mailto:bjhomer@gmail.com>> wrote:

It certainly could break *some* code. But it only breaks code written by an author who wrote 鈥榩rivate extension鈥 knowing that 鈥榝ileprivate extension鈥 was also an option, but still intended it to be shared with the whole file. (If that code was from Swift 2, it would have already been migrated to 鈥榝ileprivate extension鈥 by the 2->3 migrator.)

So existing code that says 鈥榩rivate extension鈥 was written in a Swift 3 or 4 era when 鈥榝ileprivate鈥 was an option. If the goal was specifically to share it with the whole file, it seems likely that most authors would have used 鈥榝ileprivate extension鈥 instead of 鈥榩rivate extension鈥, as that better communicates the intention. Regardless, though, we could check against the Swift source compatibility test suite to see how widespread that is.

Regardless, I think this change makes Swift a better language, and I鈥檓 in favor of it.

-BJ

On Oct 4, 2017, at 9:10 PM, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Oct 2, 2017, at 9:59 PM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 3 Oct 2017, at 05:12, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mon, Oct 2, 2017 at 9:16 PM, Matthew Johnson via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sent from my iPad

On Oct 2, 2017, at 7:33 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Oct 2, 2017, at 03:25, Vladimir.S via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 01.10.2017 1:18, Chris Lattner wrote:

On Sep 29, 2017, at 10:42 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Vladimir, I agree with you on that change, but it鈥檚 a separate topic from this one.

Tony is absolutely correct that this topic has already been discussed. It is a deliberate design decision that public types do not automatically expose members without explicit access modifiers; this has been brought up on this list, and it is clearly not in scope for discussion as no new insight can arise this late in the game. The inconsistency with public extensions was brought up, the proposed solution was to remove modifiers for extensions, but this proposal was rejected. So, the final design is what we have.

Agreed. The core team would only consider a refinement or change to access control if there were something actively broken that mattered for ABI stability.

So we have to live with *protected* extension inconsistency for very long time just because core team don't want to even discuss _this particular_ inconsistency(when access level in *private extension* must be private, not fileprivate)?

Yes, we decided that access level for extension will mean a default and top most access level for nested methods, OK. But even in this rule, which already differ from access modifiers for types, we have another one special case for 'private extension'.

Don't you think this is not normal situation and actually there IMO can't be any reason to keep this bug-producing inconsistency in Swift? (especially given Swift 5 seems like is a last moment to fix this)

I hate to say it but I'm inclined to agree with Vladimir on this. "private extension" has a useful meaning now distinct from "fileprivate extension", and it was an oversight that SE-0169 <https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md> didn't include a fix here. On this very narrow, very specific access control issue I think it would still be worth discussing; like Xiaodi said it's not related to James' original thread-starter.

I agree with this in principle but would not want to see it become a slippery slope back into extremely long access control discussions.

As I've said elsewhere, I too agree with this in principle. I agree with Jordan that the current state of things is justifiable but the alternative would be somewhat superior, agree that in a vacuum this very narrow and specific discussion might be warranted, and agree also that this could be a very slippery slide down a very steep slope.

Same here. It鈥檚 the only grudge I have left with the current access control situation. I remember Doug Gregor and John McCall discussing this during the last access control proposal. And I wouldn鈥檛 mind having a very narrow discussion about only this.

I organize my types into extensions for each conformance and for each access control. I can currently implicitly apply public or fileprivate to all members of an extension but I have no way of doing the same for private. That鈥檚 why I think it should be fixed.

This will break a bunch of code because `private extension` has always meant `fileprivate extension`. Even Swift 3 had this same behavior. Lowering the access level of the extension members will hide a bunch of code that was visible to the file.

169 was not a breaking change but this 鈥渇ix鈥 would have made it a breaking change. I doubt 169 would had been accepted if it was a breaking change. I don鈥檛 think it鈥檚 worth it.

https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md

(I maintain that the current model does not include a special case; it simply means the 'private' is resolved at the level of the extension rather than the level of its members. But that isn't what people expect and it's not as useful.)

I agree that changing the behavior of all access modifiers on extensions is out of scope. (I also agree that it is a bad idea. Sorry, James, but wanting 'pubic' here indicates that your mental model of extensions does not match what Swift is actually doing, and that could get you into trouble.)

Jordan

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

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

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

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

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

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

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

I appreciate the enthusiasm but this is not a bug. This was a deliberate change in swift 3 to make `private extension` usable. If this was a bug then during swift 3 we should have disallowed `private extension` and only allowed `fileprivate extension` but that is not what happened. `private extension` has worked the same since swift 1. I鈥檝e always used `private extension` when I want to add methods to String or other build in types.

It鈥檚 not a bug, but its unfortunate the behaviour wasn鈥檛 changed at the same time as SE-0169, and it now is very inconsistent. I also don鈥檛 have to rehash previous discussions, but if a Core Team member (Chris) is okay with going ahead with this, perhaps we should consider it.

This could have not been part of 169 because it would've required to lower the visibility of the private extension modifier.

鈥淣o migration will be necessary as this proposal merely broadens the visibility of private.鈥

There was a corner case mentioned when dealing with functions with the same name and that was understandable.

private extension is consistent to the way the private scope rules work. The word private is explicit at the top level because extensions can only be declared at top level. Top level private is always fileprivate. The inconsistency is that we have 1 scope ALC and the rest are not. An explicit declaration should always take precedence when declaring something like an access level override.

路路路

On Oct 5, 2017, at 4:32 AM, David Hart <david@hartbit.com> wrote:

On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

private is different because it is scoped so because of that it is also different when dealing with extensions. Top level private is always the same as fileprivate thanks to its scoped nature.

Making private the scope ACL was a mistake but that ship has sailed and so has this one imo.

On Oct 4, 2017, at 10:05 PM, Tony Allevato <tony.allevato@gmail.com <mailto:tony.allevato@gmail.com>> wrote:

Trust me, I'm the last person who wants to rehash access levels in Swift again. But that's not what's happening here, IMO, and fixing bugs is not just "a change for the sake of changing."

The current behavior of "private extension" is *incorrect*, because it's entirely inconsistent with how access levels on extensions are documented to behave and it's inconsistent with how other access levels apply to extensions.

Can anyone think of a reason鈥攐ther than "it's too late to change it"鈥攚hy "private extension" and "fileprivate extension" should behave the same, and why "X extension { decl }" should be identical to "extension { X decl }" for all X *except* "private"?

Yes, it's absolutely unfortunate that this oversight was not addressed when the other access level changes were made. But we shouldn't have to live with bugs in the language because we're afraid of some unknown amount of churn among code that is already written incorrectly. Nor is fixing this bug declaring open season on other, unrelated access level debates. Do you have data that shows that the amount of code broken because it's using "private" when it really should be saying "fileprivate" is high enough that we should just leave the bug there?

On Wed, Oct 4, 2017 at 9:51 PM Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
There was a high bar for breaking changes in swift 4 and is even higher for swift 5. se-110 was approved and implemented on the premises that it was not a big change but it was breaking code so it got reverted. Sure the migrator was making this easier but the result was a usability regression. I think this is a change just for the sake of changing. This will cause unnecessary churn. Let鈥檚 leave ACLs alone for the next few versions of swift unless we have a way better system.

https://lists.swift.org/pipermail/swift-evolution-announce/2017-June/000386.html

On Oct 4, 2017, at 8:47 PM, BJ Homer <bjhomer@gmail.com <mailto:bjhomer@gmail.com>> wrote:

It certainly could break *some* code. But it only breaks code written by an author who wrote 鈥榩rivate extension鈥 knowing that 鈥榝ileprivate extension鈥 was also an option, but still intended it to be shared with the whole file. (If that code was from Swift 2, it would have already been migrated to 鈥榝ileprivate extension鈥 by the 2->3 migrator.)

So existing code that says 鈥榩rivate extension鈥 was written in a Swift 3 or 4 era when 鈥榝ileprivate鈥 was an option. If the goal was specifically to share it with the whole file, it seems likely that most authors would have used 鈥榝ileprivate extension鈥 instead of 鈥榩rivate extension鈥, as that better communicates the intention. Regardless, though, we could check against the Swift source compatibility test suite to see how widespread that is.

Regardless, I think this change makes Swift a better language, and I鈥檓 in favor of it.

-BJ

On Oct 4, 2017, at 9:10 PM, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Oct 2, 2017, at 9:59 PM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 3 Oct 2017, at 05:12, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mon, Oct 2, 2017 at 9:16 PM, Matthew Johnson via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sent from my iPad

On Oct 2, 2017, at 7:33 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Oct 2, 2017, at 03:25, Vladimir.S via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 01.10.2017 1:18, Chris Lattner wrote:

On Sep 29, 2017, at 10:42 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Vladimir, I agree with you on that change, but it鈥檚 a separate topic from this one.

Tony is absolutely correct that this topic has already been discussed. It is a deliberate design decision that public types do not automatically expose members without explicit access modifiers; this has been brought up on this list, and it is clearly not in scope for discussion as no new insight can arise this late in the game. The inconsistency with public extensions was brought up, the proposed solution was to remove modifiers for extensions, but this proposal was rejected. So, the final design is what we have.

Agreed. The core team would only consider a refinement or change to access control if there were something actively broken that mattered for ABI stability.

So we have to live with *protected* extension inconsistency for very long time just because core team don't want to even discuss _this particular_ inconsistency(when access level in *private extension* must be private, not fileprivate)?

Yes, we decided that access level for extension will mean a default and top most access level for nested methods, OK. But even in this rule, which already differ from access modifiers for types, we have another one special case for 'private extension'.

Don't you think this is not normal situation and actually there IMO can't be any reason to keep this bug-producing inconsistency in Swift? (especially given Swift 5 seems like is a last moment to fix this)

I hate to say it but I'm inclined to agree with Vladimir on this. "private extension" has a useful meaning now distinct from "fileprivate extension", and it was an oversight that SE-0169 <https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md> didn't include a fix here. On this very narrow, very specific access control issue I think it would still be worth discussing; like Xiaodi said it's not related to James' original thread-starter.

I agree with this in principle but would not want to see it become a slippery slope back into extremely long access control discussions.

As I've said elsewhere, I too agree with this in principle. I agree with Jordan that the current state of things is justifiable but the alternative would be somewhat superior, agree that in a vacuum this very narrow and specific discussion might be warranted, and agree also that this could be a very slippery slide down a very steep slope.

Same here. It鈥檚 the only grudge I have left with the current access control situation. I remember Doug Gregor and John McCall discussing this during the last access control proposal. And I wouldn鈥檛 mind having a very narrow discussion about only this.

I organize my types into extensions for each conformance and for each access control. I can currently implicitly apply public or fileprivate to all members of an extension but I have no way of doing the same for private. That鈥檚 why I think it should be fixed.

This will break a bunch of code because `private extension` has always meant `fileprivate extension`. Even Swift 3 had this same behavior. Lowering the access level of the extension members will hide a bunch of code that was visible to the file.

169 was not a breaking change but this 鈥渇ix鈥 would have made it a breaking change. I doubt 169 would had been accepted if it was a breaking change. I don鈥檛 think it鈥檚 worth it.

https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md

(I maintain that the current model does not include a special case; it simply means the 'private' is resolved at the level of the extension rather than the level of its members. But that isn't what people expect and it's not as useful.)

I agree that changing the behavior of all access modifiers on extensions is out of scope. (I also agree that it is a bad idea. Sorry, James, but wanting 'pubic' here indicates that your mental model of extensions does not match what Swift is actually doing, and that could get you into trouble.)

Jordan

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

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

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

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

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

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

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

I appreciate the enthusiasm but this is not a bug. This was a deliberate change in swift 3 to make `private extension` usable. If this was a bug then during swift 3 we should have disallowed `private extension` and only allowed `fileprivate extension` but that is not what happened. `private extension` has worked the same since swift 1. I鈥檝e always used `private extension` when I want to add methods to String or other build in types.

It鈥檚 not a bug, but its unfortunate the behaviour wasn鈥檛 changed at the same time as SE-0169, and it now is very inconsistent. I also don鈥檛 have to rehash previous discussions, but if a Core Team member (Chris) is okay with going ahead with this, perhaps we should consider it.

This could have not been part of 169 because it would've required to lower the visibility of the private extension modifier.

鈥淣o migration will be necessary as this proposal merely broadens the visibility of|private|.鈥

There was a corner case mentioned when dealing with functions with the same name and that was understandable.

private extension is consistent to the way the private scope rules work. The word private is explicit at the top level because extensions can only be declared at top level. Top level private is always fileprivate. The inconsistency is that we have 1 scope ALC and the rest are not. An explicit declaration should always take precedence when declaring something like an access level override.

FWIW, I can't agree with this. 'private extension' is a real point of additional confusion for access levels in Swift.
Extension *by itself* has no access level, we only can specify the *default* (and the top most) access level for inner methods.
I.e. 'private' access modifier for extension has not the same meaning as 'private' func/type/variable at file scope.
(Yes, I also believe we should disallow 'private' keyword at file level and allow it only for extensions, so 'fileprivate' should be used explicitly if one needs this. At least warning should be raised. This is the *root* of the problem we discuss now. But unfortunately I don't expect this could be supported.)
The latter is 'direct' access level for the func/type/variable and here we apply the standard rule for scoped private, so 'private' for file scope --> 'fileprivate'.

The former means 'the default(and top most) modifier that will be auto-inserted by compiler for all nested methods in extension'. This relatively simple rule should not be complicated by additional rule as ", but if it is private extension, result access level will be fileprivate, you can't have extensions with private methods"

And, as was already said, this inconsistency leads to *relaxed* access level, which can lead to bugs. If one expects 'private extension' means 'fileprivate extension' - compiler will show(with error) that this assumption is wrong just after the first attempt to access methods from outside of the extended type.
But if one expects true 'private' access level - the methods from private extension could be called from any other code in the same file(by mistake, or because code was written a long time ago, or by another developer) and this clearly could produce complex bugs.

Also, isn't it a strange code below:

private extension MyType {
聽聽聽func foo() {}
聽聽聽private bar() {}
聽聽聽fileprivate baz() {} // note that "usually" fileprivate is 'wider' access level
}

but it has *currently* a sense - 'foo' is fileprivate, and 'bar' is 'true' private.
Yes, currently we have a warning about 'baz': "warning: declaring a fileprivate instance method in a private extension", but then we have a question "Why?", as private at top level == fileprivate. and this does not produce any warnings:
fileprivate extension MyType {
聽聽fileprivate func foo() {}
}

Even more, someone can think "why we need 'private' declaration in private extension, probably this is a mistake i.e. unnecessary duplication of code, I'll refactor this and delete this explicit 'private' because extension is already private' and so will open doors for future problems.

So I do believe we really need to remove that ugly inconsistency and make Swift better to write, understand and support the code.

Vladimir.

路路路

On 05.10.2017 20:52, Jose Cheyo Jimenez via swift-evolution wrote:

On Oct 5, 2017, at 4:32 AM, David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:

On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org >>> <mailto:swift-evolution@swift.org>> wrote:

private is different because it is scoped so because of that it is also different when dealing with extensions. Top level private is always the same as fileprivate thanks to its scoped nature.

Making private the scope ACL was a mistake but that ship has sailed and so has this one imo.

On Oct 4, 2017, at 10:05 PM, Tony Allevato <tony.allevato@gmail.com <mailto:tony.allevato@gmail.com>> wrote:

Trust me, I'm the last person who wants to rehash access levels in Swift again. But that's not what's happening here, IMO, and fixing bugs is not just "a change for the sake of changing."

The current behavior of "private extension" is *incorrect*, because it's entirely inconsistent with how access levels on extensions are documented to behave and it's inconsistent with how other access levels apply to extensions.

Can anyone think of a reason鈥攐ther than "it's too late to change it"鈥攚hy "private extension" and "fileprivate extension" should behave the same, and why "X extension { decl }" should be identical to "extension { X decl }" for all X *except* "private"?

Yes, it's absolutely unfortunate that this oversight was not addressed when the other access level changes were made. But we shouldn't have to live with bugs in the language because we're afraid of some unknown amount of churn among code that is already written incorrectly. Nor is fixing this bug declaring open season on other, unrelated access level debates. Do you have data that shows that the amount of code broken because it's using "private" when it really should be saying "fileprivate" is high enough that we should just leave the bug there?

On Wed, Oct 4, 2017 at 9:51 PM Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org >>>> <mailto:swift-evolution@swift.org>> wrote:

聽聽聽聽There was a high bar for breaking changes in swift 4 and is even higher for swift 5. se-110 was approved and
聽聽聽聽implemented on the premises that it was not a big change but it was breaking code so it got reverted. Sure the
聽聽聽聽migrator was making this easier but the result was a usability regression. I think this is a change just for the
聽聽聽聽sake of changing. This will cause unnecessary churn. Let鈥檚 leave ACLs alone for the next few versions of swift
聽聽聽聽unless we have a way better system.

聽聽聽聽https://lists.swift.org/pipermail/swift-evolution-announce/2017-June/000386.html

聽聽聽聽On Oct 4, 2017, at 8:47 PM, BJ Homer <bjhomer@gmail.com <mailto:bjhomer@gmail.com>> wrote:

聽聽聽聽It certainly could break *some* code. But it only breaks code written by an author who wrote 鈥榩rivate
聽聽聽聽extension鈥 knowing that 鈥榝ileprivate extension鈥 was also an option, but still intended it to be shared with the
聽聽聽聽whole file. (If that code was from Swift 2, it would have already been migrated to 鈥榝ileprivate extension鈥 by
聽聽聽聽the 2->3 migrator.)

聽聽聽聽So existing code that says 鈥榩rivate extension鈥 was written in a Swift 3 or 4 era when 鈥榝ileprivate鈥 was an
聽聽聽聽option. If the goal was specifically to share it with the whole file, it seems likely that most authors would
聽聽聽聽have used 鈥榝ileprivate extension鈥 instead of 鈥榩rivate extension鈥, as that better communicates the intention.
聽聽聽聽Regardless, though, we could check against the Swift source compatibility test suite to see how widespread that is.

聽聽聽聽Regardless, I think this change makes Swift a better language, and I鈥檓 in favor of it.

聽聽聽聽-BJ

聽聽聽聽On Oct 4, 2017, at 9:10 PM, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org >>>>> <mailto:swift-evolution@swift.org>> wrote:

聽聽聽聽On Oct 2, 2017, at 9:59 PM, David Hart via swift-evolution <swift-evolution@swift.org >>>>>> <mailto:swift-evolution@swift.org>> wrote:

聽聽聽聽On 3 Oct 2017, at 05:12, Xiaodi Wu via swift-evolution <swift-evolution@swift.org >>>>>>> <mailto:swift-evolution@swift.org>> wrote:

聽聽聽聽On Mon, Oct 2, 2017 at 9:16 PM, Matthew Johnson via swift-evolution<swift-evolution@swift.org >>>>>>>> <mailto:swift-evolution@swift.org>>wrote:

聽聽聽聽聽聽聽聽Sent from my iPad

聽聽聽聽聽聽聽聽On Oct 2, 2017, at 7:33 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org >>>>>>>> <mailto:swift-evolution@swift.org>> wrote:

聽聽聽聽聽聽聽聽On Oct 2, 2017, at 03:25, Vladimir.S via swift-evolution <swift-evolution@swift.org >>>>>>>>>> <mailto:swift-evolution@swift.org>> wrote:

聽聽聽聽聽聽聽聽On 01.10.2017 1:18, Chris Lattner wrote:

聽聽聽聽聽聽聽聽On Sep 29, 2017, at 10:42 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org >>>>>>>>>>>> <mailto:swift-evolution@swift.org>> wrote:

聽聽聽聽聽聽聽聽Vladimir, I agree with you on that change, but it鈥檚 a separate topic from this one.

聽聽聽聽聽聽聽聽Tony is absolutely correct that this topic has already been discussed. It is a deliberate design
聽聽聽聽聽聽聽聽decision that public types do not automatically expose members without explicit access modifiers;
聽聽聽聽聽聽聽聽this has been brought up on this list, and it is clearly not in scope for discussion as no new
聽聽聽聽聽聽聽聽insight can arise this late in the game. The inconsistency with public extensions was brought up,
聽聽聽聽聽聽聽聽the proposed solution was to remove modifiers for extensions, but this proposal was rejected. So,
聽聽聽聽聽聽聽聽the final design is what we have.

聽聽聽聽聽聽聽聽Agreed. The core team would only consider a refinement or change to access control if there were
聽聽聽聽聽聽聽聽something actively broken that mattered for ABI stability.

聽聽聽聽聽聽聽聽So we have to live with *protected* extension inconsistency for very long time just because core team
聽聽聽聽聽聽聽聽don't want to even discuss _this particular_ inconsistency(when access level in *private extension*
聽聽聽聽聽聽聽聽must be private, not fileprivate)?

聽聽聽聽聽聽聽聽Yes, we decided that access level for extension will mean a default and top most access level for
聽聽聽聽聽聽聽聽nested methods, OK. But even in this rule, which already differ from access modifiers for types, we
聽聽聽聽聽聽聽聽have another one special case for 'private extension'.

聽聽聽聽聽聽聽聽Don't you think this is not normal situation and actually there IMO can't be any reason to keep this
聽聽聽聽聽聽聽聽bug-producing inconsistency in Swift? (especially given Swift 5 seems like is a last moment to fix this)

聽聽聽聽聽聽聽聽I hate to say it but I'm inclined to agree with Vladimir on this. "private extension" has a useful
聽聽聽聽聽聽聽聽meaning now distinct from "fileprivate extension", and it was an oversight that SE-0169
聽聽聽聽聽聽聽聽<https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md> didn't
聽聽聽聽聽聽聽聽include a fix here. On this/very narrow, very specific/access control issue I think it would still be
聽聽聽聽聽聽聽聽worth discussing; like Xiaodi said it's not related to James' original thread-starter.

聽聽聽聽聽聽聽聽I agree with this in principle but would not want to see it become a slippery slope back into extremely
聽聽聽聽聽聽聽聽long access control discussions.

聽聽聽聽As I've said elsewhere, I too agree with this in principle. I agree with Jordan that the current state of
聽聽聽聽things is justifiable but the alternative would be somewhat superior, agree that in a vacuum this very
聽聽聽聽narrow and specific discussion might be warranted, and agree also that this could be a very slippery slide
聽聽聽聽down a very steep slope.

聽聽聽聽Same here. It鈥檚 the only grudge I have left with the current access control situation. I remember Doug Gregor
聽聽聽聽and John McCall discussing this during the last access control proposal. And I wouldn鈥檛 mind having a very
聽聽聽聽narrow discussion about only this.

聽聽聽聽I organize my types into extensions for each conformance and for each access control. I can currently
聽聽聽聽implicitly apply public or fileprivate to all members of an extension but I have no way of doing the same for
聽聽聽聽private. That鈥檚 why I think it should be fixed.

聽聽聽聽This will break a bunch of code because `private extension` has_always_meant `fileprivate extension`.Even
聽聽聽聽Swift 3 had this same behavior. Lowering the access level of the extension members will hide a bunch of code
聽聽聽聽that was visible to the file.

聽聽聽聽169 was not a breaking change but this 鈥渇ix鈥 would have made it a breaking change. I doubt 169 would had been
聽聽聽聽accepted if it was a breaking change. I don鈥檛 think it鈥檚 worth it.

聽聽聽聽https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md

聽聽聽聽聽聽聽聽(I maintain that the current model does/not/ include a special case; it simply means the 'private' is
聽聽聽聽聽聽聽聽resolved at the level of the extension rather than the level of its members. But that isn't what people
聽聽聽聽聽聽聽聽expect and it's not as useful.)

聽聽聽聽聽聽聽聽I agree that changing the behavior of/all/ access modifiers on extensions is out of scope. (I also
聽聽聽聽聽聽聽聽agree that it is a bad idea. Sorry, James, but wanting 'pubic' here indicates that your mental model of
聽聽聽聽聽聽聽聽extensions does not match what Swift is actually doing, and that could get you into trouble.)

聽聽聽聽聽聽聽聽Jordan

聽聽聽聽聽聽聽聽_______________________________________________
聽聽聽聽聽聽聽聽swift-evolution mailing list
聽聽聽聽聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org>
聽聽聽聽聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽聽聽聽聽聽_______________________________________________
聽聽聽聽聽聽聽聽swift-evolution mailing list
聽聽聽聽聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org>
聽聽聽聽聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽聽_______________________________________________
聽聽聽聽swift-evolution mailing list
聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org>
聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽聽_______________________________________________
聽聽聽聽swift-evolution mailing list
聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org>
聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽聽_______________________________________________
聽聽聽聽swift-evolution mailing list
聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org>
聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽聽_______________________________________________
聽聽聽聽swift-evolution mailing list
聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org>
聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

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

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

I appreciate the enthusiasm but this is not a bug. This was a deliberate change in swift 3 to make `private extension` usable. If this was a bug then during swift 3 we should have disallowed `private extension` and only allowed `fileprivate extension` but that is not what happened. `private extension` has worked the same since swift 1. I鈥檝e always used `private extension` when I want to add methods to String or other build in types.

It鈥檚 not a bug, but its unfortunate the behaviour wasn鈥檛 changed at the same time as SE-0169, and it now is very inconsistent. I also don鈥檛 have to rehash previous discussions, but if a Core Team member (Chris) is okay with going ahead with this, perhaps we should consider it.

This could have not been part of 169 because it would've required to lower the visibility of the private extension modifier.
鈥淣o migration will be necessary as this proposal merely broadens the visibility of|private|.鈥
There was a corner case mentioned when dealing with functions with the same name and that was understandable.
private extension is consistent to the way the private scope rules work. The word private is explicit at the top level because extensions can only be declared at top level. Top level private is always fileprivate. The inconsistency is that we have 1 scope ALC and the rest are not. An explicit declaration should always take precedence when declaring something like an access level override.

FWIW, I can't agree with this. 'private extension' is a real point of additional confusion for access levels in Swift.
Extension *by itself* has no access level, we only can specify the *default* (and the top most) access level for inner methods.
I.e. 'private' access modifier for extension has not the same meaning as 'private' func/type/variable at file scope.
(Yes, I also believe we should disallow 'private' keyword at file level and allow it only for extensions, so 'fileprivate' should be used explicitly if one needs this. At least warning should be raised. This is the *root* of the problem we discuss now. But unfortunately I don't expect this could be supported.)

Wouldn't that just add a special rule to extensions? :slight_smile:

The latter is 'direct' access level for the func/type/variable and here we apply the standard rule for scoped private, so 'private' for file scope --> 'fileprivate'.

The former means 'the default(and top most) modifier that will be auto-inserted by compiler for all nested methods in extension'. This relatively simple rule should not be complicated by additional rule as ", but if it is private extension, result access level will be fileprivate, you can't have extensions with private methods鈥

Private as it exist in swift now is the scope access control label. The compiler does not insert the modifier without having to first compute what access control level would be applied to the members of the extension. Doing it the other way would be counterintuitive for an scope access label. In my code base I disallow top level fileprivate because private top level is fileprivate. This is a matter of taste and a linter here would help like a mentioned up thread.

And, as was already said, this inconsistency leads to *relaxed* access level, which can lead to bugs. If one expects 'private extension' means 'fileprivate extension' - compiler will show(with error) that this assumption is wrong just after the first attempt to access methods from outside of the extended type.
But if one expects true 'private' access level - the methods from private extension could be called from any other code in the same file(by mistake, or because code was written a long time ago, or by another developer) and this clearly could produce complex bugs.

Also, isn't it a strange code below:

private extension MyType {
func foo() {}
private bar() {}
fileprivate baz() {} // note that "usually" fileprivate is 'wider' access level
}

This is also strange too :slight_smile:

fileprivate class MyType {
聽聽open func foo(){} // Is this open or fileprivate?
聽聽public func bar(){}
}

open class MyType2 {
}

open extension MyType2 { // Error: Extensions cannot use 'open' as their default access; use 'public'
聽聽聽聽func baz(){}
}

but it has *currently* a sense - 'foo' is fileprivate, and 'bar' is 'true' private.
Yes, currently we have a warning about 'baz': "warning: declaring a fileprivate instance method in a private extension", but then we have a question "Why?", as private at top level == fileprivate. and this does not produce any warnings:
fileprivate extension MyType {
聽聽fileprivate func foo() {}
}

Even more, someone can think "why we need 'private' declaration in private extension, probably this is a mistake i.e. unnecessary duplication of code, I'll refactor this and delete this explicit 'private' because extension is already private' and so will open doors for future problems.

So I do believe we really need to remove that ugly inconsistency and make Swift better to write, understand and support the code.

This is matter of taste. For example I think fileprivate is ugly and having both private and fileprivate makes the code hard to understand.

路路路

On Oct 6, 2017, at 7:10 AM, Vladimir.S <svabox@gmail.com> wrote:
On 05.10.2017 20:52, Jose Cheyo Jimenez via swift-evolution wrote:

On Oct 5, 2017, at 4:32 AM, David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:

On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Vladimir.

private is different because it is scoped so because of that it is also different when dealing with extensions. Top level private is always the same as fileprivate thanks to its scoped nature.

Making private the scope ACL was a mistake but that ship has sailed and so has this one imo.

On Oct 4, 2017, at 10:05 PM, Tony Allevato <tony.allevato@gmail.com <mailto:tony.allevato@gmail.com>> wrote:

Trust me, I'm the last person who wants to rehash access levels in Swift again. But that's not what's happening here, IMO, and fixing bugs is not just "a change for the sake of changing."

The current behavior of "private extension" is *incorrect*, because it's entirely inconsistent with how access levels on extensions are documented to behave and it's inconsistent with how other access levels apply to extensions.

Can anyone think of a reason鈥攐ther than "it's too late to change it"鈥攚hy "private extension" and "fileprivate extension" should behave the same, and why "X extension { decl }" should be identical to "extension { X decl }" for all X *except* "private"?

Yes, it's absolutely unfortunate that this oversight was not addressed when the other access level changes were made. But we shouldn't have to live with bugs in the language because we're afraid of some unknown amount of churn among code that is already written incorrectly. Nor is fixing this bug declaring open season on other, unrelated access level debates. Do you have data that shows that the amount of code broken because it's using "private" when it really should be saying "fileprivate" is high enough that we should just leave the bug there?

On Wed, Oct 4, 2017 at 9:51 PM Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

聽聽聽There was a high bar for breaking changes in swift 4 and is even higher for swift 5. se-110 was approved and
聽聽聽implemented on the premises that it was not a big change but it was breaking code so it got reverted. Sure the
聽聽聽migrator was making this easier but the result was a usability regression. I think this is a change just for the
聽聽聽sake of changing. This will cause unnecessary churn. Let鈥檚 leave ACLs alone for the next few versions of swift
聽聽聽unless we have a way better system.

聽聽聽https://lists.swift.org/pipermail/swift-evolution-announce/2017-June/000386.html

聽聽聽On Oct 4, 2017, at 8:47 PM, BJ Homer <bjhomer@gmail.com <mailto:bjhomer@gmail.com>> wrote:

聽聽聽It certainly could break *some* code. But it only breaks code written by an author who wrote 鈥榩rivate
聽聽聽extension鈥 knowing that 鈥榝ileprivate extension鈥 was also an option, but still intended it to be shared with the
聽聽聽whole file. (If that code was from Swift 2, it would have already been migrated to 鈥榝ileprivate extension鈥 by
聽聽聽the 2->3 migrator.)

聽聽聽So existing code that says 鈥榩rivate extension鈥 was written in a Swift 3 or 4 era when 鈥榝ileprivate鈥 was an
聽聽聽option. If the goal was specifically to share it with the whole file, it seems likely that most authors would
聽聽聽have used 鈥榝ileprivate extension鈥 instead of 鈥榩rivate extension鈥, as that better communicates the intention.
聽聽聽Regardless, though, we could check against the Swift source compatibility test suite to see how widespread that is.

聽聽聽Regardless, I think this change makes Swift a better language, and I鈥檓 in favor of it.

聽聽聽-BJ

聽聽聽On Oct 4, 2017, at 9:10 PM, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org >>>>>> <mailto:swift-evolution@swift.org>> wrote:

聽聽聽On Oct 2, 2017, at 9:59 PM, David Hart via swift-evolution <swift-evolution@swift.org >>>>>>> <mailto:swift-evolution@swift.org>> wrote:

聽聽聽On 3 Oct 2017, at 05:12, Xiaodi Wu via swift-evolution <swift-evolution@swift.org >>>>>>>> <mailto:swift-evolution@swift.org>> wrote:

聽聽聽On Mon, Oct 2, 2017 at 9:16 PM, Matthew Johnson via swift-evolution<swift-evolution@swift.org >>>>>>>>> <mailto:swift-evolution@swift.org>>wrote:

聽聽聽聽聽聽聽Sent from my iPad

聽聽聽聽聽聽聽On Oct 2, 2017, at 7:33 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org >>>>>>>>> <mailto:swift-evolution@swift.org>> wrote:

聽聽聽聽聽聽聽On Oct 2, 2017, at 03:25, Vladimir.S via swift-evolution <swift-evolution@swift.org >>>>>>>>>>> <mailto:swift-evolution@swift.org>> wrote:

聽聽聽聽聽聽聽On 01.10.2017 1:18, Chris Lattner wrote:

聽聽聽聽聽聽聽On Sep 29, 2017, at 10:42 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org >>>>>>>>>>>>> <mailto:swift-evolution@swift.org>> wrote:

聽聽聽聽聽聽聽Vladimir, I agree with you on that change, but it鈥檚 a separate topic from this one.

聽聽聽聽聽聽聽Tony is absolutely correct that this topic has already been discussed. It is a deliberate design
聽聽聽聽聽聽聽decision that public types do not automatically expose members without explicit access modifiers;
聽聽聽聽聽聽聽this has been brought up on this list, and it is clearly not in scope for discussion as no new
聽聽聽聽聽聽聽insight can arise this late in the game. The inconsistency with public extensions was brought up,
聽聽聽聽聽聽聽the proposed solution was to remove modifiers for extensions, but this proposal was rejected. So,
聽聽聽聽聽聽聽the final design is what we have.

聽聽聽聽聽聽聽Agreed. The core team would only consider a refinement or change to access control if there were
聽聽聽聽聽聽聽something actively broken that mattered for ABI stability.

聽聽聽聽聽聽聽So we have to live with *protected* extension inconsistency for very long time just because core team
聽聽聽聽聽聽聽don't want to even discuss _this particular_ inconsistency(when access level in *private extension*
聽聽聽聽聽聽聽must be private, not fileprivate)?

聽聽聽聽聽聽聽Yes, we decided that access level for extension will mean a default and top most access level for
聽聽聽聽聽聽聽nested methods, OK. But even in this rule, which already differ from access modifiers for types, we
聽聽聽聽聽聽聽have another one special case for 'private extension'.

聽聽聽聽聽聽聽Don't you think this is not normal situation and actually there IMO can't be any reason to keep this
聽聽聽聽聽聽聽bug-producing inconsistency in Swift? (especially given Swift 5 seems like is a last moment to fix this)

聽聽聽聽聽聽聽I hate to say it but I'm inclined to agree with Vladimir on this. "private extension" has a useful
聽聽聽聽聽聽聽meaning now distinct from "fileprivate extension", and it was an oversight that SE-0169
聽聽聽聽聽聽聽<https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md> didn't
聽聽聽聽聽聽聽include a fix here. On this/very narrow, very specific/access control issue I think it would still be
聽聽聽聽聽聽聽worth discussing; like Xiaodi said it's not related to James' original thread-starter.

聽聽聽聽聽聽聽I agree with this in principle but would not want to see it become a slippery slope back into extremely
聽聽聽聽聽聽聽long access control discussions.

聽聽聽As I've said elsewhere, I too agree with this in principle. I agree with Jordan that the current state of
聽聽聽things is justifiable but the alternative would be somewhat superior, agree that in a vacuum this very
聽聽聽narrow and specific discussion might be warranted, and agree also that this could be a very slippery slide
聽聽聽down a very steep slope.

聽聽聽Same here. It鈥檚 the only grudge I have left with the current access control situation. I remember Doug Gregor
聽聽聽and John McCall discussing this during the last access control proposal. And I wouldn鈥檛 mind having a very
聽聽聽narrow discussion about only this.

聽聽聽I organize my types into extensions for each conformance and for each access control. I can currently
聽聽聽implicitly apply public or fileprivate to all members of an extension but I have no way of doing the same for
聽聽聽private. That鈥檚 why I think it should be fixed.

聽聽聽This will break a bunch of code because `private extension` has_always_meant `fileprivate extension`.Even
聽聽聽Swift 3 had this same behavior. Lowering the access level of the extension members will hide a bunch of code
聽聽聽that was visible to the file.

聽聽聽169 was not a breaking change but this 鈥渇ix鈥 would have made it a breaking change. I doubt 169 would had been
聽聽聽accepted if it was a breaking change. I don鈥檛 think it鈥檚 worth it.

聽聽聽https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md

聽聽聽聽聽聽聽(I maintain that the current model does/not/ include a special case; it simply means the 'private' is
聽聽聽聽聽聽聽resolved at the level of the extension rather than the level of its members. But that isn't what people
聽聽聽聽聽聽聽expect and it's not as useful.)

聽聽聽聽聽聽聽I agree that changing the behavior of/all/ access modifiers on extensions is out of scope. (I also
聽聽聽聽聽聽聽agree that it is a bad idea. Sorry, James, but wanting 'pubic' here indicates that your mental model of
聽聽聽聽聽聽聽extensions does not match what Swift is actually doing, and that could get you into trouble.)

聽聽聽聽聽聽聽Jordan

聽聽聽聽聽聽聽_______________________________________________
聽聽聽聽聽聽聽swift-evolution mailing list
聽聽聽聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org>
聽聽聽聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽聽聽聽聽_______________________________________________
聽聽聽聽聽聽聽swift-evolution mailing list
聽聽聽聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org>
聽聽聽聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

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

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

These exceed the confines of the narrow discussion we are trying to have
here about private extensions. We are not going to rehash the ugliness of
fileprivate.

路路路

On Fri, Oct 6, 2017 at 12:16 Jose Cheyo Jimenez via swift-evolution < swift-evolution@swift.org> wrote:

On Oct 6, 2017, at 7:10 AM, Vladimir.S <svabox@gmail.com> wrote:

On 05.10.2017 20:52, Jose Cheyo Jimenez via swift-evolution wrote:

On Oct 5, 2017, at 4:32 AM, David Hart <david@hartbit.com < > mailto:david@hartbit.com <david@hartbit.com>>> wrote:

On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution < > swift-evolution@swift.org <mailto:swift-evolution@swift.org > <swift-evolution@swift.org>>> wrote:

I appreciate the enthusiasm but this is not a bug. This was a deliberate
change in swift 3 to make `private extension` usable. If this was a bug
then during swift 3 we should have disallowed `private extension` and only
allowed `fileprivate extension` but that is not what happened. `private
extension` has worked the same since swift 1. I鈥檝e always used `private
extension` when I want to add methods to String or other build in types.

It鈥檚 not a bug, but its unfortunate the behaviour wasn鈥檛 changed at the
same time as SE-0169, and it now is very inconsistent. I also don鈥檛 have to
rehash previous discussions, but if a Core Team member (Chris) is okay with
going ahead with this, perhaps we should consider it.

This could have not been part of 169 because it would've required to lower
the visibility of the private extension modifier.
鈥淣o migration will be necessary as this proposal merely broadens the
visibility of|private|.鈥
There was a corner case mentioned when dealing with functions with the
same name and that was understandable.
private extension is consistent to the way the private scope rules work.
The word private is explicit at the top level because extensions can only
be declared at top level. Top level private is always fileprivate. The
inconsistency is that we have 1 scope ALC and the rest are not. An explicit
declaration should always take precedence when declaring something like an
access level override.

FWIW, I can't agree with this. 'private extension' is a real point of
additional confusion for access levels in Swift.
Extension *by itself* has no access level, we only can specify the
*default* (and the top most) access level for inner methods.
I.e. 'private' access modifier for extension has not the same meaning as
'private' func/type/variable at file scope.
(Yes, I also believe we should disallow 'private' keyword at file level
and allow it only for extensions, so 'fileprivate' should be used
explicitly if one needs this. At least warning should be raised. This is
the *root* of the problem we discuss now. But unfortunately I don't expect
this could be supported.)

Wouldn't that just add a *special* rule to extensions? :slight_smile:

The latter is 'direct' access level for the func/type/variable and here we
apply the standard rule for scoped private, so 'private' for file scope -->
'fileprivate'.

The former means 'the default(and top most) modifier that will be
auto-inserted by compiler for all nested methods in extension'. This
relatively simple rule should not be complicated by additional rule as ",
but if it is private extension, result access level will be fileprivate,
you can't have extensions with private methods鈥

Private as it exist in swift now is the scope access control label. The
compiler does not insert the modifier without having to first compute what
access control level would be applied to the members of the extension.
Doing it the other way would be counterintuitive for an scope access label.
In my code base I disallow top level fileprivate because private top level
is fileprivate. This is a matter of taste and a linter here would help like
a mentioned up thread.

And, as was already said, this inconsistency leads to *relaxed* access
level, which can lead to bugs. If one expects 'private extension' means
'fileprivate extension' - compiler will show(with error) that this
assumption is wrong just after the first attempt to access methods from
outside of the extended type.
But if one expects true 'private' access level - the methods from private
extension could be called from any other code in the same file(by mistake,
or because code was written a long time ago, or by another developer) and
this clearly could produce complex bugs.

Also, isn't it a strange code below:

private extension MyType {
func foo() {}
private bar() {}
fileprivate baz() {} // note that "usually" fileprivate is 'wider' access
level
}

This is also strange too :slight_smile:

fileprivate class MyType {
聽聽open func foo(){} // Is this open or fileprivate?
聽聽public func bar(){}
}

open class MyType2 {
}

open extension MyType2 { // Error: Extensions cannot use 'open' as their
default access; use 'public'
聽聽聽聽func baz(){}
}

but it has *currently* a sense - 'foo' is fileprivate, and 'bar' is 'true'
private.
Yes, currently we have a warning about 'baz': "warning: declaring a
fileprivate instance method in a private extension", but then we have a
question "Why?", as private at top level == fileprivate. and this does not
produce any warnings:
fileprivate extension MyType {
fileprivate func foo() {}
}

Even more, someone can think "why we need 'private' declaration in private
extension, probably this is a mistake i.e. unnecessary duplication of code,
I'll refactor this and delete this explicit 'private' because extension is
already private' and so will open doors for future problems.

So I do believe we really need to remove that ugly inconsistency and make
Swift better to write, understand and support the code.

This is matter of taste. For example I think fileprivate is ugly and
having both private and fileprivate makes the code hard to understand.

Vladimir.

private is different because it is scoped so because of that it is also
different when dealing with extensions. Top level private is always the
same as fileprivate thanks to its scoped nature.

Making private the scope ACL was a mistake but that ship has sailed and so
has this one imo.

On Oct 4, 2017, at 10:05 PM, Tony Allevato <tony.allevato@gmail.com < > mailto:tony.allevato@gmail.com <tony.allevato@gmail.com>>> wrote:

Trust me, I'm the last person who wants to rehash access levels in Swift
again. But that's not what's happening here, IMO, and fixing bugs is not
just "a change for the sake of changing."

The current behavior of "private extension" is *incorrect*, because it's
entirely inconsistent with how access levels on extensions are documented
to behave and it's inconsistent with how other access levels apply to
extensions.

Can anyone think of a reason鈥攐ther than "it's too late to change it"鈥攚hy
"private extension" and "fileprivate extension" should behave the same, and
why "X extension { decl }" should be identical to "extension { X decl }"
for all X *except* "private"?

Yes, it's absolutely unfortunate that this oversight was not addressed
when the other access level changes were made. But we shouldn't have to
live with bugs in the language because we're afraid of some unknown amount
of churn among code that is already written incorrectly. Nor is fixing this
bug declaring open season on other, unrelated access level debates. Do you
have data that shows that the amount of code broken because it's using
"private" when it really should be saying "fileprivate" is high enough that
we should just leave the bug there?

On Wed, Oct 4, 2017 at 9:51 PM Jose Cheyo Jimenez via swift-evolution < > swift-evolution@swift.org <mailto:swift-evolution@swift.org > <swift-evolution@swift.org>>> wrote:

聽聽聽There was a high bar for breaking changes in swift 4 and is even higher
for swift 5. se-110 was approved and
聽聽聽implemented on the premises that it was not a big change but it was
breaking code so it got reverted. Sure the
聽聽聽migrator was making this easier but the result was a usability
regression. I think this is a change just for the
聽聽聽sake of changing. This will cause unnecessary churn. Let鈥檚 leave ACLs
alone for the next few versions of swift
聽聽聽unless we have a way better system.

https://lists.swift.org/pipermail/swift-evolution-announce/2017-June/000386.html

聽聽聽On Oct 4, 2017, at 8:47 PM, BJ Homer <bjhomer@gmail.com < > mailto:bjhomer@gmail.com <bjhomer@gmail.com>>> wrote:

聽聽聽It certainly could break *some* code. But it only breaks code written
by an author who wrote 鈥榩rivate
聽聽聽extension鈥 knowing that 鈥榝ileprivate extension鈥 was also an option, but
still intended it to be shared with the
聽聽聽whole file. (If that code was from Swift 2, it would have already been
migrated to 鈥榝ileprivate extension鈥 by
聽聽聽the 2->3 migrator.)

聽聽聽So existing code that says 鈥榩rivate extension鈥 was written in a Swift 3
or 4 era when 鈥榝ileprivate鈥 was an
聽聽聽option. If the goal was specifically to share it with the whole file,
it seems likely that most authors would
聽聽聽have used 鈥榝ileprivate extension鈥 instead of 鈥榩rivate extension鈥, as
that better communicates the intention.
聽聽聽Regardless, though, we could check against the Swift source
compatibility test suite to see how widespread that is.

聽聽聽Regardless, I think this change makes Swift a better language, and I鈥檓
in favor of it.

聽聽聽-BJ

聽聽聽On Oct 4, 2017, at 9:10 PM, Jose Cheyo Jimenez via swift-evolution < > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> wrote:

聽聽聽On Oct 2, 2017, at 9:59 PM, David Hart via swift-evolution < > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> wrote:

聽聽聽On 3 Oct 2017, at 05:12, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> wrote:

聽聽聽On Mon, Oct 2, 2017 at 9:16 PM, Matthew Johnson via swift-evolution< > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>>wrote:

聽聽聽聽聽聽聽Sent from my iPad

聽聽聽聽聽聽聽On Oct 2, 2017, at 7:33 PM, Jordan Rose via swift-evolution < > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> > wrote:

聽聽聽聽聽聽聽On Oct 2, 2017, at 03:25, Vladimir.S via swift-evolution < > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> > wrote:

聽聽聽聽聽聽聽On 01.10.2017 1:18, Chris Lattner wrote:

聽聽聽聽聽聽聽On Sep 29, 2017, at 10:42 AM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> > wrote:

聽聽聽聽聽聽聽Vladimir, I agree with you on that change, but it鈥檚 a separate
topic from this one.

聽聽聽聽聽聽聽Tony is absolutely correct that this topic has already been
discussed. It is a deliberate design
聽聽聽聽聽聽聽decision that public types do not automatically expose members
without explicit access modifiers;
聽聽聽聽聽聽聽this has been brought up on this list, and it is clearly not in
scope for discussion as no new
聽聽聽聽聽聽聽insight can arise this late in the game. The inconsistency with
public extensions was brought up,
聽聽聽聽聽聽聽the proposed solution was to remove modifiers for extensions, but
this proposal was rejected. So,
聽聽聽聽聽聽聽the final design is what we have.

聽聽聽聽聽聽聽Agreed. The core team would only consider a refinement or change
to access control if there were
聽聽聽聽聽聽聽something actively broken that mattered for ABI stability.

聽聽聽聽聽聽聽So we have to live with *protected* extension inconsistency for
very long time just because core team
聽聽聽聽聽聽聽don't want to even discuss _this particular_ inconsistency(when
access level in *private extension*
聽聽聽聽聽聽聽must be private, not fileprivate)?

聽聽聽聽聽聽聽Yes, we decided that access level for extension will mean a default
and top most access level for
聽聽聽聽聽聽聽nested methods, OK. But even in this rule, which already differ
from access modifiers for types, we
聽聽聽聽聽聽聽have another one special case for 'private extension'.

聽聽聽聽聽聽聽Don't you think this is not normal situation and actually there IMO
can't be any reason to keep this
聽聽聽聽聽聽聽bug-producing inconsistency in Swift? (especially given Swift 5
seems like is a last moment to fix this)

聽聽聽聽聽聽聽I hate to say it but I'm inclined to agree with Vladimir on this.
"private extension" has a useful
聽聽聽聽聽聽聽meaning now distinct from "fileprivate extension", and it was an
oversight that SE-0169
聽聽聽聽聽聽聽<
https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md>
didn't
聽聽聽聽聽聽聽include a fix here. On this/very narrow, very specific/access
control issue I think it would still be
聽聽聽聽聽聽聽worth discussing; like Xiaodi said it's not related to James'
original thread-starter.

聽聽聽聽聽聽聽I agree with this in principle but would not want to see it become
a slippery slope back into extremely
聽聽聽聽聽聽聽long access control discussions.

聽聽聽As I've said elsewhere, I too agree with this in principle. I agree
with Jordan that the current state of
聽聽聽things is justifiable but the alternative would be somewhat superior,
agree that in a vacuum this very
聽聽聽narrow and specific discussion might be warranted, and agree also that
this could be a very slippery slide
聽聽聽down a very steep slope.

聽聽聽Same here. It鈥檚 the only grudge I have left with the current access
control situation. I remember Doug Gregor
聽聽聽and John McCall discussing this during the last access control
proposal. And I wouldn鈥檛 mind having a very
聽聽聽narrow discussion about only this.

聽聽聽I organize my types into extensions for each conformance and for each
access control. I can currently
聽聽聽implicitly apply public or fileprivate to all members of an extension
but I have no way of doing the same for
聽聽聽private. That鈥檚 why I think it should be fixed.

聽聽聽This will break a bunch of code because `private extension`
has_always_meant `fileprivate extension`.Even
聽聽聽Swift 3 had this same behavior. Lowering the access level of the
extension members will hide a bunch of code
聽聽聽that was visible to the file.

聽聽聽169 was not a breaking change but this 鈥渇ix鈥 would have made it a
breaking change. I doubt 169 would had been
聽聽聽accepted if it was a breaking change. I don鈥檛 think it鈥檚 worth it.

https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md

聽聽聽聽聽聽聽(I maintain that the current model does/not/ include a special
case; it simply means the 'private' is
聽聽聽聽聽聽聽resolved at the level of the extension rather than the level of its
members. But that isn't what people
聽聽聽聽聽聽聽expect and it's not as useful.)

聽聽聽聽聽聽聽I agree that changing the behavior of/all/ access modifiers on
extensions is out of scope. (I also
聽聽聽聽聽聽聽agree that it is a bad idea. Sorry, James, but wanting 'pubic' here
indicates that your mental model of
聽聽聽聽聽聽聽extensions does not match what Swift is actually doing, and that
could get you into trouble.)

聽聽聽聽聽聽聽Jordan

聽聽聽聽聽聽聽_______________________________________________
聽聽聽聽聽聽聽swift-evolution mailing list
聽聽聽聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽聽聽聽聽_______________________________________________
聽聽聽聽聽聽聽swift-evolution mailing list
聽聽聽聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

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

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

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

I appreciate the enthusiasm but this is not a bug. This was a deliberate
change in swift 3 to make `private extension` usable. If this was a bug
then during swift 3 we should have disallowed `private extension` and only
allowed `fileprivate extension` but that is not what happened. `private
extension` has worked the same since swift 1. I鈥檝e always used `private
extension` when I want to add methods to String or other build in types.

It鈥檚 not a bug, but its unfortunate the behaviour wasn鈥檛 changed at the
same time as SE-0169, and it now is very inconsistent. I also don鈥檛 have to
rehash previous discussions, but if a Core Team member (Chris) is okay with
going ahead with this, perhaps we should consider it.

This could have not been part of 169 because it would've required to lower
the visibility of the private extension modifier.
鈥淣o migration will be necessary as this proposal merely broadens the
visibility of|private|.鈥
There was a corner case mentioned when dealing with functions with the
same name and that was understandable.
private extension is consistent to the way the private scope rules work.
The word private is explicit at the top level because extensions can only
be declared at top level. Top level private is always fileprivate. The
inconsistency is that we have 1 scope ALC and the rest are not. An explicit
declaration should always take precedence when declaring something like an
access level override.

FWIW, I can't agree with this. 'private extension' is a real point of
additional confusion for access levels in Swift.
Extension *by itself* has no access level, we only can specify the
*default* (and the top most) access level for inner methods.
I.e. 'private' access modifier for extension has not the same meaning as
'private' func/type/variable at file scope.
(Yes, I also believe we should disallow 'private' keyword at file level
and allow it only for extensions, so 'fileprivate' should be used
explicitly if one needs this. At least warning should be raised. This is
the *root* of the problem we discuss now. But unfortunately I don't expect
this could be supported.)

Wouldn't that just add a *special* rule to extensions? :slight_smile:

The latter is 'direct' access level for the func/type/variable and here we
apply the standard rule for scoped private, so 'private' for file scope -->
'fileprivate'.

The former means 'the default(and top most) modifier that will be
auto-inserted by compiler for all nested methods in extension'. This
relatively simple rule should not be complicated by additional rule as ",
but if it is private extension, result access level will be fileprivate,
you can't have extensions with private methods鈥

Private as it exist in swift now is the scope access control label. The
compiler does not insert the modifier without having to first compute what
access control level would be applied to the members of the extension.
Doing it the other way would be counterintuitive for an scope access label.
In my code base I disallow top level fileprivate because private top level
is fileprivate. This is a matter of taste and a linter here would help like
a mentioned up thread.

This is the sticking point, which is why there are two possible
interpretations of "private extension":

Choice 1) Attach-then-evaluate. "ACL extension { ... }" is a syntactic
shortcut for "extension { ACL ... }". Under that definition, the ACL is
evaluated as if it were attached to each declaration, so "private
extension" would expand to "private" in front of each decl.

Choice 2) Evaluate-then-attach. "ACL extension { ... }" is evaluated such
that "ACL" takes on the meaning based on its scope; since it's equivalent
to "fileprivate" there, that is what is attached to each declaration inside
the extension.

The phrasing in the official Swift language guide doesn't specifically
state it, but I think most readers would interpret the following as #1:

"Alternatively, you can mark an extension with an explicit access-level
modifier (for example, `private extension`) to set a new default access
level for all members defined within the extension."

I personally find that choice to be the clearer interpretation of the rule,
because it's based entirely on what words are in the source file and not
about how they interact in special edge cases.

I also think it's hard to rationalize "private extension" working like #2
because compared to #1, it's both duplicative ("private extension" and
"fileprivate extension" are awkwardly the same) _and_ it is strictly less
flexible (there is _no_ way using that syntax to define an extension whose
members are private, which is an inconsistent hole in the language).

路路路

On Fri, Oct 6, 2017 at 10:16 AM Jose Cheyo Jimenez via swift-evolution < swift-evolution@swift.org> wrote:

On Oct 6, 2017, at 7:10 AM, Vladimir.S <svabox@gmail.com> wrote:
On 05.10.2017 20:52, Jose Cheyo Jimenez via swift-evolution wrote:
On Oct 5, 2017, at 4:32 AM, David Hart <david@hartbit.com < > mailto:david@hartbit.com <david@hartbit.com>>> wrote:
On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution < > swift-evolution@swift.org <mailto:swift-evolution@swift.org > <swift-evolution@swift.org>>> wrote:

And, as was already said, this inconsistency leads to *relaxed* access
level, which can lead to bugs. If one expects 'private extension' means
'fileprivate extension' - compiler will show(with error) that this
assumption is wrong just after the first attempt to access methods from
outside of the extended type.
But if one expects true 'private' access level - the methods from private
extension could be called from any other code in the same file(by mistake,
or because code was written a long time ago, or by another developer) and
this clearly could produce complex bugs.

Also, isn't it a strange code below:

private extension MyType {
func foo() {}
private bar() {}
fileprivate baz() {} // note that "usually" fileprivate is 'wider' access
level
}

This is also strange too :slight_smile:

fileprivate class MyType {
聽聽open func foo(){} // Is this open or fileprivate?
聽聽public func bar(){}
}

open class MyType2 {
}

open extension MyType2 { // Error: Extensions cannot use 'open' as their
default access; use 'public'
聽聽聽聽func baz(){}
}

but it has *currently* a sense - 'foo' is fileprivate, and 'bar' is 'true'
private.
Yes, currently we have a warning about 'baz': "warning: declaring a
fileprivate instance method in a private extension", but then we have a
question "Why?", as private at top level == fileprivate. and this does not
produce any warnings:
fileprivate extension MyType {
fileprivate func foo() {}
}

Even more, someone can think "why we need 'private' declaration in private
extension, probably this is a mistake i.e. unnecessary duplication of code,
I'll refactor this and delete this explicit 'private' because extension is
already private' and so will open doors for future problems.

So I do believe we really need to remove that ugly inconsistency and make
Swift better to write, understand and support the code.

This is matter of taste. For example I think fileprivate is ugly and
having both private and fileprivate makes the code hard to understand.

Vladimir.

private is different because it is scoped so because of that it is also
different when dealing with extensions. Top level private is always the
same as fileprivate thanks to its scoped nature.

Making private the scope ACL was a mistake but that ship has sailed and so
has this one imo.

On Oct 4, 2017, at 10:05 PM, Tony Allevato <tony.allevato@gmail.com < > mailto:tony.allevato@gmail.com <tony.allevato@gmail.com>>> wrote:

Trust me, I'm the last person who wants to rehash access levels in Swift
again. But that's not what's happening here, IMO, and fixing bugs is not
just "a change for the sake of changing."

The current behavior of "private extension" is *incorrect*, because it's
entirely inconsistent with how access levels on extensions are documented
to behave and it's inconsistent with how other access levels apply to
extensions.

Can anyone think of a reason鈥攐ther than "it's too late to change it"鈥攚hy
"private extension" and "fileprivate extension" should behave the same, and
why "X extension { decl }" should be identical to "extension { X decl }"
for all X *except* "private"?

Yes, it's absolutely unfortunate that this oversight was not addressed
when the other access level changes were made. But we shouldn't have to
live with bugs in the language because we're afraid of some unknown amount
of churn among code that is already written incorrectly. Nor is fixing this
bug declaring open season on other, unrelated access level debates. Do you
have data that shows that the amount of code broken because it's using
"private" when it really should be saying "fileprivate" is high enough that
we should just leave the bug there?

On Wed, Oct 4, 2017 at 9:51 PM Jose Cheyo Jimenez via swift-evolution < > swift-evolution@swift.org <mailto:swift-evolution@swift.org > <swift-evolution@swift.org>>> wrote:

聽聽聽There was a high bar for breaking changes in swift 4 and is even higher
for swift 5. se-110 was approved and
聽聽聽implemented on the premises that it was not a big change but it was
breaking code so it got reverted. Sure the
聽聽聽migrator was making this easier but the result was a usability
regression. I think this is a change just for the
聽聽聽sake of changing. This will cause unnecessary churn. Let鈥檚 leave ACLs
alone for the next few versions of swift
聽聽聽unless we have a way better system.

https://lists.swift.org/pipermail/swift-evolution-announce/2017-June/000386.html

聽聽聽On Oct 4, 2017, at 8:47 PM, BJ Homer <bjhomer@gmail.com < > mailto:bjhomer@gmail.com <bjhomer@gmail.com>>> wrote:

聽聽聽It certainly could break *some* code. But it only breaks code written
by an author who wrote 鈥榩rivate
聽聽聽extension鈥 knowing that 鈥榝ileprivate extension鈥 was also an option, but
still intended it to be shared with the
聽聽聽whole file. (If that code was from Swift 2, it would have already been
migrated to 鈥榝ileprivate extension鈥 by
聽聽聽the 2->3 migrator.)

聽聽聽So existing code that says 鈥榩rivate extension鈥 was written in a Swift 3
or 4 era when 鈥榝ileprivate鈥 was an
聽聽聽option. If the goal was specifically to share it with the whole file,
it seems likely that most authors would
聽聽聽have used 鈥榝ileprivate extension鈥 instead of 鈥榩rivate extension鈥, as
that better communicates the intention.
聽聽聽Regardless, though, we could check against the Swift source
compatibility test suite to see how widespread that is.

聽聽聽Regardless, I think this change makes Swift a better language, and I鈥檓
in favor of it.

聽聽聽-BJ

聽聽聽On Oct 4, 2017, at 9:10 PM, Jose Cheyo Jimenez via swift-evolution < > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> wrote:

聽聽聽On Oct 2, 2017, at 9:59 PM, David Hart via swift-evolution < > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> wrote:

聽聽聽On 3 Oct 2017, at 05:12, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> wrote:

聽聽聽On Mon, Oct 2, 2017 at 9:16 PM, Matthew Johnson via swift-evolution< > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>>wrote:

聽聽聽聽聽聽聽Sent from my iPad

聽聽聽聽聽聽聽On Oct 2, 2017, at 7:33 PM, Jordan Rose via swift-evolution < > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> > wrote:

聽聽聽聽聽聽聽On Oct 2, 2017, at 03:25, Vladimir.S via swift-evolution < > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> > wrote:

聽聽聽聽聽聽聽On 01.10.2017 1:18, Chris Lattner wrote:

聽聽聽聽聽聽聽On Sep 29, 2017, at 10:42 AM, Xiaodi Wu via swift-evolution < > swift-evolution@swift.org > <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> > wrote:

聽聽聽聽聽聽聽Vladimir, I agree with you on that change, but it鈥檚 a separate
topic from this one.

聽聽聽聽聽聽聽Tony is absolutely correct that this topic has already been
discussed. It is a deliberate design
聽聽聽聽聽聽聽decision that public types do not automatically expose members
without explicit access modifiers;
聽聽聽聽聽聽聽this has been brought up on this list, and it is clearly not in
scope for discussion as no new
聽聽聽聽聽聽聽insight can arise this late in the game. The inconsistency with
public extensions was brought up,
聽聽聽聽聽聽聽the proposed solution was to remove modifiers for extensions, but
this proposal was rejected. So,
聽聽聽聽聽聽聽the final design is what we have.

聽聽聽聽聽聽聽Agreed. The core team would only consider a refinement or change
to access control if there were
聽聽聽聽聽聽聽something actively broken that mattered for ABI stability.

聽聽聽聽聽聽聽So we have to live with *protected* extension inconsistency for
very long time just because core team
聽聽聽聽聽聽聽don't want to even discuss _this particular_ inconsistency(when
access level in *private extension*
聽聽聽聽聽聽聽must be private, not fileprivate)?

聽聽聽聽聽聽聽Yes, we decided that access level for extension will mean a default
and top most access level for
聽聽聽聽聽聽聽nested methods, OK. But even in this rule, which already differ
from access modifiers for types, we
聽聽聽聽聽聽聽have another one special case for 'private extension'.

聽聽聽聽聽聽聽Don't you think this is not normal situation and actually there IMO
can't be any reason to keep this
聽聽聽聽聽聽聽bug-producing inconsistency in Swift? (especially given Swift 5
seems like is a last moment to fix this)

聽聽聽聽聽聽聽I hate to say it but I'm inclined to agree with Vladimir on this.
"private extension" has a useful
聽聽聽聽聽聽聽meaning now distinct from "fileprivate extension", and it was an
oversight that SE-0169
聽聽聽聽聽聽聽<
https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md>
didn't
聽聽聽聽聽聽聽include a fix here. On this/very narrow, very specific/access
control issue I think it would still be
聽聽聽聽聽聽聽worth discussing; like Xiaodi said it's not related to James'
original thread-starter.

聽聽聽聽聽聽聽I agree with this in principle but would not want to see it become
a slippery slope back into extremely
聽聽聽聽聽聽聽long access control discussions.

聽聽聽As I've said elsewhere, I too agree with this in principle. I agree
with Jordan that the current state of
聽聽聽things is justifiable but the alternative would be somewhat superior,
agree that in a vacuum this very
聽聽聽narrow and specific discussion might be warranted, and agree also that
this could be a very slippery slide
聽聽聽down a very steep slope.

聽聽聽Same here. It鈥檚 the only grudge I have left with the current access
control situation. I remember Doug Gregor
聽聽聽and John McCall discussing this during the last access control
proposal. And I wouldn鈥檛 mind having a very
聽聽聽narrow discussion about only this.

聽聽聽I organize my types into extensions for each conformance and for each
access control. I can currently
聽聽聽implicitly apply public or fileprivate to all members of an extension
but I have no way of doing the same for
聽聽聽private. That鈥檚 why I think it should be fixed.

聽聽聽This will break a bunch of code because `private extension`
has_always_meant `fileprivate extension`.Even
聽聽聽Swift 3 had this same behavior. Lowering the access level of the
extension members will hide a bunch of code
聽聽聽that was visible to the file.

聽聽聽169 was not a breaking change but this 鈥渇ix鈥 would have made it a
breaking change. I doubt 169 would had been
聽聽聽accepted if it was a breaking change. I don鈥檛 think it鈥檚 worth it.

https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md

聽聽聽聽聽聽聽(I maintain that the current model does/not/ include a special
case; it simply means the 'private' is
聽聽聽聽聽聽聽resolved at the level of the extension rather than the level of its
members. But that isn't what people
聽聽聽聽聽聽聽expect and it's not as useful.)

聽聽聽聽聽聽聽I agree that changing the behavior of/all/ access modifiers on
extensions is out of scope. (I also
聽聽聽聽聽聽聽agree that it is a bad idea. Sorry, James, but wanting 'pubic' here
indicates that your mental model of
聽聽聽聽聽聽聽extensions does not match what Swift is actually doing, and that
could get you into trouble.)

聽聽聽聽聽聽聽Jordan

聽聽聽聽聽聽聽_______________________________________________
聽聽聽聽聽聽聽swift-evolution mailing list
聽聽聽聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽聽聽聽聽_______________________________________________
聽聽聽聽聽聽聽swift-evolution mailing list
聽聽聽聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

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

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

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

I appreciate the enthusiasm but this is not a bug. This was a deliberate change in swift 3 to make `private extension` usable. If this was a bug then during swift 3 we should have disallowed `private extension` and only allowed `fileprivate extension` but that is not what happened. `private extension` has worked the same since swift 1. I鈥檝e always used `private extension` when I want to add methods to String or other build in types.

It鈥檚 not a bug, but its unfortunate the behaviour wasn鈥檛 changed at the same time as SE-0169, and it now is very inconsistent. I also don鈥檛 have to rehash previous discussions, but if a Core Team member (Chris) is okay with going ahead with this, perhaps we should consider it.

This could have not been part of 169 because it would've required to lower the visibility of the private extension modifier.
鈥淣o migration will be necessary as this proposal merely broadens the visibility of|private|.鈥
There was a corner case mentioned when dealing with functions with the same name and that was understandable.
private extension is consistent to the way the private scope rules work. The word private is explicit at the top level because extensions can only be declared at top level. Top level private is always fileprivate. The inconsistency is that we have 1 scope ALC and the rest are not. An explicit declaration should always take precedence when declaring something like an access level override.

FWIW, I can't agree with this. 'private extension' is a real point of additional confusion for access levels in Swift.
Extension *by itself* has no access level, we only can specify the *default* (and the top most) access level for inner methods.
I.e. 'private' access modifier for extension has not the same meaning as 'private' func/type/variable at file scope.
(Yes, I also believe we should disallow 'private' keyword at file level and allow it only for extensions, so 'fileprivate' should be used explicitly if one needs this. At least warning should be raised. This is the *root* of the problem we discuss now. But unfortunately I don't expect this could be supported.)

Wouldn't that just add a special rule to extensions? :slight_smile:

The latter is 'direct' access level for the func/type/variable and here we apply the standard rule for scoped private, so 'private' for file scope --> 'fileprivate'.

The former means 'the default(and top most) modifier that will be auto-inserted by compiler for all nested methods in extension'. This relatively simple rule should not be complicated by additional rule as ", but if it is private extension, result access level will be fileprivate, you can't have extensions with private methods鈥

Private as it exist in swift now is the scope access control label. The compiler does not insert the modifier without having to first compute what access control level would be applied to the members of the extension. Doing it the other way would be counterintuitive for an scope access label. In my code base I disallow top level fileprivate because private top level is fileprivate. This is a matter of taste and a linter here would help like a mentioned up thread.

This is the sticking point, which is why there are two possible interpretations of "private extension":

Choice 1) Attach-then-evaluate. "ACL extension { ... }" is a syntactic shortcut for "extension { ACL ... }". Under that definition, the ACL is evaluated as if it were attached to each declaration, so "private extension" would expand to "private" in front of each decl.

Choice 2) Evaluate-then-attach. "ACL extension { ... }" is evaluated such that "ACL" takes on the meaning based on its scope; since it's equivalent to "fileprivate" there, that is what is attached to each declaration inside the extension.

Yep. This is the issue. Nice summary!

The phrasing in the official Swift language guide doesn't specifically state it, but I think most readers would interpret the following as #1:

"Alternatively, you can mark an extension with an explicit access-level modifier (for example, `private extension`) to set a new default access level for all members defined within the extension."

I personally find that choice to be the clearer interpretation of the rule, because it's based entirely on what words are in the source file and not about how they interact in special edge cases.

Documentation is hard to keep in sync.
https://github.com/apple/swift-evolution/blob/master/proposals/0025-scoped-access-level.md#complications-with-private-types

I also think it's hard to rationalize "private extension" working like #2 because compared to #1, it's both duplicative ("private extension" and "fileprivate extension" are awkwardly the same) _and_ it is strictly less flexible (there is _no_ way using that syntax to define an extension whose members are private, which is an inconsistent hole in the language).

This compiles on an Xcode 9 playground. SE-0025 doesn't only affect extensions.
``MyClass.myFunc()` looks like (Choice 2) to me. Same as `private extension MyClass2`.

private class MyClass {
聽聽聽聽static func myFunc(){
聽聽聽聽聽聽聽聽print(鈥淎cts likes fileprivate")
聽聽聽聽}
}

private class MyClass2 {
}

private extension MyClass2{
聽聽聽聽static func myFunc2(){
聽聽聽聽聽聽聽print("Same as MyClass.myFunc")
聽聽聽聽}
}

MyClass.myFunc() // Acts likes fileprivate
MyClass2.myFunc2() // Same as MyClass.myFunc

路路路

On Oct 6, 2017, at 11:07 AM, Tony Allevato <tony.allevato@gmail.com> wrote:
On Fri, Oct 6, 2017 at 10:16 AM Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Oct 6, 2017, at 7:10 AM, Vladimir.S <svabox@gmail.com <mailto:svabox@gmail.com>> wrote:
On 05.10.2017 20:52, Jose Cheyo Jimenez via swift-evolution wrote:

On Oct 5, 2017, at 4:32 AM, David Hart <david@hartbit.com <mailto:david@hartbit.com><mailto:david@hartbit.com <mailto:david@hartbit.com>>> wrote:

On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> wrote:

And, as was already said, this inconsistency leads to *relaxed* access level, which can lead to bugs. If one expects 'private extension' means 'fileprivate extension' - compiler will show(with error) that this assumption is wrong just after the first attempt to access methods from outside of the extended type.
But if one expects true 'private' access level - the methods from private extension could be called from any other code in the same file(by mistake, or because code was written a long time ago, or by another developer) and this clearly could produce complex bugs.

Also, isn't it a strange code below:

private extension MyType {
func foo() {}
private bar() {}
fileprivate baz() {} // note that "usually" fileprivate is 'wider' access level
}

This is also strange too :slight_smile:

fileprivate class MyType {
聽聽open func foo(){} // Is this open or fileprivate?
聽聽public func bar(){}
}

open class MyType2 {
}

open extension MyType2 { // Error: Extensions cannot use 'open' as their default access; use 'public'
聽聽聽聽func baz(){}
}

but it has *currently* a sense - 'foo' is fileprivate, and 'bar' is 'true' private.
Yes, currently we have a warning about 'baz': "warning: declaring a fileprivate instance method in a private extension", but then we have a question "Why?", as private at top level == fileprivate. and this does not produce any warnings:
fileprivate extension MyType {
聽聽fileprivate func foo() {}
}

Even more, someone can think "why we need 'private' declaration in private extension, probably this is a mistake i.e. unnecessary duplication of code, I'll refactor this and delete this explicit 'private' because extension is already private' and so will open doors for future problems.

So I do believe we really need to remove that ugly inconsistency and make Swift better to write, understand and support the code.

This is matter of taste. For example I think fileprivate is ugly and having both private and fileprivate makes the code hard to understand.

Vladimir.

private is different because it is scoped so because of that it is also different when dealing with extensions. Top level private is always the same as fileprivate thanks to its scoped nature.

Making private the scope ACL was a mistake but that ship has sailed and so has this one imo.

On Oct 4, 2017, at 10:05 PM, Tony Allevato <tony.allevato@gmail.com <mailto:tony.allevato@gmail.com> <mailto:tony.allevato@gmail.com <mailto:tony.allevato@gmail.com>>> wrote:

Trust me, I'm the last person who wants to rehash access levels in Swift again. But that's not what's happening here, IMO, and fixing bugs is not just "a change for the sake of changing."

The current behavior of "private extension" is *incorrect*, because it's entirely inconsistent with how access levels on extensions are documented to behave and it's inconsistent with how other access levels apply to extensions.

Can anyone think of a reason鈥攐ther than "it's too late to change it"鈥攚hy "private extension" and "fileprivate extension" should behave the same, and why "X extension { decl }" should be identical to "extension { X decl }" for all X *except* "private"?

Yes, it's absolutely unfortunate that this oversight was not addressed when the other access level changes were made. But we shouldn't have to live with bugs in the language because we're afraid of some unknown amount of churn among code that is already written incorrectly. Nor is fixing this bug declaring open season on other, unrelated access level debates. Do you have data that shows that the amount of code broken because it's using "private" when it really should be saying "fileprivate" is high enough that we should just leave the bug there?

On Wed, Oct 4, 2017 at 9:51 PM Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> wrote:

聽聽聽There was a high bar for breaking changes in swift 4 and is even higher for swift 5. se-110 was approved and
聽聽聽implemented on the premises that it was not a big change but it was breaking code so it got reverted. Sure the
聽聽聽migrator was making this easier but the result was a usability regression. I think this is a change just for the
聽聽聽sake of changing. This will cause unnecessary churn. Let鈥檚 leave ACLs alone for the next few versions of swift
聽聽聽unless we have a way better system.

聽聽聽https://lists.swift.org/pipermail/swift-evolution-announce/2017-June/000386.html

聽聽聽On Oct 4, 2017, at 8:47 PM, BJ Homer <bjhomer@gmail.com <mailto:bjhomer@gmail.com><mailto:bjhomer@gmail.com <mailto:bjhomer@gmail.com>>> wrote:

聽聽聽It certainly could break *some* code. But it only breaks code written by an author who wrote 鈥榩rivate
聽聽聽extension鈥 knowing that 鈥榝ileprivate extension鈥 was also an option, but still intended it to be shared with the
聽聽聽whole file. (If that code was from Swift 2, it would have already been migrated to 鈥榝ileprivate extension鈥 by
聽聽聽the 2->3 migrator.)

聽聽聽So existing code that says 鈥榩rivate extension鈥 was written in a Swift 3 or 4 era when 鈥榝ileprivate鈥 was an
聽聽聽option. If the goal was specifically to share it with the whole file, it seems likely that most authors would
聽聽聽have used 鈥榝ileprivate extension鈥 instead of 鈥榩rivate extension鈥, as that better communicates the intention.
聽聽聽Regardless, though, we could check against the Swift source compatibility test suite to see how widespread that is.

聽聽聽Regardless, I think this change makes Swift a better language, and I鈥檓 in favor of it.

聽聽聽-BJ

聽聽聽On Oct 4, 2017, at 9:10 PM, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> wrote:

聽聽聽On Oct 2, 2017, at 9:59 PM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> wrote:

聽聽聽On 3 Oct 2017, at 05:12, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> wrote:

聽聽聽On Mon, Oct 2, 2017 at 9:16 PM, Matthew Johnson via swift-evolution<swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>>wrote:

聽聽聽聽聽聽聽Sent from my iPad

聽聽聽聽聽聽聽On Oct 2, 2017, at 7:33 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> wrote:

聽聽聽聽聽聽聽On Oct 2, 2017, at 03:25, Vladimir.S via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> wrote:

聽聽聽聽聽聽聽On 01.10.2017 1:18, Chris Lattner wrote:

聽聽聽聽聽聽聽On Sep 29, 2017, at 10:42 AM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>>>>>>>>>>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>> wrote:

聽聽聽聽聽聽聽Vladimir, I agree with you on that change, but it鈥檚 a separate topic from this one.

聽聽聽聽聽聽聽Tony is absolutely correct that this topic has already been discussed. It is a deliberate design
聽聽聽聽聽聽聽decision that public types do not automatically expose members without explicit access modifiers;
聽聽聽聽聽聽聽this has been brought up on this list, and it is clearly not in scope for discussion as no new
聽聽聽聽聽聽聽insight can arise this late in the game. The inconsistency with public extensions was brought up,
聽聽聽聽聽聽聽the proposed solution was to remove modifiers for extensions, but this proposal was rejected. So,
聽聽聽聽聽聽聽the final design is what we have.

聽聽聽聽聽聽聽Agreed. The core team would only consider a refinement or change to access control if there were
聽聽聽聽聽聽聽something actively broken that mattered for ABI stability.

聽聽聽聽聽聽聽So we have to live with *protected* extension inconsistency for very long time just because core team
聽聽聽聽聽聽聽don't want to even discuss _this particular_ inconsistency(when access level in *private extension*
聽聽聽聽聽聽聽must be private, not fileprivate)?

聽聽聽聽聽聽聽Yes, we decided that access level for extension will mean a default and top most access level for
聽聽聽聽聽聽聽nested methods, OK. But even in this rule, which already differ from access modifiers for types, we
聽聽聽聽聽聽聽have another one special case for 'private extension'.

聽聽聽聽聽聽聽Don't you think this is not normal situation and actually there IMO can't be any reason to keep this
聽聽聽聽聽聽聽bug-producing inconsistency in Swift? (especially given Swift 5 seems like is a last moment to fix this)

聽聽聽聽聽聽聽I hate to say it but I'm inclined to agree with Vladimir on this. "private extension" has a useful
聽聽聽聽聽聽聽meaning now distinct from "fileprivate extension", and it was an oversight that SE-0169
聽聽聽聽聽聽聽<https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md> didn't
聽聽聽聽聽聽聽include a fix here. On this/very narrow, very specific/access control issue I think it would still be
聽聽聽聽聽聽聽worth discussing; like Xiaodi said it's not related to James' original thread-starter.

聽聽聽聽聽聽聽I agree with this in principle but would not want to see it become a slippery slope back into extremely
聽聽聽聽聽聽聽long access control discussions.

聽聽聽As I've said elsewhere, I too agree with this in principle. I agree with Jordan that the current state of
聽聽聽things is justifiable but the alternative would be somewhat superior, agree that in a vacuum this very
聽聽聽narrow and specific discussion might be warranted, and agree also that this could be a very slippery slide
聽聽聽down a very steep slope.

聽聽聽Same here. It鈥檚 the only grudge I have left with the current access control situation. I remember Doug Gregor
聽聽聽and John McCall discussing this during the last access control proposal. And I wouldn鈥檛 mind having a very
聽聽聽narrow discussion about only this.

聽聽聽I organize my types into extensions for each conformance and for each access control. I can currently
聽聽聽implicitly apply public or fileprivate to all members of an extension but I have no way of doing the same for
聽聽聽private. That鈥檚 why I think it should be fixed.

聽聽聽This will break a bunch of code because `private extension` has_always_meant `fileprivate extension`.Even
聽聽聽Swift 3 had this same behavior. Lowering the access level of the extension members will hide a bunch of code
聽聽聽that was visible to the file.

聽聽聽169 was not a breaking change but this 鈥渇ix鈥 would have made it a breaking change. I doubt 169 would had been
聽聽聽accepted if it was a breaking change. I don鈥檛 think it鈥檚 worth it.

聽聽聽https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md

聽聽聽聽聽聽聽(I maintain that the current model does/not/ include a special case; it simply means the 'private' is
聽聽聽聽聽聽聽resolved at the level of the extension rather than the level of its members. But that isn't what people
聽聽聽聽聽聽聽expect and it's not as useful.)

聽聽聽聽聽聽聽I agree that changing the behavior of/all/ access modifiers on extensions is out of scope. (I also
聽聽聽聽聽聽聽agree that it is a bad idea. Sorry, James, but wanting 'pubic' here indicates that your mental model of
聽聽聽聽聽聽聽extensions does not match what Swift is actually doing, and that could get you into trouble.)

聽聽聽聽聽聽聽Jordan

聽聽聽聽聽聽聽_______________________________________________
聽聽聽聽聽聽聽swift-evolution mailing list
聽聽聽聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>
聽聽聽聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽聽聽聽聽_______________________________________________
聽聽聽聽聽聽聽swift-evolution mailing list
聽聽聽聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>
聽聽聽聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

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

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

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

I appreciate the enthusiasm but this is not a bug. This was a deliberate
change in swift 3 to make `private extension` usable. If this was a bug
then during swift 3 we should have disallowed `private extension` and only
allowed `fileprivate extension` but that is not what happened. `private
extension` has worked the same since swift 1. I鈥檝e always used `private
extension` when I want to add methods to String or other build in types.

It鈥檚 not a bug, but its unfortunate the behaviour wasn鈥檛 changed at the
same time as SE-0169, and it now is very inconsistent. I also don鈥檛 have to
rehash previous discussions, but if a Core Team member (Chris) is okay with
going ahead with this, perhaps we should consider it.

This could have not been part of 169 because it would've required to
lower the visibility of the private extension modifier.
鈥淣o migration will be necessary as this proposal merely broadens the
visibility of|private|.鈥
There was a corner case mentioned when dealing with functions with the
same name and that was understandable.
private extension is consistent to the way the private scope rules work.
The word private is explicit at the top level because extensions can only
be declared at top level. Top level private is always fileprivate. The
inconsistency is that we have 1 scope ALC and the rest are not. An explicit
declaration should always take precedence when declaring something like an
access level override.

FWIW, I can't agree with this. 'private extension' is a real point of
additional confusion for access levels in Swift.
Extension *by itself* has no access level, we only can specify the
*default* (and the top most) access level for inner methods.
I.e. 'private' access modifier for extension has not the same meaning as
'private' func/type/variable at file scope.
(Yes, I also believe we should disallow 'private' keyword at file level
and allow it only for extensions, so 'fileprivate' should be used
explicitly if one needs this. At least warning should be raised. This is
the *root* of the problem we discuss now. But unfortunately I don't expect
this could be supported.)

Wouldn't that just add a *special* rule to extensions? :slight_smile:

The latter is 'direct' access level for the func/type/variable and here
we apply the standard rule for scoped private, so 'private' for file scope
--> 'fileprivate'.

The former means 'the default(and top most) modifier that will be
auto-inserted by compiler for all nested methods in extension'. This
relatively simple rule should not be complicated by additional rule as ",
but if it is private extension, result access level will be fileprivate,
you can't have extensions with private methods鈥

Private as it exist in swift now is the scope access control label. The
compiler does not insert the modifier without having to first compute what
access control level would be applied to the members of the extension.
Doing it the other way would be counterintuitive for an scope access label.
In my code base I disallow top level fileprivate because private top level
is fileprivate. This is a matter of taste and a linter here would help like
a mentioned up thread.

This is the sticking point, which is why there are two possible
interpretations of "private extension":

Choice 1) Attach-then-evaluate. "ACL extension { ... }" is a syntactic
shortcut for "extension { ACL ... }". Under that definition, the ACL is
evaluated as if it were attached to each declaration, so "private
extension" would expand to "private" in front of each decl.

Choice 2) Evaluate-then-attach. "ACL extension { ... }" is evaluated such
that "ACL" takes on the meaning based on its scope; since it's equivalent
to "fileprivate" there, that is what is attached to each declaration inside
the extension.

Yep. This is the issue. Nice summary!

The phrasing in the official Swift language guide doesn't specifically
state it, but I think most readers would interpret the following as #1:

"Alternatively, you can mark an extension with an explicit access-level
modifier (for example, `private extension`) to set a new default access
level for all members defined within the extension."

I personally find that choice to be the clearer interpretation of the
rule, because it's based entirely on what words are in the source file and
not about how they interact in special edge cases.

Documentation is hard to keep in sync.

https://github.com/apple/swift-evolution/blob/master/proposals/0025-scoped-access-level.md#complications-with-private-types

At the time SE-0025 was accepted, "private extension" would have been
meaningless if it did not mean "fileprivate" because it predated the
SE-0169 behavior extending "private" to extensions in the same file. The
very issue being debated here is whether the oversight that SE-0169 did not
consider extensions鈥攏ow that "private extension" *could* have a meaningful
use separate from "fileprivate extension"鈥攊s something that is worth
correcting.

If the documentation is out-of-date and needs to be updated to list
describe unintuitive special behavior, why not use the opportunity to make
the behavior intuitive and consistent instead?

I also think it's hard to rationalize "private extension" working like #2
because compared to #1, it's both duplicative ("private extension" and
"fileprivate extension" are awkwardly the same) _and_ it is strictly less
flexible (there is _no_ way using that syntax to define an extension whose
members are private, which is an inconsistent hole in the language).

This compiles on an Xcode 9 playground. SE-0025 doesn't only affect
extensions.
``MyClass.myFunc()` looks like (Choice 2) to me. Same as `private
extension MyClass2`.

private class MyClass {
聽聽聽聽static func myFunc(){
聽聽聽聽聽聽聽聽print(鈥淎cts likes fileprivate")
聽聽聽聽}
}

private class MyClass2 {
}

private extension MyClass2{
聽聽聽聽static func myFunc2(){
聽聽聽聽聽聽聽print("Same as MyClass.myFunc")
聽聽聽聽}
}

MyClass.myFunc() // Acts likes fileprivate
MyClass2.myFunc2() // Same as MyClass.myFunc

This example is somewhat irrelevant to what's being discussed here鈥攊t's
purely about SE-0025 behavior rather than, as the original message said,
the extremely narrow specific case of access control for extensions.

路路路

On Fri, Oct 6, 2017 at 7:07 PM Jose Cheyo Jimenez <cheyo@masters3d.com> wrote:

On Oct 6, 2017, at 11:07 AM, Tony Allevato <tony.allevato@gmail.com> > wrote:
On Fri, Oct 6, 2017 at 10:16 AM Jose Cheyo Jimenez via swift-evolution < > swift-evolution@swift.org> wrote:

On Oct 6, 2017, at 7:10 AM, Vladimir.S <svabox@gmail.com> wrote:
On 05.10.2017 20:52, Jose Cheyo Jimenez via swift-evolution wrote:
On Oct 5, 2017, at 4:32 AM, David Hart <david@hartbit.com< >> mailto:david@hartbit.com <david@hartbit.com>>> wrote:
On 5 Oct 2017, at 07:34, Jose Cheyo Jimenez via swift-evolution < >> swift-evolution@swift.org <mailto:swift-evolution@swift.org >> <swift-evolution@swift.org>>> wrote:

And, as was already said, this inconsistency leads to *relaxed* access
level, which can lead to bugs. If one expects 'private extension' means
'fileprivate extension' - compiler will show(with error) that this
assumption is wrong just after the first attempt to access methods from
outside of the extended type.
But if one expects true 'private' access level - the methods from private
extension could be called from any other code in the same file(by mistake,
or because code was written a long time ago, or by another developer) and
this clearly could produce complex bugs.

Also, isn't it a strange code below:

private extension MyType {
func foo() {}
private bar() {}
fileprivate baz() {} // note that "usually" fileprivate is 'wider'
access level
}

This is also strange too :slight_smile:

fileprivate class MyType {
聽聽open func foo(){} // Is this open or fileprivate?
聽聽public func bar(){}
}

open class MyType2 {
}

open extension MyType2 { // Error: Extensions cannot use 'open' as their
default access; use 'public'
聽聽聽聽func baz(){}
}

but it has *currently* a sense - 'foo' is fileprivate, and 'bar' is
'true' private.
Yes, currently we have a warning about 'baz': "warning: declaring a
fileprivate instance method in a private extension", but then we have a
question "Why?", as private at top level == fileprivate. and this does not
produce any warnings:
fileprivate extension MyType {
fileprivate func foo() {}
}

Even more, someone can think "why we need 'private' declaration in
private extension, probably this is a mistake i.e. unnecessary duplication
of code, I'll refactor this and delete this explicit 'private' because
extension is already private' and so will open doors for future problems.

So I do believe we really need to remove that ugly inconsistency and make
Swift better to write, understand and support the code.

This is matter of taste. For example I think fileprivate is ugly and
having both private and fileprivate makes the code hard to understand.

Vladimir.

private is different because it is scoped so because of that it is also
different when dealing with extensions. Top level private is always the
same as fileprivate thanks to its scoped nature.

Making private the scope ACL was a mistake but that ship has sailed and
so has this one imo.

On Oct 4, 2017, at 10:05 PM, Tony Allevato <tony.allevato@gmail.com < >> mailto:tony.allevato@gmail.com <tony.allevato@gmail.com>>> wrote:

Trust me, I'm the last person who wants to rehash access levels in Swift
again. But that's not what's happening here, IMO, and fixing bugs is not
just "a change for the sake of changing."

The current behavior of "private extension" is *incorrect*, because it's
entirely inconsistent with how access levels on extensions are documented
to behave and it's inconsistent with how other access levels apply to
extensions.

Can anyone think of a reason鈥攐ther than "it's too late to change it"鈥攚hy
"private extension" and "fileprivate extension" should behave the same, and
why "X extension { decl }" should be identical to "extension { X decl }"
for all X *except* "private"?

Yes, it's absolutely unfortunate that this oversight was not addressed
when the other access level changes were made. But we shouldn't have to
live with bugs in the language because we're afraid of some unknown amount
of churn among code that is already written incorrectly. Nor is fixing this
bug declaring open season on other, unrelated access level debates. Do you
have data that shows that the amount of code broken because it's using
"private" when it really should be saying "fileprivate" is high enough that
we should just leave the bug there?

On Wed, Oct 4, 2017 at 9:51 PM Jose Cheyo Jimenez via swift-evolution < >> swift-evolution@swift.org <mailto:swift-evolution@swift.org >> <swift-evolution@swift.org>>> wrote:

聽聽聽There was a high bar for breaking changes in swift 4 and is even
higher for swift 5. se-110 was approved and
聽聽聽implemented on the premises that it was not a big change but it was
breaking code so it got reverted. Sure the
聽聽聽migrator was making this easier but the result was a usability
regression. I think this is a change just for the
聽聽聽sake of changing. This will cause unnecessary churn. Let鈥檚 leave ACLs
alone for the next few versions of swift
聽聽聽unless we have a way better system.

https://lists.swift.org/pipermail/swift-evolution-announce/2017-June/000386.html

聽聽聽On Oct 4, 2017, at 8:47 PM, BJ Homer <bjhomer@gmail.com< >> mailto:bjhomer@gmail.com <bjhomer@gmail.com>>> wrote:

聽聽聽It certainly could break *some* code. But it only breaks code written
by an author who wrote 鈥榩rivate
聽聽聽extension鈥 knowing that 鈥榝ileprivate extension鈥 was also an option,
but still intended it to be shared with the
聽聽聽whole file. (If that code was from Swift 2, it would have already been
migrated to 鈥榝ileprivate extension鈥 by
聽聽聽the 2->3 migrator.)

聽聽聽So existing code that says 鈥榩rivate extension鈥 was written in a Swift
3 or 4 era when 鈥榝ileprivate鈥 was an
聽聽聽option. If the goal was specifically to share it with the whole file,
it seems likely that most authors would
聽聽聽have used 鈥榝ileprivate extension鈥 instead of 鈥榩rivate extension鈥, as
that better communicates the intention.
聽聽聽Regardless, though, we could check against the Swift source
compatibility test suite to see how widespread that is.

聽聽聽Regardless, I think this change makes Swift a better language, and I鈥檓
in favor of it.

聽聽聽-BJ

聽聽聽On Oct 4, 2017, at 9:10 PM, Jose Cheyo Jimenez via swift-evolution < >> swift-evolution@swift.org >> <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> wrote:

聽聽聽On Oct 2, 2017, at 9:59 PM, David Hart via swift-evolution < >> swift-evolution@swift.org >> <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> wrote:

聽聽聽On 3 Oct 2017, at 05:12, Xiaodi Wu via swift-evolution < >> swift-evolution@swift.org >> <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> wrote:

聽聽聽On Mon, Oct 2, 2017 at 9:16 PM, Matthew Johnson via swift-evolution< >> swift-evolution@swift.org >> <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>>wrote:

聽聽聽聽聽聽聽Sent from my iPad

聽聽聽聽聽聽聽On Oct 2, 2017, at 7:33 PM, Jordan Rose via swift-evolution < >> swift-evolution@swift.org >> <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> >> wrote:

聽聽聽聽聽聽聽On Oct 2, 2017, at 03:25, Vladimir.S via swift-evolution < >> swift-evolution@swift.org >> <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> >> wrote:

聽聽聽聽聽聽聽On 01.10.2017 1:18, Chris Lattner wrote:

聽聽聽聽聽聽聽On Sep 29, 2017, at 10:42 AM, Xiaodi Wu via swift-evolution < >> swift-evolution@swift.org >> <mailto:swift-evolution@swift.org <swift-evolution@swift.org>>> >> wrote:

聽聽聽聽聽聽聽Vladimir, I agree with you on that change, but it鈥檚 a separate
topic from this one.

聽聽聽聽聽聽聽Tony is absolutely correct that this topic has already been
discussed. It is a deliberate design
聽聽聽聽聽聽聽decision that public types do not automatically expose members
without explicit access modifiers;
聽聽聽聽聽聽聽this has been brought up on this list, and it is clearly not in
scope for discussion as no new
聽聽聽聽聽聽聽insight can arise this late in the game. The inconsistency with
public extensions was brought up,
聽聽聽聽聽聽聽the proposed solution was to remove modifiers for extensions, but
this proposal was rejected. So,
聽聽聽聽聽聽聽the final design is what we have.

聽聽聽聽聽聽聽Agreed. The core team would only consider a refinement or change
to access control if there were
聽聽聽聽聽聽聽something actively broken that mattered for ABI stability.

聽聽聽聽聽聽聽So we have to live with *protected* extension inconsistency for
very long time just because core team
聽聽聽聽聽聽聽don't want to even discuss _this particular_ inconsistency(when
access level in *private extension*
聽聽聽聽聽聽聽must be private, not fileprivate)?

聽聽聽聽聽聽聽Yes, we decided that access level for extension will mean a
default and top most access level for
聽聽聽聽聽聽聽nested methods, OK. But even in this rule, which already differ
from access modifiers for types, we
聽聽聽聽聽聽聽have another one special case for 'private extension'.

聽聽聽聽聽聽聽Don't you think this is not normal situation and actually there
IMO can't be any reason to keep this
聽聽聽聽聽聽聽bug-producing inconsistency in Swift? (especially given Swift 5
seems like is a last moment to fix this)

聽聽聽聽聽聽聽I hate to say it but I'm inclined to agree with Vladimir on this.
"private extension" has a useful
聽聽聽聽聽聽聽meaning now distinct from "fileprivate extension", and it was an
oversight that SE-0169
聽聽聽聽聽聽聽<
https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md>
didn't
聽聽聽聽聽聽聽include a fix here. On this/very narrow, very specific/access
control issue I think it would still be
聽聽聽聽聽聽聽worth discussing; like Xiaodi said it's not related to James'
original thread-starter.

聽聽聽聽聽聽聽I agree with this in principle but would not want to see it become
a slippery slope back into extremely
聽聽聽聽聽聽聽long access control discussions.

聽聽聽As I've said elsewhere, I too agree with this in principle. I agree
with Jordan that the current state of
聽聽聽things is justifiable but the alternative would be somewhat superior,
agree that in a vacuum this very
聽聽聽narrow and specific discussion might be warranted, and agree also that
this could be a very slippery slide
聽聽聽down a very steep slope.

聽聽聽Same here. It鈥檚 the only grudge I have left with the current access
control situation. I remember Doug Gregor
聽聽聽and John McCall discussing this during the last access control
proposal. And I wouldn鈥檛 mind having a very
聽聽聽narrow discussion about only this.

聽聽聽I organize my types into extensions for each conformance and for each
access control. I can currently
聽聽聽implicitly apply public or fileprivate to all members of an extension
but I have no way of doing the same for
聽聽聽private. That鈥檚 why I think it should be fixed.

聽聽聽This will break a bunch of code because `private extension`
has_always_meant `fileprivate extension`.Even
聽聽聽Swift 3 had this same behavior. Lowering the access level of the
extension members will hide a bunch of code
聽聽聽that was visible to the file.

聽聽聽169 was not a breaking change but this 鈥渇ix鈥 would have made it a
breaking change. I doubt 169 would had been
聽聽聽accepted if it was a breaking change. I don鈥檛 think it鈥檚 worth it.

https://github.com/apple/swift-evolution/blob/master/proposals/0169-improve-interaction-between-private-declarations-and-extensions.md

聽聽聽聽聽聽聽(I maintain that the current model does/not/ include a special
case; it simply means the 'private' is
聽聽聽聽聽聽聽resolved at the level of the extension rather than the level of
its members. But that isn't what people
聽聽聽聽聽聽聽expect and it's not as useful.)

聽聽聽聽聽聽聽I agree that changing the behavior of/all/ access modifiers on
extensions is out of scope. (I also
聽聽聽聽聽聽聽agree that it is a bad idea. Sorry, James, but wanting 'pubic'
here indicates that your mental model of
聽聽聽聽聽聽聽extensions does not match what Swift is actually doing, and that
could get you into trouble.)

聽聽聽聽聽聽聽Jordan

聽聽聽聽聽聽聽_______________________________________________
聽聽聽聽聽聽聽swift-evolution mailing list
聽聽聽聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽聽聽聽聽_______________________________________________
聽聽聽聽聽聽聽swift-evolution mailing list
聽聽聽聽聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽聽聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

聽聽聽_______________________________________________
聽聽聽swift-evolution mailing list
聽聽聽swift-evolution@swift.org <mailto:swift-evolution@swift.org
<swift-evolution@swift.org>>
聽聽聽https://lists.swift.org/mailman/listinfo/swift-evolution

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

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

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

Lets say you 鈥渇ix鈥 the private extension override. Now MyClass2.myFunc2() is not accessible from outside the type.
Wouldn't MyClass2.myFunc2() now be inconsistent with MyClass.myFunc()?
I don鈥檛 think you can make a change to one with out causing other inconsistencies. I rest my case. :slight_smile:

private class MyClass {
聽聽聽聽static func myFunc(){ // This would now act differently from private extensions?
聽聽聽聽聽聽聽聽print("acts like fileprivate now")
聽聽聽聽}
}

private class MyClass2 {}

private extension MyClass2{
聽聽聽聽聽聽static func myFunc2(){
聽聽聽聽聽聽聽print("Same as MyClass.myFunc")
聽聽聽聽}
}

MyClass.myFunc() // acts like fileprivate
MyClass2.myFunc2() // The proposed change would hide myFunc2
聽聽聽聽聽聽聽聽聽聽聽聽聽//Error: 'myFunc2' is inaccessible due to 'private' protection level

路路路

On Oct 6, 2017, at 8:01 PM, Tony Allevato <tony.allevato@gmail.com> wrote:

At the time SE-0025 was accepted, "private extension" would have been meaningless if it did not mean "fileprivate" because it predated the SE-0169 behavior extending "private" to extensions in the same file. The very issue being debated here is whether the oversight that SE-0169 did not consider extensions鈥攏ow that "private extension" *could* have a meaningful use separate from "fileprivate extension"鈥攊s something that is worth correcting.

If the documentation is out-of-date and needs to be updated to list describe unintuitive special behavior, why not use the opportunity to make the behavior intuitive and consistent instead?

At the time SE-0025 was accepted, "private extension" would have been

meaningless if it did not mean "fileprivate" because it predated the
SE-0169 behavior extending "private" to extensions in the same file. The
very issue being debated here is whether the oversight that SE-0169 did not
consider extensions鈥攏ow that "private extension" *could* have a meaningful
use separate from "fileprivate extension"鈥攊s something that is worth
correcting.

If the documentation is out-of-date and needs to be updated to list
describe unintuitive special behavior, why not use the opportunity to make
the behavior intuitive and consistent instead?

Lets say you 鈥渇ix鈥 the private extension override. Now MyClass2.myFunc2()
is not accessible from outside the type.
Wouldn't MyClass2.myFunc2() now be inconsistent with MyClass.myFunc()?
I don鈥檛 think you can make a change to one with out causing other
inconsistencies. I rest my case. :slight_smile:

No, because a class is a concrete "thing" whose access level which鈥攚hile
providing an upper bound for access levels of its defaulting members鈥攊s
otherwise independent of the access level of its members.

Extensions, on the other hand, aren't a concrete thing of their own. The
access level on an extension exists *solely* as a shortcut to specify the
upper bound for its defaulting members that are injected into the main type.

What happens in your example if you replace "private" with "public"? Then
myFunc has internal access but myFunc2 is public. So the "inconsistency"
you're pointing out between access inherited from a type and access
inherited from an extension already exists鈥攖hey're apples and oranges.

That's why access levels of classes/structs/other types aren't relevant
examples here鈥攅xtensions treat access levels fundamentally differently.

路路路

On Fri, Oct 6, 2017 at 8:45 PM Jose Cheyo Jimenez <cheyo@masters3d.com> wrote:

On Oct 6, 2017, at 8:01 PM, Tony Allevato <tony.allevato@gmail.com> wrote:

private class MyClass {
聽聽聽聽static func myFunc(){ // This would now act differently from private
extensions?
聽聽聽聽聽聽聽聽print("acts like fileprivate now")
聽聽聽聽}
}

private class MyClass2 {}

private extension MyClass2{
聽聽聽聽聽聽static func myFunc2(){
聽聽聽聽聽聽聽print("Same as MyClass.myFunc")
聽聽聽聽}
}

MyClass.myFunc() // acts like fileprivate
MyClass2.myFunc2() // The proposed change would hide myFunc2
聽聽聽聽聽聽聽聽聽聽聽聽聽//Error: 'myFunc2' is inaccessible due to 'private'
protection level

At the time SE-0025 was accepted, "private extension" would have been meaningless if it did not mean "fileprivate" because it predated the SE-0169 behavior extending "private" to extensions in the same file. The very issue being debated here is whether the oversight that SE-0169 did not consider extensions鈥攏ow that "private extension" *could* have a meaningful use separate from "fileprivate extension"鈥攊s something that is worth correcting.

If the documentation is out-of-date and needs to be updated to list describe unintuitive special behavior, why not use the opportunity to make the behavior intuitive and consistent instead?

Lets say you 鈥渇ix鈥 the private extension override. Now MyClass2.myFunc2() is not accessible from outside the type.
Wouldn't MyClass2.myFunc2() now be inconsistent with MyClass.myFunc()?
I don鈥檛 think you can make a change to one with out causing other inconsistencies. I rest my case. :slight_smile:

No, because a class is a concrete "thing" whose access level which鈥攚hile providing an upper bound for access levels of its defaulting members鈥攊s otherwise independent of the access level of its members.

Extensions, on the other hand, aren't a concrete thing of their own. The access level on an extension exists *solely* as a shortcut to specify the upper bound for its defaulting members that are injected into the main type.

What happens in your example if you replace "private" with "public"? Then myFunc has internal access but myFunc2 is public. So the "inconsistency" you're pointing out between access inherited from a type and access inherited from an extension already exists鈥攖hey're apples and oranges.

That's why access levels of classes/structs/other types aren't relevant examples here鈥攅xtensions treat access levels fundamentally differently.

Sure. Extensions apply a default upper bound and types can lower the upper bound of the default internal members. The upper bound on the below example is the same for both when dealing with top level private.

Extensions should resolve their upper bound accessibility where the 鈥榩rivate鈥 appears explicitly and this now happens to be the same for both types and extensions regardless of how they are enforced.

路路路

On Oct 6, 2017, at 8:58 PM, Tony Allevato <tony.allevato@gmail.com> wrote:
On Fri, Oct 6, 2017 at 8:45 PM Jose Cheyo Jimenez <cheyo@masters3d.com <mailto:cheyo@masters3d.com>> wrote:

On Oct 6, 2017, at 8:01 PM, Tony Allevato <tony.allevato@gmail.com <mailto:tony.allevato@gmail.com>> wrote:

private class MyClass {
聽聽聽聽static func myFunc(){ // This would now act differently from private extensions?
聽聽聽聽聽聽聽聽print("acts like fileprivate now")
聽聽聽聽}
}

private class MyClass2 {}

private extension MyClass2{
聽聽聽聽聽聽static func myFunc2(){
聽聽聽聽聽聽聽print("Same as MyClass.myFunc")
聽聽聽聽}
}

MyClass.myFunc() // acts like fileprivate
MyClass2.myFunc2() // The proposed change would hide myFunc2
聽聽聽聽聽聽聽聽聽聽聽聽聽//Error: 'myFunc2' is inaccessible due to 'private' protection level

At the time SE-0025 was accepted, "private extension" would have been

meaningless if it did not mean "fileprivate" because it predated the
SE-0169 behavior extending "private" to extensions in the same file. The
very issue being debated here is whether the oversight that SE-0169 did not
consider extensions鈥攏ow that "private extension" *could* have a meaningful
use separate from "fileprivate extension"鈥攊s something that is worth
correcting.

If the documentation is out-of-date and needs to be updated to list
describe unintuitive special behavior, why not use the opportunity to make
the behavior intuitive and consistent instead?

Lets say you 鈥渇ix鈥 the private extension override. Now MyClass2.myFunc2()
is not accessible from outside the type.
Wouldn't MyClass2.myFunc2() now be inconsistent with MyClass.myFunc()?
I don鈥檛 think you can make a change to one with out causing other
inconsistencies. I rest my case. :slight_smile:

No, because a class is a concrete "thing" whose access level which鈥攚hile
providing an upper bound for access levels of its defaulting members鈥攊s
otherwise independent of the access level of its members.

Extensions, on the other hand, aren't a concrete thing of their own. The
access level on an extension exists *solely* as a shortcut to specify the
upper bound for its defaulting members that are injected into the main type.

What happens in your example if you replace "private" with "public"? Then
myFunc has internal access but myFunc2 is public. So the "inconsistency"
you're pointing out between access inherited from a type and access
inherited from an extension already exists鈥攖hey're apples and oranges.

That's why access levels of classes/structs/other types aren't relevant
examples here鈥攅xtensions treat access levels fundamentally differently.

Sure. Extensions apply a default upper bound and types can lower the upper
bound of the default internal members. The upper bound on the below example
is the same for both when dealing with top level private.

Extensions should resolve their upper bound accessibility where the
鈥榩rivate鈥 appears explicitly and this now happens to be the same for both
types and extensions regardless of how they are enforced.

But *why* do you think that should be? You're stating what the current
situation is and you say that it "should" be that way, but why should we
accept that status quo instead of making "private extension" more useful
for people who use "private" in the sense introduced by SE-0169, when the
argument for consistency can honestly be argued either way (the two options
I wrote a few messages up)?

路路路

On Fri, Oct 6, 2017 at 9:29 PM Jose Cheyo Jimenez <cheyo@masters3d.com> wrote:

On Oct 6, 2017, at 8:58 PM, Tony Allevato <tony.allevato@gmail.com> wrote:
On Fri, Oct 6, 2017 at 8:45 PM Jose Cheyo Jimenez <cheyo@masters3d.com> > wrote:

On Oct 6, 2017, at 8:01 PM, Tony Allevato <tony.allevato@gmail.com> >> wrote:

private class MyClass {
聽聽聽聽static func myFunc(){ // This would now act differently from private
extensions?
聽聽聽聽聽聽聽聽print("acts like fileprivate now")
聽聽聽聽}
}

private class MyClass2 {}

private extension MyClass2{
聽聽聽聽聽聽static func myFunc2(){
聽聽聽聽聽聽聽print("Same as MyClass.myFunc")
聽聽聽聽}
}

MyClass.myFunc() // acts like fileprivate
MyClass2.myFunc2() // The proposed change would hide myFunc2
聽聽聽聽聽聽聽聽聽聽聽聽聽//Error: 'myFunc2' is inaccessible due to 'private'
protection level

At the time SE-0025 was accepted, "private extension" would have been meaningless if it did not mean "fileprivate" because it predated the SE-0169 behavior extending "private" to extensions in the same file. The very issue being debated here is whether the oversight that SE-0169 did not consider extensions鈥攏ow that "private extension" *could* have a meaningful use separate from "fileprivate extension"鈥攊s something that is worth correcting.

If the documentation is out-of-date and needs to be updated to list describe unintuitive special behavior, why not use the opportunity to make the behavior intuitive and consistent instead?

Lets say you 鈥渇ix鈥 the private extension override. Now MyClass2.myFunc2() is not accessible from outside the type.
Wouldn't MyClass2.myFunc2() now be inconsistent with MyClass.myFunc()?
I don鈥檛 think you can make a change to one with out causing other inconsistencies. I rest my case. :slight_smile:

No, because a class is a concrete "thing" whose access level which鈥攚hile providing an upper bound for access levels of its defaulting members鈥攊s otherwise independent of the access level of its members.

Extensions, on the other hand, aren't a concrete thing of their own. The access level on an extension exists *solely* as a shortcut to specify the upper bound for its defaulting members that are injected into the main type.

What happens in your example if you replace "private" with "public"? Then myFunc has internal access but myFunc2 is public. So the "inconsistency" you're pointing out between access inherited from a type and access inherited from an extension already exists鈥攖hey're apples and oranges.

That's why access levels of classes/structs/other types aren't relevant examples here鈥攅xtensions treat access levels fundamentally differently.

Sure. Extensions apply a default upper bound and types can lower the upper bound of the default internal members. The upper bound on the below example is the same for both when dealing with top level private.

Extensions should resolve their upper bound accessibility where the 鈥榩rivate鈥 appears explicitly and this now happens to be the same for both types and extensions regardless of how they are enforced.

But *why* do you think that should be? You're stating what the current situation is and you say that it "should" be that way, but why should we accept that status quo instead of making "private extension" more useful for people who use "private" in the sense introduced by SE-0169, when the argument for consistency can honestly be argued either way (the two options I wrote a few messages up)?

Oh :slight_smile: Because I believe that lowering the scope of 鈥減rivate extension鈥 would undermine the spirit of 169. 169 was a compromise after 159 was rejected. 169 was meant to make fileprivate less common and thus more meaningful when it occurs in source. Where 169 was meant to relax the rules, the proposed 鈥渇ix鈥 would force people who now use 鈥減rivate extension鈥 to use 鈥渇ileprivate extension鈥 thus making fileprivate more common. In other words, 169 was about relaxing rules and not about tightening down the rules or allowing 鈥渢rue鈥 private to be applied as a default ACL extension.

鈥渟coped" `private extension` can鈥檛 be archived now in the same way that 鈥榦pen extension鈥 is not allowed. The lowest and highest ACL are not able to be applied as default extension modifiers and this makes sense to me.

There is no solution that will make everyone happy: maintaining the status quo makes 鈥渇ileprivate鈥 too common and therefore not meaningful when it occurs in source; removing or diluting scope-level access control (as in SE-0159 <https://github.com/apple/swift-evolution/blob/master/proposals/0159-fix-private-access-levels.md> and this proposal)
https://lists.swift.org/pipermail/swift-evolution-announce/2017-April/000357.html

路路路

On Oct 6, 2017, at 9:35 PM, Tony Allevato <tony.allevato@gmail.com> wrote:
On Fri, Oct 6, 2017 at 9:29 PM Jose Cheyo Jimenez <cheyo@masters3d.com <mailto:cheyo@masters3d.com>> wrote:

On Oct 6, 2017, at 8:58 PM, Tony Allevato <tony.allevato@gmail.com <mailto:tony.allevato@gmail.com>> wrote:
On Fri, Oct 6, 2017 at 8:45 PM Jose Cheyo Jimenez <cheyo@masters3d.com <mailto:cheyo@masters3d.com>> wrote:

On Oct 6, 2017, at 8:01 PM, Tony Allevato <tony.allevato@gmail.com <mailto:tony.allevato@gmail.com>> wrote:

private class MyClass {
聽聽聽聽static func myFunc(){ // This would now act differently from private extensions?
聽聽聽聽聽聽聽聽print("acts like fileprivate now")
聽聽聽聽}
}

private class MyClass2 {}

private extension MyClass2{
聽聽聽聽聽聽static func myFunc2(){
聽聽聽聽聽聽聽print("Same as MyClass.myFunc")
聽聽聽聽}
}

MyClass.myFunc() // acts like fileprivate
MyClass2.myFunc2() // The proposed change would hide myFunc2
聽聽聽聽聽聽聽聽聽聽聽聽聽//Error: 'myFunc2' is inaccessible due to 'private' protection level

One argument: without this fix, private is the only access level for which we have no means to easily and implicitly apply an access level to a group of members. And it bums me to have to explicitly type private on ever single member to achieve the same result as I can with any other access level.

路路路

On 7 Oct 2017, at 07:07, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org> wrote:

On Oct 6, 2017, at 9:35 PM, Tony Allevato <tony.allevato@gmail.com> wrote:

On Fri, Oct 6, 2017 at 9:29 PM Jose Cheyo Jimenez <cheyo@masters3d.com> wrote:

On Oct 6, 2017, at 8:58 PM, Tony Allevato <tony.allevato@gmail.com> wrote:

On Fri, Oct 6, 2017 at 8:45 PM Jose Cheyo Jimenez <cheyo@masters3d.com> wrote:

On Oct 6, 2017, at 8:01 PM, Tony Allevato <tony.allevato@gmail.com> wrote:

At the time SE-0025 was accepted, "private extension" would have been meaningless if it did not mean "fileprivate" because it predated the SE-0169 behavior extending "private" to extensions in the same file. The very issue being debated here is whether the oversight that SE-0169 did not consider extensions鈥攏ow that "private extension" *could* have a meaningful use separate from "fileprivate extension"鈥攊s something that is worth correcting.

If the documentation is out-of-date and needs to be updated to list describe unintuitive special behavior, why not use the opportunity to make the behavior intuitive and consistent instead?

Lets say you 鈥渇ix鈥 the private extension override. Now MyClass2.myFunc2() is not accessible from outside the type.
Wouldn't MyClass2.myFunc2() now be inconsistent with MyClass.myFunc()?
I don鈥檛 think you can make a change to one with out causing other inconsistencies. I rest my case. :slight_smile:

No, because a class is a concrete "thing" whose access level which鈥攚hile providing an upper bound for access levels of its defaulting members鈥攊s otherwise independent of the access level of its members.

Extensions, on the other hand, aren't a concrete thing of their own. The access level on an extension exists *solely* as a shortcut to specify the upper bound for its defaulting members that are injected into the main type.

What happens in your example if you replace "private" with "public"? Then myFunc has internal access but myFunc2 is public. So the "inconsistency" you're pointing out between access inherited from a type and access inherited from an extension already exists鈥攖hey're apples and oranges.

That's why access levels of classes/structs/other types aren't relevant examples here鈥攅xtensions treat access levels fundamentally differently.

Sure. Extensions apply a default upper bound and types can lower the upper bound of the default internal members. The upper bound on the below example is the same for both when dealing with top level private.

Extensions should resolve their upper bound accessibility where the 鈥榩rivate鈥 appears explicitly and this now happens to be the same for both types and extensions regardless of how they are enforced.

But *why* do you think that should be? You're stating what the current situation is and you say that it "should" be that way, but why should we accept that status quo instead of making "private extension" more useful for people who use "private" in the sense introduced by SE-0169, when the argument for consistency can honestly be argued either way (the two options I wrote a few messages up)?

Oh :slight_smile: Because I believe that lowering the scope of 鈥減rivate extension鈥 would undermine the spirit of 169. 169 was a compromise after 159 was rejected. 169 was meant to make fileprivate less common and thus more meaningful when it occurs in source. Where 169 was meant to relax the rules, the proposed 鈥渇ix鈥 would force people who now use 鈥減rivate extension鈥 to use 鈥渇ileprivate extension鈥 thus making fileprivate more common. In other words, 169 was about relaxing rules and not about tightening down the rules or allowing 鈥渢rue鈥 private to be applied as a default ACL extension.

鈥渟coped" `private extension` can鈥檛 be archived now in the same way that 鈥榦pen extension鈥 is not allowed. The lowest and highest ACL are not able to be applied as default extension modifiers and this makes sense to me.

There is no solution that will make everyone happy: maintaining the status quo makes 鈥渇ileprivate鈥 too common and therefore not meaningful when it occurs in source; removing or diluting scope-level access control (as in SE-0159 <https://github.com/apple/swift-evolution/blob/master/proposals/0159-fix-private-access-levels.md> and this proposal)
https://lists.swift.org/pipermail/swift-evolution-announce/2017-April/000357.html

private class MyClass {
聽聽聽聽static func myFunc(){ // This would now act differently from private extensions?
聽聽聽聽聽聽聽聽print("acts like fileprivate now")
聽聽聽聽}
}

private class MyClass2 {}

private extension MyClass2{
聽聽聽聽聽聽static func myFunc2(){
聽聽聽聽聽聽聽print("Same as MyClass.myFunc")
聽聽聽聽}
}

MyClass.myFunc() // acts like fileprivate
MyClass2.myFunc2() // The proposed change would hide myFunc2
聽聽聽聽聽聽聽聽聽聽聽聽聽//Error: 'myFunc2' is inaccessible due to 'private' protection level

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

This, I think, is the most persuasive argument available here; it provides
a concrete use case to justify why one design is superior to the other.

路路路

On Sat, Oct 7, 2017 at 10:26 David Hart via swift-evolution < swift-evolution@swift.org> wrote:

One argument: without this fix, private is the only access level for which
we have no means to easily and implicitly apply an access level to a group
of members. And it bums me to have to explicitly type private on ever
single member to achieve the same result as I can with any other access
level.

On 7 Oct 2017, at 07:07, Jose Cheyo Jimenez via swift-evolution < > swift-evolution@swift.org> wrote:

On Oct 6, 2017, at 9:35 PM, Tony Allevato <tony.allevato@gmail.com> wrote:

On Fri, Oct 6, 2017 at 9:29 PM Jose Cheyo Jimenez <cheyo@masters3d.com> > wrote:

On Oct 6, 2017, at 8:58 PM, Tony Allevato <tony.allevato@gmail.com> >> wrote:

On Fri, Oct 6, 2017 at 8:45 PM Jose Cheyo Jimenez <cheyo@masters3d.com> >> wrote:

On Oct 6, 2017, at 8:01 PM, Tony Allevato <tony.allevato@gmail.com> >>> wrote:

At the time SE-0025 was accepted, "private extension" would have been

meaningless if it did not mean "fileprivate" because it predated the
SE-0169 behavior extending "private" to extensions in the same file. The
very issue being debated here is whether the oversight that SE-0169 did not
consider extensions鈥攏ow that "private extension" *could* have a meaningful
use separate from "fileprivate extension"鈥攊s something that is worth
correcting.

If the documentation is out-of-date and needs to be updated to list
describe unintuitive special behavior, why not use the opportunity to make
the behavior intuitive and consistent instead?

Lets say you 鈥渇ix鈥 the private extension override. Now
MyClass2.myFunc2() is not accessible from outside the type.
Wouldn't MyClass2.myFunc2() now be inconsistent with MyClass.myFunc()?
I don鈥檛 think you can make a change to one with out causing other
inconsistencies. I rest my case. :slight_smile:

No, because a class is a concrete "thing" whose access level which鈥攚hile
providing an upper bound for access levels of its defaulting members鈥攊s
otherwise independent of the access level of its members.

Extensions, on the other hand, aren't a concrete thing of their own. The
access level on an extension exists *solely* as a shortcut to specify the
upper bound for its defaulting members that are injected into the main type.

What happens in your example if you replace "private" with "public"? Then
myFunc has internal access but myFunc2 is public. So the "inconsistency"
you're pointing out between access inherited from a type and access
inherited from an extension already exists鈥攖hey're apples and oranges.

That's why access levels of classes/structs/other types aren't relevant
examples here鈥攅xtensions treat access levels fundamentally differently.

Sure. Extensions apply a default upper bound and types can lower the
upper bound of the default internal members. The upper bound on the below
example is the same for both when dealing with top level private.

Extensions should resolve their upper bound accessibility where the
鈥榩rivate鈥 appears explicitly and this now happens to be the same for both
types and extensions regardless of how they are enforced.

But *why* do you think that should be? You're stating what the current
situation is and you say that it "should" be that way, but why should we
accept that status quo instead of making "private extension" more useful
for people who use "private" in the sense introduced by SE-0169, when the
argument for consistency can honestly be argued either way (the two options
I wrote a few messages up)?

Oh :slight_smile: Because I believe that lowering the scope of 鈥減rivate extension鈥
would undermine the spirit of 169. 169 was a compromise after 159 was
rejected. 169 was meant to make fileprivate less common and thus more
meaningful when it occurs in source. Where 169 was meant to relax the
rules, the proposed 鈥渇ix鈥 would force people who now use 鈥減rivate
extension鈥 to use 鈥渇ileprivate extension鈥 thus making fileprivate more
common. In other words, 169 was about relaxing rules and not about
tightening down the rules or allowing 鈥渢rue鈥 private to be applied as a
default ACL extension.

鈥渟coped" `private extension` can鈥檛 be archived now in the same way that
鈥榦pen extension鈥 is not allowed. The lowest and highest ACL are not able to
be applied as default extension modifiers and this makes sense to me.

There is no solution that will make everyone happy: maintaining the status quo makes 鈥渇ileprivate鈥 too common and therefore not meaningful when it occurs in source; removing or diluting scope-level access control (as in SE-0159 <https://github.com/apple/swift-evolution/blob/master/proposals/0159-fix-private-access-levels.md> and this proposal)

https://lists.swift.org/pipermail/swift-evolution-announce/2017-April/000357.html

private class MyClass {
聽聽聽聽static func myFunc(){ // This would now act differently from
private extensions?
聽聽聽聽聽聽聽聽print("acts like fileprivate now")
聽聽聽聽}
}

private class MyClass2 {}

private extension MyClass2{
聽聽聽聽聽聽static func myFunc2(){
聽聽聽聽聽聽聽print("Same as MyClass.myFunc")
聽聽聽聽}
}

MyClass.myFunc() // acts like fileprivate
MyClass2.myFunc2() // The proposed change would hide myFunc2
聽聽聽聽聽聽聽聽聽聽聽聽聽//Error: 'myFunc2' is inaccessible due to 'private'
protection level

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

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

This, I think, is the most persuasive argument available here; it provides a concrete use case to justify why one design is superior to the other.

open extension do not exist either. :slight_smile:

路路路

On Oct 7, 2017, at 8:28 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Sat, Oct 7, 2017 at 10:26 David Hart via swift-evolution <swift-evolution@swift.org> wrote:
One argument: without this fix, private is the only access level for which we have no means to easily and implicitly apply an access level to a group of members. And it bums me to have to explicitly type private on ever single member to achieve the same result as I can with any other access level.

In the same way that we need to be explicit about open in extension members or public in public type members; the lowest access version of scope private needs to also be explicit in private extension members and top level private concrete type members.

The premise of 169 was never about creating a new version of scope private that could only be used in extensions. It just relaxed the rules for explicit private extension members.

This, I think, is the most persuasive argument available here; it provides
a concrete use case to justify why one design is superior to the other.

open extension do not exist either. :slight_smile:

That could be fixed too then.

路路路

On Sat, Oct 7, 2017 at 12:21 Jose Cheyo Jimenez <cheyo@masters3d.com> wrote:

On Oct 7, 2017, at 8:28 AM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Sat, Oct 7, 2017 at 10:26 David Hart via swift-evolution < > swift-evolution@swift.org> wrote:

One argument: without this fix, private is the only access level for which

we have no means to easily and implicitly apply an access level to a group
of members. And it bums me to have to explicitly type private on ever
single member to achieve the same result as I can with any other access
level.

In the same way that we need to be explicit about open in extension
members or public in public type members; the lowest access version of
scope private needs to also be explicit in private extension members and
top level private concrete type members.

The premise of 169 was never about creating a new version of scope private
that could only be used in extensions. It just relaxed the rules for
explicit private extension members.