On 05.10.2017 20:52, Jose Cheyo Jimenez via swift-evolution wrote:
On Oct 5, 2017, at 4:32 AM, David Hart <da...@hartbit.com
<mailto:da...@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:
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’ve always used `private extension` when I want to add methods to String or other build in types.
It’s not a bug, but its unfortunate the behaviour wasn’t changed at the same time as SE-0169, and it now is very
inconsistent. I also don’t 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.
“No 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.
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.allev...@gmail.com
<mailto:tony.allev...@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—other than "it's too late to change it"—why "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’s 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 <bjho...@gmail.com
<mailto:bjho...@gmail.com>> wrote:
It certainly could break *some* code. But it only breaks code written by an
author who wrote ‘private
extension’ knowing that ‘fileprivate 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 ‘fileprivate extension’ by
the 2->3 migrator.)
So existing code that says ‘private extension’ was written in a Swift 3 or
4 era when ‘fileprivate’ was an
option. If the goal was specifically to share it with the whole file, it
seems likely that most authors would
have used ‘fileprivate extension’ instead of ‘private 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’m 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’s 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’s 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’t 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’s 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 “fix” would have made it a breaking
change. I doubt 169 would had been
accepted if it was a breaking change. I don’t think it’s 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
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution