Enhancing access levels without breaking changes

This struck me as a bit odd at first, but the more I think about it, the more I really like the ability to nest extensions/scopes. The one issue I see is sticking that public extension inside a private one. I think you would have to mark ‘secret: Int’ as private instead of the extension itself to allow the effect you are looking for...

What I ultimately want is the ability to declare storage in extensions in the same submodule. Combining that with fileprivate will allow the same tricks without the indentation (together in their own file). This nesting will help in the mean-time (and would still be useful after for those who prefer to organize their code in fewer/longer files). I think it could be helpful in other ways too…

What do you think of `partial` types like C# but limited to a file?
partial type - C# Reference - C# | Microsoft Learn

[swift-evolution] [Review] SE-0169: Improve Interaction Between private Declarations and Extensions

That's the direction the new proposal (0169) is going towards with extensions in the same file.

I don’t see how SE-0169 do that more than any other meaning private got until now. This was already the case with the initial meaning of private, and was the case with fileprivate.

The current semantics of private don’t give any support for partial types like in C# because the accessibility is restricted to the current scope. With SE-0169’s private, extensions in the same file as the type share that scope. Plus, the Alternatives Considered section of the proposal discusses potential future directions where those extensions could look even more like C# partials :)

SE-169 could be emulated cleanly by introducing partial types within the same scope as a new feature completely separate from extensions. Partial types would not require redefining how private or extensions work now. It would also serve as a way to communicate to the user that the type is not done being defined so if they want to encapsulate the type completely, They have to make it non partial.

···

On Apr 10, 2017, at 12:20 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

On 10 Apr 2017, at 08:21, Jean-Daniel <mailing@xenonium.com> wrote:
Le 10 avr. 2017 à 07:15, David Hart via swift-evolution <swift-evolution@swift.org> a écrit :
On 10 Apr 2017, at 05:08, Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org> wrote:

On Apr 9, 2017, at 7:14 PM, Jonathan Hull via swift-evolution <swift-evolution@swift.org> wrote:

And for file splitting and visibility control, we need submodules. Until then, if this proposal is to define the ultimate meaning of private, I rather like this meaning that the SE-0025 one.

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

Extensions can already do what partials would do, and more—Swift does not
need two features that are almost the same but with subtle differences when
it comes to the visibility of its members. That seems like something that
will only cause confusion for users. Partials feel like trying to shoehorn
a feature from another language into Swift to solve an unrelated problem.

Swift 2 and 3 have never had type-oriented visibility—they've only had
visibility that covered contiguous regions of the symbol space ("the
universe", "the module", "the file", and then in Swift 3, "the enclosing
scope"). Being able to split a type's *scope* with partials (as opposed to
just the type itself with extensions) across multiple files files would be
quite inconsistent with how visibility in Swift has been so far.

At some point, we need to come to grips with the fact that there are going
to be keywords we think are a little ugly (I much preferred the original
definition of "private", but "fileprivate" is part of Swift now and I've
moved on) and that there's never going to be a way to perfectly audit
visibility of every single member that we write in a way that makes
everyone happy.

I don't want to sound dismissive, but I feel like it's simply not
productive to keep rehashing visibility over and over again.

···

On Mon, Apr 10, 2017 at 7:20 AM Jose Cheyo Jimenez via swift-evolution < swift-evolution@swift.org> wrote:

On Apr 10, 2017, at 12:20 AM, David Hart via swift-evolution < > swift-evolution@swift.org> wrote:

On 10 Apr 2017, at 08:21, Jean-Daniel <mailing@xenonium.com> wrote:

Le 10 avr. 2017 à 07:15, David Hart via swift-evolution < > swift-evolution@swift.org> a écrit :

On 10 Apr 2017, at 05:08, Jose Cheyo Jimenez via swift-evolution < > swift-evolution@swift.org> wrote:

On Apr 9, 2017, at 7:14 PM, Jonathan Hull via swift-evolution < > swift-evolution@swift.org> wrote:

This struck me as a bit odd at first, but the more I think about it, the
more I really like the ability to nest extensions/scopes. The one issue I
see is sticking that public extension inside a private one. I think you
would have to mark ‘secret: Int’ as private instead of the extension itself
to allow the effect you are looking for...

What I ultimately want is the ability to declare storage in extensions in
the same submodule. Combining that with fileprivate will allow the same
tricks without the indentation (together in their own file). This nesting
will help in the mean-time (and would still be useful after for those who
prefer to organize their code in fewer/longer files). I think it could be
helpful in other ways too…

What do you think of `partial` types like C# but limited to a file?
partial type - C# Reference - C# | Microsoft Learn

[swift-evolution] [Review] SE-0169: Improve Interaction Between private Declarations and Extensions

That's the direction the new proposal (0169) is going towards with
extensions in the same file.

I don’t see how SE-0169 do that more than any other meaning private got
until now. This was already the case with the initial meaning of private,
and was the case with fileprivate.

The current semantics of private don’t give any support for partial types
like in C# because the accessibility is restricted to the current scope.
With SE-0169’s private, extensions in the same file as the type share that
scope. Plus, the *Alternatives Considered* section of the proposal
discusses potential future directions where those extensions could look
even more like C# partials :)

SE-169 could be emulated cleanly by introducing partial types within the *same
scope* as a new feature completely separate from extensions. Partial
types would not require redefining how private or extensions work now. It
would also serve as a way to communicate to the user that the type is not
done being defined so if they want to encapsulate the type completely, They
have to make it non partial.

And for file splitting and visibility control, we need submodules. Until
then, if this proposal is to define the ultimate meaning of private, I
rather like this meaning that the SE-0025 one.

_______________________________________________
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

Sent from my iPhone

I have not voted in favor or against the proposal. I have been reading a lot of responses but I agree with Tony.

When I started reading the proposal everything was more or less fine half way through the proposal because it was reverting private to fileprivate between the type and its extensions within the same file. I said, if you think of the type and its extensions as a unit then it makes sense. I can explain that.

Then it started describing a different behavior among the extensions located in a file separate from the file containing the definition of the type. That just started a whole debate inside my head and I understand the passionate responses on both sides.

But then I imagined myself explaining this to someone new to Swift and it just doesn't seem right. If it becomes convoluted then that's a red flag that it does not belong in Swift.

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

John.

···

On Apr 11, 2017, at 1:34 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:
On 11 Apr 2017, at 01:37, Ricardo Parada via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I agree fileprivate may be ugly to some and it may be more popular than private. But I think fileprivate is very clear. I know what it does from its name without having to ask. And private behaves the way private works in other languages.

Regards

On Apr 10, 2017, at 1:35 PM, Tony Allevato via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Mon, Apr 10, 2017 at 9:49 AM Tino Heth <2th@gmx.de <mailto:2th@gmx.de>> wrote:

But even outside the generated code use cases, it's nice to just be able to implement helpers or additional "convenience" conformances in separate files named appropriately (like "Type+Protocol.swift" or "Type+Helpers.swift"). I find it makes my codebase easier to navigate.

No doubt about the usefulness of having separate files with extensions here

If nothing else, nested extensions could save those who actually don't care much about such issues from another breaking change in Swift — and imho it adds consistency:
We can nest types, so why can't we nest extensions?

Because types and extensions are quite different beasts, so something that applies to one doesn't necessarily apply to the other.

I don't buy this argument at all without an objective explanation why the curly braces of extensions should be treated different than the curly braces of types...

They shouldn't be. That's why I don't support SE-0169 either, because it would allow extensions to extend the *scope* rather than the *type*, but only within the same file. I think that's fundamentally broken.

But my comment wasn't about curly braces—it was about types vs. extensions. For example, you can declare local types within a function, but you can't extend a type within a function (nor do I think it would be a good idea).

I don't think that holds its weight. This feels like another case of "let's try to satisfy everyone who's unhappy with some part of Swift visibility by changing a completely different feature to make things fall into place", which I don't think is a sound motivation or design principle. The example you posted in your initial message weaves multiple types/nesting levels together in a way that looks *incredibly* difficult to follow/parse to even an experienced user of the language.

Did you noticed that I started this example as mockery? In real life, I would hopefully never nest more than once… and do you think sprinkling parts of class over the project is easier to follow?

Depending on the type, yes. I wouldn't sprinkle the *fundamental/core* parts of a type across the project, but if there's some kind of "aside" functionality that doesn't depend on private knowledge of the type, then I find it to be a nice feature to have. It requires me to have reasonable names to my source files, but that's not a significant burden.

Everyone seems to be striving for a "perfect" level of access control that lets individual types/members dictate precisely what other types/members can access them. I'm not sure if that perfection is attainable or not, but even if it is, I don't think it's something we should strive for. I'd rather have a simple visibility model that leaks a little than an air-tight model that allows people to write overly complicated code for the sake of fine-tuning access.

I had no desire to change the model of Swift 2 — but apparently, others thought it wasn't sufficient, and I'd rather prefer a conceptually simple model like nesting over a complicated one with less power.

Let's remember that the core team has limited resources to implement the things we propose, and if I have to choose between, say, serialization, reflection, asynchronous constructs, and rehashing visibility levels yet again, it's clear to me which one I would want dropped on the floor. I don't want perfect to be the enemy of good.

Well, right now, there are several (at least one ;-) proposals that aim for a breaking change of the whole model… nested extensions break nothing, so it can be delayed for as long as the core team likes, without causing any trouble.

_______________________________________________
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

Sent from my iPhone

I have not voted in favor or against the proposal. I have been reading a lot of responses but I agree with Tony.

When I started reading the proposal everything was more or less fine half way through the proposal because it was reverting private to fileprivate between the type and its extensions within the same file. I said, if you think of the type and its extensions as a unit then it makes sense. I can explain that.

Then it started describing a different behavior among the extensions located in a file separate from the file containing the definition of the type. That just started a whole debate inside my head and I understand the passionate responses on both sides.

But then I imagined myself explaining this to someone new to Swift and it just doesn't seem right. If it becomes convoluted then that's a red flag that it does not belong in Swift.

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

We had to take a stance and Chris seemed to prefer the rule that was proposed. I didn't press because I'm sure he has reasons for preferring it that way. But I have a preference for generalizing visibility to all extensions, even to those in a different file than the type.

···

On 11 Apr 2017, at 09:40, John McCall <rjmccall@apple.com> wrote:

On Apr 11, 2017, at 1:34 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:
On 11 Apr 2017, at 01:37, Ricardo Parada via swift-evolution <swift-evolution@swift.org> wrote:

John.

I agree fileprivate may be ugly to some and it may be more popular than private. But I think fileprivate is very clear. I know what it does from its name without having to ask. And private behaves the way private works in other languages.

Regards

On Apr 10, 2017, at 1:35 PM, Tony Allevato via swift-evolution <swift-evolution@swift.org> wrote:

On Mon, Apr 10, 2017 at 9:49 AM Tino Heth <2th@gmx.de> wrote:

But even outside the generated code use cases, it's nice to just be able to implement helpers or additional "convenience" conformances in separate files named appropriately (like "Type+Protocol.swift" or "Type+Helpers.swift"). I find it makes my codebase easier to navigate.

No doubt about the usefulness of having separate files with extensions here

If nothing else, nested extensions could save those who actually don't care much about such issues from another breaking change in Swift — and imho it adds consistency:
We can nest types, so why can't we nest extensions?

Because types and extensions are quite different beasts, so something that applies to one doesn't necessarily apply to the other.

I don't buy this argument at all without an objective explanation why the curly braces of extensions should be treated different than the curly braces of types...

They shouldn't be. That's why I don't support SE-0169 either, because it would allow extensions to extend the *scope* rather than the *type*, but only within the same file. I think that's fundamentally broken.

But my comment wasn't about curly braces—it was about types vs. extensions. For example, you can declare local types within a function, but you can't extend a type within a function (nor do I think it would be a good idea).

I don't think that holds its weight. This feels like another case of "let's try to satisfy everyone who's unhappy with some part of Swift visibility by changing a completely different feature to make things fall into place", which I don't think is a sound motivation or design principle. The example you posted in your initial message weaves multiple types/nesting levels together in a way that looks *incredibly* difficult to follow/parse to even an experienced user of the language.

Did you noticed that I started this example as mockery? In real life, I would hopefully never nest more than once… and do you think sprinkling parts of class over the project is easier to follow?

Depending on the type, yes. I wouldn't sprinkle the *fundamental/core* parts of a type across the project, but if there's some kind of "aside" functionality that doesn't depend on private knowledge of the type, then I find it to be a nice feature to have. It requires me to have reasonable names to my source files, but that's not a significant burden.

Everyone seems to be striving for a "perfect" level of access control that lets individual types/members dictate precisely what other types/members can access them. I'm not sure if that perfection is attainable or not, but even if it is, I don't think it's something we should strive for. I'd rather have a simple visibility model that leaks a little than an air-tight model that allows people to write overly complicated code for the sake of fine-tuning access.

I had no desire to change the model of Swift 2 — but apparently, others thought it wasn't sufficient, and I'd rather prefer a conceptually simple model like nesting over a complicated one with less power.

Let's remember that the core team has limited resources to implement the things we propose, and if I have to choose between, say, serialization, reflection, asynchronous constructs, and rehashing visibility levels yet again, it's clear to me which one I would want dropped on the floor. I don't want perfect to be the enemy of good.

Well, right now, there are several (at least one ;-) proposals that aim for a breaking change of the whole model… nested extensions break nothing, so it can be delayed for as long as the core team likes, without causing any trouble.

_______________________________________________
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 think there is a technical limitation if the visibility goes beyond the compilation unit (unless whole module optimization is turned on).

···

On Apr 11, 2017, at 3:53 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

On 11 Apr 2017, at 09:40, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

On Apr 11, 2017, at 1:34 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sent from my iPhone
On 11 Apr 2017, at 01:37, Ricardo Parada via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I have not voted in favor or against the proposal. I have been reading a lot of responses but I agree with Tony.

When I started reading the proposal everything was more or less fine half way through the proposal because it was reverting private to fileprivate between the type and its extensions within the same file. I said, if you think of the type and its extensions as a unit then it makes sense. I can explain that.

Then it started describing a different behavior among the extensions located in a file separate from the file containing the definition of the type. That just started a whole debate inside my head and I understand the passionate responses on both sides.

But then I imagined myself explaining this to someone new to Swift and it just doesn't seem right. If it becomes convoluted then that's a red flag that it does not belong in Swift.

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

We had to take a stance and Chris seemed to prefer the rule that was proposed. I didn't press because I'm sure he has reasons for preferring it that way. But I have a preference for generalizing visibility to all extensions, even to those in a different file than the type.

I’m not suggesting visibility beyond the compilation unit. That would break the hierarchy of visibility layers: accessibility levels have always been contained in one-another and that’s why you can go from private, to fileprivate, to internal, to public, to open (but not the other way round) without the risk of any compilation error. If all scopes of a type were visible to each other (whatever the file), you could not go from private to fileprivate.

I’m talking about extensions of the same type in the same file (but in a separate file from the type) to be able to share private members:

Type.swift

struct A {
}

Other.swift

extension A {
    func foo() {
        bar()
    }
}

extension A {
    private func bar() {
    }
}

···

On 11 Apr 2017, at 13:29, Jonathan Hull <jhull@gbis.com> wrote:

On Apr 11, 2017, at 3:53 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 11 Apr 2017, at 09:40, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

On Apr 11, 2017, at 1:34 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sent from my iPhone
On 11 Apr 2017, at 01:37, Ricardo Parada via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I have not voted in favor or against the proposal. I have been reading a lot of responses but I agree with Tony.

When I started reading the proposal everything was more or less fine half way through the proposal because it was reverting private to fileprivate between the type and its extensions within the same file. I said, if you think of the type and its extensions as a unit then it makes sense. I can explain that.

Then it started describing a different behavior among the extensions located in a file separate from the file containing the definition of the type. That just started a whole debate inside my head and I understand the passionate responses on both sides.

But then I imagined myself explaining this to someone new to Swift and it just doesn't seem right. If it becomes convoluted then that's a red flag that it does not belong in Swift.

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

We had to take a stance and Chris seemed to prefer the rule that was proposed. I didn't press because I'm sure he has reasons for preferring it that way. But I have a preference for generalizing visibility to all extensions, even to those in a different file than the type.

I think there is a technical limitation if the visibility goes beyond the compilation unit (unless whole module optimization is turned on).

To me, the reason for limiting it to a file is about predictability, the ability to locally reason about a type, and the need to define some boundary (for symbol visibility reasons). Saying that extensions to a type have access to private members if they are in the same module is just as arbitrary as limiting it to a single file, and a whole lot less useful from the “reasoning about a type” perspective.

Expanding it beyond a module would require a ton of stuff to be exported that otherwise wouldn’t be, and would defeat a ton of optimization potential that we can’t accept.

-Chris

···

On Apr 11, 2017, at 3:53 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

We had to take a stance and Chris seemed to prefer the rule that was proposed. I didn't press because I'm sure he has reasons for preferring it that way. But I have a preference for generalizing visibility to all extensions, even to those in a different file than the type.

Sent from my iPhone

I have not voted in favor or against the proposal. I have been reading a lot of responses but I agree with Tony.

When I started reading the proposal everything was more or less fine half way through the proposal because it was reverting private to fileprivate between the type and its extensions within the same file. I said, if you think of the type and its extensions as a unit then it makes sense. I can explain that.

Then it started describing a different behavior among the extensions located in a file separate from the file containing the definition of the type. That just started a whole debate inside my head and I understand the passionate responses on both sides.

But then I imagined myself explaining this to someone new to Swift and it just doesn't seem right. If it becomes convoluted then that's a red flag that it does not belong in Swift.

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

We had to take a stance and Chris seemed to prefer the rule that was proposed. I didn't press because I'm sure he has reasons for preferring it that way. But I have a preference for generalizing visibility to all extensions, even to those in a different file than the type.

I think there is a technical limitation if the visibility goes beyond the compilation unit (unless whole module optimization is turned on).

I’m not suggesting visibility beyond the compilation unit. That would break the hierarchy of visibility layers: accessibility levels have always been contained in one-another and that’s why you can go from private, to fileprivate, to internal, to public, to open (but not the other way round) without the risk of any compilation error. If all scopes of a type were visible to each other (whatever the file), you could not go from private to fileprivate.

I’m talking about extensions of the same type in the same file (but in a separate file from the type) to be able to share private members:

Type.swift

struct A {
}

Other.swift

extension A {
    func foo() {
        bar()
    }
}

extension A {
    private func bar() {
    }
}

If this is not how your proposal already works I missed that aspect earlier and find it extremely perplexing (which is probably why I missed it). It leaves scoped access working as in Swift 3 in exactly the case where it is least useful. We cannot place stored properties in any extensions, let alone extensions in a file other than the one containing the original declaration.

···

Sent from my iPad

On Apr 11, 2017, at 8:53 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

On 11 Apr 2017, at 13:29, Jonathan Hull <jhull@gbis.com> wrote:
On Apr 11, 2017, at 3:53 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:
On 11 Apr 2017, at 09:40, John McCall <rjmccall@apple.com> wrote:

On Apr 11, 2017, at 1:34 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:
On 11 Apr 2017, at 01:37, Ricardo Parada via swift-evolution <swift-evolution@swift.org> wrote:

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

Sent from my iPad

Sent from my iPhone

I have not voted in favor or against the proposal. I have been reading a lot of responses but I agree with Tony.

When I started reading the proposal everything was more or less fine half way through the proposal because it was reverting private to fileprivate between the type and its extensions within the same file. I said, if you think of the type and its extensions as a unit then it makes sense. I can explain that.

Then it started describing a different behavior among the extensions located in a file separate from the file containing the definition of the type. That just started a whole debate inside my head and I understand the passionate responses on both sides.

But then I imagined myself explaining this to someone new to Swift and it just doesn't seem right. If it becomes convoluted then that's a red flag that it does not belong in Swift.

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

We had to take a stance and Chris seemed to prefer the rule that was proposed. I didn't press because I'm sure he has reasons for preferring it that way. But I have a preference for generalizing visibility to all extensions, even to those in a different file than the type.

I think there is a technical limitation if the visibility goes beyond the compilation unit (unless whole module optimization is turned on).

I’m not suggesting visibility beyond the compilation unit. That would break the hierarchy of visibility layers: accessibility levels have always been contained in one-another and that’s why you can go from private, to fileprivate, to internal, to public, to open (but not the other way round) without the risk of any compilation error. If all scopes of a type were visible to each other (whatever the file), you could not go from private to fileprivate.

I’m talking about extensions of the same type in the same file (but in a separate file from the type) to be able to share private members:

Type.swift

struct A {
}

Other.swift

extension A {
    func foo() {
        bar()
    }
}

extension A {
    private func bar() {
    }
}

If this is not how your proposal already works I missed that aspect earlier and find it extremely perplexing (which is probably why I missed it).

It's mentioned in the Derailed design section:

This proposal does not change the behavior of extensions that are not in the same file as the type - i.e., extensions in a seperate file to the type do not share access between themselves:

But I agree this should be changed if there is no major technical reason against it.

···

On 11 Apr 2017, at 16:27, Matthew Johnson <matthew@anandabits.com> wrote:

On Apr 11, 2017, at 8:53 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

On 11 Apr 2017, at 13:29, Jonathan Hull <jhull@gbis.com> wrote:
On Apr 11, 2017, at 3:53 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:
On 11 Apr 2017, at 09:40, John McCall <rjmccall@apple.com> wrote:

On Apr 11, 2017, at 1:34 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:
On 11 Apr 2017, at 01:37, Ricardo Parada via swift-evolution <swift-evolution@swift.org> wrote:

It leaves scoped access working as in Swift 3 in exactly the case where it is least useful. We cannot place stored properties in any extensions, let alone extensions in a file other than the one containing the original declaration.

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

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

We had to take a stance and Chris seemed to prefer the rule that was proposed. I didn't press because I'm sure he has reasons for preferring it that way. But I have a preference for generalizing visibility to all extensions, even to those in a different file than the type.

To me, the reason for limiting it to a file is about predictability, the ability to locally reason about a type, and the need to define some boundary (for symbol visibility reasons). Saying that extensions to a type have access to private members if they are in the same module is just as arbitrary as limiting it to a single file, and a whole lot less useful from the “reasoning about a type” perspective.

I think you misunderstand. We were talking about two extensions of a type, in a different file from the type, to share private members between themselves.

Doug Gregor mentioned it during the PR process and we added an example to disallow it, but in hindsight, I think it should be allowed.

···

On 12 Apr 2017, at 07:16, Chris Lattner <clattner@nondot.org> wrote:
On Apr 11, 2017, at 3:53 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

Expanding it beyond a module would require a ton of stuff to be exported that otherwise wouldn’t be, and would defeat a ton of optimization potential that we can’t accept.

-Chris

Sent from my iPad

Sent from my iPhone

I have not voted in favor or against the proposal. I have been reading a lot of responses but I agree with Tony.

When I started reading the proposal everything was more or less fine half way through the proposal because it was reverting private to fileprivate between the type and its extensions within the same file. I said, if you think of the type and its extensions as a unit then it makes sense. I can explain that.

Then it started describing a different behavior among the extensions located in a file separate from the file containing the definition of the type. That just started a whole debate inside my head and I understand the passionate responses on both sides.

But then I imagined myself explaining this to someone new to Swift and it just doesn't seem right. If it becomes convoluted then that's a red flag that it does not belong in Swift.

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

We had to take a stance and Chris seemed to prefer the rule that was proposed. I didn't press because I'm sure he has reasons for preferring it that way. But I have a preference for generalizing visibility to all extensions, even to those in a different file than the type.

I think there is a technical limitation if the visibility goes beyond the compilation unit (unless whole module optimization is turned on).

I’m not suggesting visibility beyond the compilation unit. That would break the hierarchy of visibility layers: accessibility levels have always been contained in one-another and that’s why you can go from private, to fileprivate, to internal, to public, to open (but not the other way round) without the risk of any compilation error. If all scopes of a type were visible to each other (whatever the file), you could not go from private to fileprivate.

I’m talking about extensions of the same type in the same file (but in a separate file from the type) to be able to share private members:

Type.swift

struct A {
}

Other.swift

extension A {
    func foo() {
        bar()
    }
}

extension A {
    private func bar() {
    }
}

If this is not how your proposal already works I missed that aspect earlier and find it extremely perplexing (which is probably why I missed it).

It's mentioned in the Derailed design section:

This proposal does not change the behavior of extensions that are not in the same file as the type - i.e., extensions in a seperate file to the type do not share access between themselves:

But I agree this should be changed if there is no major technical reason against it.

I'm not aware of any technical reason why extensions in the same file should not have access to each other's members.

John.

···

On Apr 11, 2017, at 12:00 PM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:
On 11 Apr 2017, at 16:27, Matthew Johnson <matthew@anandabits.com <mailto:matthew@anandabits.com>> wrote:

On Apr 11, 2017, at 8:53 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 11 Apr 2017, at 13:29, Jonathan Hull <jhull@gbis.com <mailto:jhull@gbis.com>> wrote:

On Apr 11, 2017, at 3:53 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
On 11 Apr 2017, at 09:40, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

On Apr 11, 2017, at 1:34 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
On 11 Apr 2017, at 01:37, Ricardo Parada via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

It leaves scoped access working as in Swift 3 in exactly the case where it is least useful. We cannot place stored properties in any extensions, let alone extensions in a file other than the one containing the original declaration.

_______________________________________________
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 don't want to make any change until Chris has been able to chime in. If he agrees with us, what should be done?

• Immediate change in the proposal?
• Would it have to go through a new review?
• Or can the Core Team make the change if it is accepted?

···

On 11 Apr 2017, at 19:01, John McCall <rjmccall@apple.com> wrote:

On Apr 11, 2017, at 12:00 PM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

On 11 Apr 2017, at 16:27, Matthew Johnson <matthew@anandabits.com> wrote:

Sent from my iPad

On Apr 11, 2017, at 8:53 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

On 11 Apr 2017, at 13:29, Jonathan Hull <jhull@gbis.com> wrote:

On Apr 11, 2017, at 3:53 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

On 11 Apr 2017, at 09:40, John McCall <rjmccall@apple.com> wrote:

On Apr 11, 2017, at 1:34 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

Sent from my iPhone
On 11 Apr 2017, at 01:37, Ricardo Parada via swift-evolution <swift-evolution@swift.org> wrote:

I have not voted in favor or against the proposal. I have been reading a lot of responses but I agree with Tony.

When I started reading the proposal everything was more or less fine half way through the proposal because it was reverting private to fileprivate between the type and its extensions within the same file. I said, if you think of the type and its extensions as a unit then it makes sense. I can explain that.

Then it started describing a different behavior among the extensions located in a file separate from the file containing the definition of the type. That just started a whole debate inside my head and I understand the passionate responses on both sides.

But then I imagined myself explaining this to someone new to Swift and it just doesn't seem right. If it becomes convoluted then that's a red flag that it does not belong in Swift.

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

We had to take a stance and Chris seemed to prefer the rule that was proposed. I didn't press because I'm sure he has reasons for preferring it that way. But I have a preference for generalizing visibility to all extensions, even to those in a different file than the type.

I think there is a technical limitation if the visibility goes beyond the compilation unit (unless whole module optimization is turned on).

I’m not suggesting visibility beyond the compilation unit. That would break the hierarchy of visibility layers: accessibility levels have always been contained in one-another and that’s why you can go from private, to fileprivate, to internal, to public, to open (but not the other way round) without the risk of any compilation error. If all scopes of a type were visible to each other (whatever the file), you could not go from private to fileprivate.

I’m talking about extensions of the same type in the same file (but in a separate file from the type) to be able to share private members:

Type.swift

struct A {
}

Other.swift

extension A {
    func foo() {
        bar()
    }
}

extension A {
    private func bar() {
    }
}

If this is not how your proposal already works I missed that aspect earlier and find it extremely perplexing (which is probably why I missed it).

It's mentioned in the Derailed design section:

This proposal does not change the behavior of extensions that are not in the same file as the type - i.e., extensions in a seperate file to the type do not share access between themselves:

But I agree this should be changed if there is no major technical reason against it.

I'm not aware of any technical reason why extensions in the same file should not have access to each other's members.

John.

It leaves scoped access working as in Swift 3 in exactly the case where it is least useful. We cannot place stored properties in any extensions, let alone extensions in a file other than the one containing the original declaration.

_______________________________________________
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

Ah, you’re saying:

a.swift:
struct X {}

b.swift:
extension X {
  private func f() {}
}

extension X {
  func g() { f() }
}

If so, then yes, I agree we should accept that.

-Chris

···

On Apr 11, 2017, at 10:30 PM, David Hart <david@hartbit.com> wrote:

To me, the reason for limiting it to a file is about predictability, the ability to locally reason about a type, and the need to define some boundary (for symbol visibility reasons). Saying that extensions to a type have access to private members if they are in the same module is just as arbitrary as limiting it to a single file, and a whole lot less useful from the “reasoning about a type” perspective.

I think you misunderstand. We were talking about two extensions of a type, in a different file from the type, to share private members between themselves.

Doug Gregor mentioned it during the PR process and we added an example to disallow it, but in hindsight, I think it should be allowed.

Should we edit the proposal or let the Core Team fix it during review as John suggests?

···

On 12 Apr 2017, at 07:42, Chris Lattner <clattner@nondot.org> wrote:

On Apr 11, 2017, at 10:30 PM, David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:

To me, the reason for limiting it to a file is about predictability, the ability to locally reason about a type, and the need to define some boundary (for symbol visibility reasons). Saying that extensions to a type have access to private members if they are in the same module is just as arbitrary as limiting it to a single file, and a whole lot less useful from the “reasoning about a type” perspective.

I think you misunderstand. We were talking about two extensions of a type, in a different file from the type, to share private members between themselves.

Doug Gregor mentioned it during the PR process and we added an example to disallow it, but in hindsight, I think it should be allowed.

Ah, you’re saying:

a.swift:
struct X {}

b.swift:
extension X {
  private func f() {}
}

extension X {
  func g() { f() }
}

If so, then yes, I agree we should accept that.

-Chris

That would remove the objection I had. It would make the first half and the second half of the proposal consistent.

···

On Apr 12, 2017, at 1:42 AM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Apr 11, 2017, at 10:30 PM, David Hart <david@hartbit.com> wrote:

To me, the reason for limiting it to a file is about predictability, the ability to locally reason about a type, and the need to define some boundary (for symbol visibility reasons). Saying that extensions to a type have access to private members if they are in the same module is just as arbitrary as limiting it to a single file, and a whole lot less useful from the “reasoning about a type” perspective.

I think you misunderstand. We were talking about two extensions of a type, in a different file from the type, to share private members between themselves.

Doug Gregor mentioned it during the PR process and we added an example to disallow it, but in hindsight, I think it should be allowed.

Ah, you’re saying:

a.swift:
struct X {}

b.swift:
extension X {
  private func f() {}
}

extension X {
  func g() { f() }
}

If so, then yes, I agree we should accept that.

-Chris

This never went into a review. The pull request is still open Reduce with inout by chriseidhof · Pull Request #587 · apple/swift-evolution · GitHub

···

On Apr 11, 2017, at 10:45 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

I don't want to make any change until Chris has been able to chime in. If he agrees with us, what should be done?

• Immediate change in the proposal?
• Would it have to go through a new review?
• Or can the Core Team make the change if it is accepted?

On 11 Apr 2017, at 19:01, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

On Apr 11, 2017, at 12:00 PM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 11 Apr 2017, at 16:27, Matthew Johnson <matthew@anandabits.com <mailto:matthew@anandabits.com>> wrote:

Sent from my iPad

On Apr 11, 2017, at 8:53 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 11 Apr 2017, at 13:29, Jonathan Hull <jhull@gbis.com <mailto:jhull@gbis.com>> wrote:

On Apr 11, 2017, at 3:53 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 11 Apr 2017, at 09:40, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

On Apr 11, 2017, at 1:34 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sent from my iPhone
On 11 Apr 2017, at 01:37, Ricardo Parada via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I have not voted in favor or against the proposal. I have been reading a lot of responses but I agree with Tony.

When I started reading the proposal everything was more or less fine half way through the proposal because it was reverting private to fileprivate between the type and its extensions within the same file. I said, if you think of the type and its extensions as a unit then it makes sense. I can explain that.

Then it started describing a different behavior among the extensions located in a file separate from the file containing the definition of the type. That just started a whole debate inside my head and I understand the passionate responses on both sides.

But then I imagined myself explaining this to someone new to Swift and it just doesn't seem right. If it becomes convoluted then that's a red flag that it does not belong in Swift.

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

We had to take a stance and Chris seemed to prefer the rule that was proposed. I didn't press because I'm sure he has reasons for preferring it that way. But I have a preference for generalizing visibility to all extensions, even to those in a different file than the type.

I think there is a technical limitation if the visibility goes beyond the compilation unit (unless whole module optimization is turned on).

I’m not suggesting visibility beyond the compilation unit. That would break the hierarchy of visibility layers: accessibility levels have always been contained in one-another and that’s why you can go from private, to fileprivate, to internal, to public, to open (but not the other way round) without the risk of any compilation error. If all scopes of a type were visible to each other (whatever the file), you could not go from private to fileprivate.

I’m talking about extensions of the same type in the same file (but in a separate file from the type) to be able to share private members:

Type.swift

struct A {
}

Other.swift

extension A {
    func foo() {
        bar()
    }
}

extension A {
    private func bar() {
    }
}

If this is not how your proposal already works I missed that aspect earlier and find it extremely perplexing (which is probably why I missed it).

It's mentioned in the Derailed design section:

This proposal does not change the behavior of extensions that are not in the same file as the type - i.e., extensions in a seperate file to the type do not share access between themselves:

But I agree this should be changed if there is no major technical reason against it.

I'm not aware of any technical reason why extensions in the same file should not have access to each other's members.

John.

It leaves scoped access working as in Swift 3 in exactly the case where it is least useful. We cannot place stored properties in any extensions, let alone extensions in a file other than the one containing the original declaration.

_______________________________________________
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 don't want to make any change until Chris has been able to chime in. If he agrees with us, what should be done?

• Immediate change in the proposal?
• Would it have to go through a new review?

This is major change. I would hope for a new review if the proposal is being accepted.

I would also want this new behavior to be explicit thus making it a non breaking change.

···

On Apr 11, 2017, at 10:45 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

• Or can the Core Team make the change if it is accepted?

On 11 Apr 2017, at 19:01, John McCall <rjmccall@apple.com> wrote:

On Apr 11, 2017, at 12:00 PM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

On 11 Apr 2017, at 16:27, Matthew Johnson <matthew@anandabits.com> wrote:

Sent from my iPad

On Apr 11, 2017, at 8:53 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

On 11 Apr 2017, at 13:29, Jonathan Hull <jhull@gbis.com> wrote:

On Apr 11, 2017, at 3:53 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

On 11 Apr 2017, at 09:40, John McCall <rjmccall@apple.com> wrote:

On Apr 11, 2017, at 1:34 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

Sent from my iPhone
On 11 Apr 2017, at 01:37, Ricardo Parada via swift-evolution <swift-evolution@swift.org> wrote:

I have not voted in favor or against the proposal. I have been reading a lot of responses but I agree with Tony.

When I started reading the proposal everything was more or less fine half way through the proposal because it was reverting private to fileprivate between the type and its extensions within the same file. I said, if you think of the type and its extensions as a unit then it makes sense. I can explain that.

Then it started describing a different behavior among the extensions located in a file separate from the file containing the definition of the type. That just started a whole debate inside my head and I understand the passionate responses on both sides.

But then I imagined myself explaining this to someone new to Swift and it just doesn't seem right. If it becomes convoluted then that's a red flag that it does not belong in Swift.

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

We had to take a stance and Chris seemed to prefer the rule that was proposed. I didn't press because I'm sure he has reasons for preferring it that way. But I have a preference for generalizing visibility to all extensions, even to those in a different file than the type.

I think there is a technical limitation if the visibility goes beyond the compilation unit (unless whole module optimization is turned on).

I’m not suggesting visibility beyond the compilation unit. That would break the hierarchy of visibility layers: accessibility levels have always been contained in one-another and that’s why you can go from private, to fileprivate, to internal, to public, to open (but not the other way round) without the risk of any compilation error. If all scopes of a type were visible to each other (whatever the file), you could not go from private to fileprivate.

I’m talking about extensions of the same type in the same file (but in a separate file from the type) to be able to share private members:

Type.swift

struct A {
}

Other.swift

extension A {
    func foo() {
        bar()
    }
}

extension A {
    private func bar() {
    }
}

If this is not how your proposal already works I missed that aspect earlier and find it extremely perplexing (which is probably why I missed it).

It's mentioned in the Derailed design section:

This proposal does not change the behavior of extensions that are not in the same file as the type - i.e., extensions in a seperate file to the type do not share access between themselves:

But I agree this should be changed if there is no major technical reason against it.

I'm not aware of any technical reason why extensions in the same file should not have access to each other's members.

John.

It leaves scoped access working as in Swift 3 in exactly the case where it is least useful. We cannot place stored properties in any extensions, let alone extensions in a file other than the one containing the original declaration.

_______________________________________________
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

We’re not talking about the same proposal. I’m talking about SE-0169

···

On 11 Apr 2017, at 19:49, Daniel Duan <daniel@duan.org> wrote:

This never went into a review. The pull request is still open Reduce with inout by chriseidhof · Pull Request #587 · apple/swift-evolution · GitHub

On Apr 11, 2017, at 10:45 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I don't want to make any change until Chris has been able to chime in. If he agrees with us, what should be done?

• Immediate change in the proposal?
• Would it have to go through a new review?
• Or can the Core Team make the change if it is accepted?

On 11 Apr 2017, at 19:01, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

On Apr 11, 2017, at 12:00 PM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 11 Apr 2017, at 16:27, Matthew Johnson <matthew@anandabits.com <mailto:matthew@anandabits.com>> wrote:

Sent from my iPad

On Apr 11, 2017, at 8:53 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 11 Apr 2017, at 13:29, Jonathan Hull <jhull@gbis.com <mailto:jhull@gbis.com>> wrote:

On Apr 11, 2017, at 3:53 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 11 Apr 2017, at 09:40, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

On Apr 11, 2017, at 1:34 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sent from my iPhone
On 11 Apr 2017, at 01:37, Ricardo Parada via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I have not voted in favor or against the proposal. I have been reading a lot of responses but I agree with Tony.

When I started reading the proposal everything was more or less fine half way through the proposal because it was reverting private to fileprivate between the type and its extensions within the same file. I said, if you think of the type and its extensions as a unit then it makes sense. I can explain that.

Then it started describing a different behavior among the extensions located in a file separate from the file containing the definition of the type. That just started a whole debate inside my head and I understand the passionate responses on both sides.

But then I imagined myself explaining this to someone new to Swift and it just doesn't seem right. If it becomes convoluted then that's a red flag that it does not belong in Swift.

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

We had to take a stance and Chris seemed to prefer the rule that was proposed. I didn't press because I'm sure he has reasons for preferring it that way. But I have a preference for generalizing visibility to all extensions, even to those in a different file than the type.

I think there is a technical limitation if the visibility goes beyond the compilation unit (unless whole module optimization is turned on).

I’m not suggesting visibility beyond the compilation unit. That would break the hierarchy of visibility layers: accessibility levels have always been contained in one-another and that’s why you can go from private, to fileprivate, to internal, to public, to open (but not the other way round) without the risk of any compilation error. If all scopes of a type were visible to each other (whatever the file), you could not go from private to fileprivate.

I’m talking about extensions of the same type in the same file (but in a separate file from the type) to be able to share private members:

Type.swift

struct A {
}

Other.swift

extension A {
    func foo() {
        bar()
    }
}

extension A {
    private func bar() {
    }
}

If this is not how your proposal already works I missed that aspect earlier and find it extremely perplexing (which is probably why I missed it).

It's mentioned in the Derailed design section:

This proposal does not change the behavior of extensions that are not in the same file as the type - i.e., extensions in a seperate file to the type do not share access between themselves:

But I agree this should be changed if there is no major technical reason against it.

I'm not aware of any technical reason why extensions in the same file should not have access to each other's members.

John.

It leaves scoped access working as in Swift 3 in exactly the case where it is least useful. We cannot place stored properties in any extensions, let alone extensions in a file other than the one containing the original declaration.

_______________________________________________
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 don't want to make any change until Chris has been able to chime in. If he agrees with us, what should be done?

The rationale here is to propose the minimal thing that improves the (bad) access control situation we have today, while leaving open this direction for future discussion.

I’m trying to factor potentially large N*M controversy into N+M controversy.

-Chris

···

On Apr 11, 2017, at 10:45 AM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

• Immediate change in the proposal?
• Would it have to go through a new review?
• Or can the Core Team make the change if it is accepted?

On 11 Apr 2017, at 19:01, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

On Apr 11, 2017, at 12:00 PM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 11 Apr 2017, at 16:27, Matthew Johnson <matthew@anandabits.com <mailto:matthew@anandabits.com>> wrote:

Sent from my iPad

On Apr 11, 2017, at 8:53 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 11 Apr 2017, at 13:29, Jonathan Hull <jhull@gbis.com <mailto:jhull@gbis.com>> wrote:

On Apr 11, 2017, at 3:53 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On 11 Apr 2017, at 09:40, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:

On Apr 11, 2017, at 1:34 AM, David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Sent from my iPhone
On 11 Apr 2017, at 01:37, Ricardo Parada via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I have not voted in favor or against the proposal. I have been reading a lot of responses but I agree with Tony.

When I started reading the proposal everything was more or less fine half way through the proposal because it was reverting private to fileprivate between the type and its extensions within the same file. I said, if you think of the type and its extensions as a unit then it makes sense. I can explain that.

Then it started describing a different behavior among the extensions located in a file separate from the file containing the definition of the type. That just started a whole debate inside my head and I understand the passionate responses on both sides.

But then I imagined myself explaining this to someone new to Swift and it just doesn't seem right. If it becomes convoluted then that's a red flag that it does not belong in Swift.

I understand what you are saying and I wouldn't be against relaxing that requirement (not talking for Chris here).

The model would change from "Types share scopes with their extensions in the same file the type was defined" to "Types and their extensions share the same scope in each file".

Oh, I had missed that somehow. I agree that that is a very strange rule. Do you know why it was proposed that way?

We had to take a stance and Chris seemed to prefer the rule that was proposed. I didn't press because I'm sure he has reasons for preferring it that way. But I have a preference for generalizing visibility to all extensions, even to those in a different file than the type.

I think there is a technical limitation if the visibility goes beyond the compilation unit (unless whole module optimization is turned on).

I’m not suggesting visibility beyond the compilation unit. That would break the hierarchy of visibility layers: accessibility levels have always been contained in one-another and that’s why you can go from private, to fileprivate, to internal, to public, to open (but not the other way round) without the risk of any compilation error. If all scopes of a type were visible to each other (whatever the file), you could not go from private to fileprivate.

I’m talking about extensions of the same type in the same file (but in a separate file from the type) to be able to share private members:

Type.swift

struct A {
}

Other.swift

extension A {
    func foo() {
        bar()
    }
}

extension A {
    private func bar() {
    }
}

If this is not how your proposal already works I missed that aspect earlier and find it extremely perplexing (which is probably why I missed it).

It's mentioned in the Derailed design section:

This proposal does not change the behavior of extensions that are not in the same file as the type - i.e., extensions in a seperate file to the type do not share access between themselves:

But I agree this should be changed if there is no major technical reason against it.

I'm not aware of any technical reason why extensions in the same file should not have access to each other's members.

John.

It leaves scoped access working as in Swift 3 in exactly the case where it is least useful. We cannot place stored properties in any extensions, let alone extensions in a file other than the one containing the original declaration.

_______________________________________________
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

Just FYI, I revised the proposal. It was an oversight/misunderstanding that the proposal indicated the previous approach:

-Chris

···

On Apr 12, 2017, at 6:09 AM, Ricardo Parada <rparada@mac.com> wrote:

On Apr 12, 2017, at 1:42 AM, Chris Lattner via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Apr 11, 2017, at 10:30 PM, David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:

To me, the reason for limiting it to a file is about predictability, the ability to locally reason about a type, and the need to define some boundary (for symbol visibility reasons). Saying that extensions to a type have access to private members if they are in the same module is just as arbitrary as limiting it to a single file, and a whole lot less useful from the “reasoning about a type” perspective.

I think you misunderstand. We were talking about two extensions of a type, in a different file from the type, to share private members between themselves.

Doug Gregor mentioned it during the PR process and we added an example to disallow it, but in hindsight, I think it should be allowed.

Ah, you’re saying:

a.swift:
struct X {}

b.swift:
extension X {
  private func f() {}
}

extension X {
  func g() { f() }
}

If so, then yes, I agree we should accept that.

-Chris

That would remove the objection I had. It would make the first half and the second half of the proposal consistent.