SE-0025: Scoped Access Level, next steps

I’ve seen a number of concerns on this list about moduleprivate, and how it penalizes folks who want to explicitly write their access control. I’ve come to think that there is yes-another possible path forward here (which I haven’t seen mentioned so far):

public
internal
fileprivate
private

The advantages, as I see them are:
1) We keep public and private meaning the “right” and “obvious” things.
2) The declmodifiers “read” correctly.
3) Compared to Swift 2, there is almost no change. The only thing that changes is that some uses of Swift 2 “private” will be migrated to “fileprivate”, which makes the intent of the code much more clear.
4) fileprivate is the unusual and not-really-precedented-in-other-languages modifier, and it would still be “googable”.
5) The addresses the “excessively long” declmodifier problem that several people are concerned with.
6) Support for named submodules could be “dropped in” by parameterizing “internal”.

Thoughts?

+1

Following on from my experience with Delphi adding "strict private" for "OO private" members of classes, I would totally agree with your proposition.

Having to use Delphi's "strict private" never really felt right to those of us who were brought up on the OO concept of private, and having "private" mean file scope simply encouraged very bad, large, files with lots of classes; especially for those who were new to programming.

This proposal means that folks coming from other OO languages will instantly understand "private"; "fileprivate" does what it says on the tin.

To my mind, the only extra scope that might be useful is the OO concept of "protected" on a class, but I would like to see a discussion purely centred on the effect of more protocols and less class inheritance, with its attendant impact on whether protected could also suit extending (otherwise private) scope to extensions.

In recent experiments of adapting the GOF Design Patterns to Swift, I have found using protocols and extensions to greatly reduce the need for class inheritance, if not removing the need for classes at all in favour of structs.

Joanna

···

--
Joanna Carter
Carter Consulting

Hi Everyone,

Thank you for all of the input. I know that this was a highly contentious topic, that it is impossible to make everyone happy. Getting the different inputs and perspectives has been very very useful.

The core team met to discuss this, and settled on the list above: public/internal/fileprivate/private. This preserves the benefit of the “fileprivate” concept that we have today in Swift, while aligning the “private” keyword with common expectations of people coming to Swift. This also makes “private" the "safe default” for cases where you don’t think about which one you want to use, and this schema will cause minimal churn for existing Swift code.

Thank you again for all of the input and discussion!

-Chris

btw, to be clear, this is *not* an April 1 joke.

···

On Mar 30, 2016, at 9:22 PM, Chris Lattner <clattner@apple.com> wrote:

I’ve seen a number of concerns on this list about moduleprivate, and how it penalizes folks who want to explicitly write their access control. I’ve come to think that there is yes-another possible path forward here (which I haven’t seen mentioned so far):

public
internal
fileprivate
private

IMHO, “file” is a reasonable variable name. Although if you’re talking about ‘private(file)’ rather than just ‘file’, that might not be a problem.

- Dave Sweeris

···

On Mar 14, 2016, at 9:42 PM, Sean Heber via swift-evolution <swift-evolution@swift.org> wrote:

Although really, why not just use “file” instead of “internal” since it won’t burn any keywords or cause any other conflicts as far as I know.

l8r
Sean

Another +1 for James' idea to use private(module), private(file), private:
- It avoids ambiguity whether internal/private/local is more restrictive
and replaces it with a single axis, public vs. private.
- The two longer terms, private(module) and private(file), are the least
used ones.
- As mentioned by Joe, it admits clean extension to groupings between file
and modules in the future (e.g. submodules).

The only question is (as Sean mentioned) how this combines with the syntax
for setter access level, e.g. the current private(set). Options:
- Unnamed 2nd argument, giving private(file), private(file, set),
private(set).
- Named 2nd argument, giving e.g. private(file), private(file, accessor:
set), private(accessor: set). Less ambiguity but longer.
- Not using multiple arguments, but that'd probably break consistency with
the other unification efforts going on to make everything look like
function calls.

···

On Tue, Mar 15, 2016 at 1:42 PM, Sean Heber via swift-evolution < swift-evolution@swift.org> wrote:

Although really, why not just use “file” instead of “internal” since it
won’t burn any keywords or cause any other conflicts as far as I know.

l8r
Sean

> On Mar 14, 2016, at 9:38 PM, Sean Heber <sean@fifthace.com> wrote:
>
> I, too, prefer it to be more like this:
>
> public // unchanged
> module // currently internal
> internal // currently private
> private // new hotness
>
> l8r
> Sean
>
>
>> On Mar 14, 2016, at 7:50 PM, Jo Albright via swift-evolution < > swift-evolution@swift.org> wrote:
>>
>> +1
>>
>> I like this a lot. Name ideas : enclosed, filelocal, fileonly,
filelock, fileaccess, fileprivate, insidefile, inner. I also like Erica’s
filebound & file fixed.
>>
>> By Erica’s suggestion about switching…
>>
>> - public
>> - modular, modulelock, packaged (module only)
>> - internal (file only)
>> - private
>>
>> Designer . Developer .  Nerd
>> Jo Albright
>>
>>
>>> On Mar 14, 2016, at 8:18 PM, Chris Lattner via swift-evolution < > swift-evolution@swift.org> wrote:
>>>
>>> Per Doug’s email, the core team agrees we should make a change here,
but would like some bikeshedding to happen on the replacement name for
private.
>>>
>>> To summarize the place we’d like to end up:
>>>
>>> - “public” -> symbol visible outside the current module.
>>> - “internal” -> symbol visible within the current module.
>>> - unknown -> symbol visible within the current file.
>>> - “private” -> symbol visible within the current declaration (class,
extension, etc).
>>>
>>> The rationale here is that this aligns Swift with common art seen in
other languages, and that many people using private today don’t *want*
visibility out of their current declaration. It also encourages “extension
oriented programming”, at least it will when some of the other restrictions
on extensions are lifted. We discussed dropping the third one entirely,
but think it *is* a useful and important level of access control, and
when/if we ever get the ability to write unit tests inside of the file that
defines the functionality, they will be a nicer solution to @testable.
>>>
>>> The thing we need to know is what the spelling should be for the third
one. Off hand, perhaps:
>>>
>>> fileprivate
>>> private(file)
>>> internal(file)
>>> fileaccessible
>>> etc
>>>
>>> Some other thoughts on the choice:
>>> - this will be a declaration modifier, so it will not “burn” a keyword.
>>> - if will be a uniquely Swift thing, so there is virtue in it being a
googlable keyword.
>>>
>>> Thoughts appreciated.
>>>
>>> -Chris
>>>
>>> _______________________________________________
>>> 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

Generally I’m in favor of dropping “internal” as being somewhat vague, and moving forward with module and fileprivate.

public
module
fileprivate (also google friendly)
private

···

On Mar 15, 2016, at 5:32 PM, Charles Kissinger via swift-evolution <swift-evolution@swift.org> wrote:

On Mar 14, 2016, at 7:38 PM, Sean Heber via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I, too, prefer it to be more like this:

public // unchanged
module // currently internal
internal // currently private
private // new hotness

I like these best out of what’s been suggested so far. I agree with those that think the parameterized versions are too long and unnecessary.

—CK

l8r
Sean

On Mar 14, 2016, at 7:50 PM, Jo Albright via swift-evolution <swift-evolution@swift.org> wrote:

+1

I like this a lot. Name ideas : enclosed, filelocal, fileonly, filelock, fileaccess, fileprivate, insidefile, inner. I also like Erica’s filebound & file fixed.

By Erica’s suggestion about switching…

- public
- modular, modulelock, packaged (module only)
- internal (file only)
- private

Designer . Developer .  Nerd
Jo Albright

On Mar 14, 2016, at 8:18 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

Per Doug’s email, the core team agrees we should make a change here, but would like some bikeshedding to happen on the replacement name for private.

To summarize the place we’d like to end up:

- “public” -> symbol visible outside the current module.
- “internal” -> symbol visible within the current module.
- unknown -> symbol visible within the current file.
- “private” -> symbol visible within the current declaration (class, extension, etc).

The rationale here is that this aligns Swift with common art seen in other languages, and that many people using private today don’t *want* visibility out of their current declaration. It also encourages “extension oriented programming”, at least it will when some of the other restrictions on extensions are lifted. We discussed dropping the third one entirely, but think it *is* a useful and important level of access control, and when/if we ever get the ability to write unit tests inside of the file that defines the functionality, they will be a nicer solution to @testable.

The thing we need to know is what the spelling should be for the third one. Off hand, perhaps:

fileprivate
private(file)
internal(file)
fileaccessible
etc

Some other thoughts on the choice:
- this will be a declaration modifier, so it will not “burn” a keyword.
- if will be a uniquely Swift thing, so there is virtue in it being a googlable keyword.

Thoughts appreciated.

-Chris

_______________________________________________
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 <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

David James

See my email earlier in this thread about how to potentially deal with this
leveraging fairly normal syntax we already have to support in swift.

···

On Tue, Mar 15, 2016 at 1:34 PM Erica Sadun via swift-evolution < swift-evolution@swift.org> wrote:

Oddball cases:

Global visibility, private settable public private(set) var foo: String
Global visibility, module settable public private(module set) var foo:
String
Module visibility, file settable private(module, file set) var foo: String

of course if module visibility is the default, that might be instead:

Module visibility, file settable private(file set) var foo: String

-- E

On Mar 15, 2016, at 2:14 PM, David Waite via swift-evolution < > swift-evolution@swift.org> wrote:

I like the idea of public and then varying degrees of private (with the
default being the most private). Public values are published outside of the
build target.

However, I have a question how we would express the concept of mixed
property access levels, for instance with a private (to the scope) setter
and private (to the module) getter.

-DW

On Mar 14, 2016, at 6:49 PM, James Berry via swift-evolution < > swift-evolution@swift.org> wrote:

private symbol visible within the current declaration (class, extension,
etc).
private(module) symbol visible within the current module.
private(file) symbol visible within the current file.

James
_______________________________________________
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, too, prefer it to be more like this:
>
> public // unchanged
> module // currently internal
> internal // currently private
> private // new hotness

I like these best out of what’s been suggested so far. I agree with those
that think the parameterized versions are too long and unnecessary.

+1 to this as well. "file" is fine instead of "internal" as well. I don't
like the parameterized versions private(file) and private(module) because
they can get very verbose (I find I use file access all the time), and
because of the already-mentioned concerns about stacking with the
private(set) convention.

···

On Tue, Mar 15, 2016 at 10:32 AM, Charles Kissinger via swift-evolution < swift-evolution@swift.org> wrote:

> On Mar 14, 2016, at 7:38 PM, Sean Heber via swift-evolution < > swift-evolution@swift.org> wrote:

>
> l8r
> Sean
>
>
>> On Mar 14, 2016, at 7:50 PM, Jo Albright via swift-evolution < > swift-evolution@swift.org> wrote:
>>
>> +1
>>
>> I like this a lot. Name ideas : enclosed, filelocal, fileonly,
filelock, fileaccess, fileprivate, insidefile, inner. I also like Erica’s
filebound & file fixed.
>>
>> By Erica’s suggestion about switching…
>>
>> - public
>> - modular, modulelock, packaged (module only)
>> - internal (file only)
>> - private
>>
>> Designer . Developer .  Nerd
>> Jo Albright
>>
>>
>>> On Mar 14, 2016, at 8:18 PM, Chris Lattner via swift-evolution < > swift-evolution@swift.org> wrote:
>>>
>>> Per Doug’s email, the core team agrees we should make a change here,
but would like some bikeshedding to happen on the replacement name for
private.
>>>
>>> To summarize the place we’d like to end up:
>>>
>>> - “public” -> symbol visible outside the current module.
>>> - “internal” -> symbol visible within the current module.
>>> - unknown -> symbol visible within the current file.
>>> - “private” -> symbol visible within the current declaration (class,
extension, etc).
>>>
>>> The rationale here is that this aligns Swift with common art seen in
other languages, and that many people using private today don’t *want*
visibility out of their current declaration. It also encourages “extension
oriented programming”, at least it will when some of the other restrictions
on extensions are lifted. We discussed dropping the third one entirely,
but think it *is* a useful and important level of access control, and
when/if we ever get the ability to write unit tests inside of the file that
defines the functionality, they will be a nicer solution to @testable.
>>>
>>> The thing we need to know is what the spelling should be for the third
one. Off hand, perhaps:
>>>
>>> fileprivate
>>> private(file)
>>> internal(file)
>>> fileaccessible
>>> etc
>>>
>>> Some other thoughts on the choice:
>>> - this will be a declaration modifier, so it will not “burn” a keyword.
>>> - if will be a uniquely Swift thing, so there is virtue in it being a
googlable keyword.
>>>
>>> Thoughts appreciated.
>>>
>>> -Chris
>>>
>>> _______________________________________________
>>> 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

The discussion was about the other direction: whether a nested class should have access to private members of the outer class.

In that case the answer seems clear as well. Everywhere in Swift's access model nested scopes have visibility to all members visible in the containing scope. For example, all scopes in a file can see any "fileprivate" members contained in that file.

Following this semantic, all nested types would be able to see members of their containing type, even those with the new "private" visibility because the nested types are within the same scope where those members are declared.

Semantic consistency is the most important concern IMO. All current access modifiers are strictly based on nested scopes. Hiding members of a containing type from a nested type would break this model and introduce type-driven semantics, which I think (and hope) is beyond the scope of this proposal (pun mildly intended).

Matthew

···

Sent from my iPad

On Mar 24, 2016, at 8:40 AM, Ilya Belenkiy <ilya.belenkiy@gmail.com> wrote:

On Thu, Mar 24, 2016 at 9:35 AM Matthew Johnson <matthew@anandabits.com> wrote:

Sent from my iPad

On Mar 24, 2016, at 5:07 AM, Ilya Belenkiy via swift-evolution <swift-evolution@swift.org> wrote:

It's very consistent with other keywords. I wish compound keywords were joined with a dash or something that made them easier to read, but I guess it's too late now. If we have associatedtype, it makes sense to use moduleprivate (I saw that the name associatedtype was discussed extensively but didn't participate in the discussion; I am sure that it was given a lot of thought). If we could change this, I'd suggest keyword names with dashes everywhere, but if not, these names work well and is a great compromise for everything I've seen in this thread.

I am not worried about the length because the 2 most frequently written keywords would be public and private. Moduleprivate is the default, and file private will not be used as often as private.

One question: should the proposal be explicit about access control for nested classes? We discussed it here briefly (I wanted private to be completely private to the class or extension itself while 2 other people wanted a nested class to have access to the outer class.)

I don't think it would make sense at all to allow an outer type to see private members of a nested class. That would break the semantics of private meaning "containing scope".

However, with Chris's suggestion of using identifiers as parameters, maybe we could eventually have something like private(OuterTypeName) to specify the precise level of access desired.

On Thu, Mar 24, 2016 at 1:13 AM Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:
<responding to several posts in this thread at once>

On Mar 14, 2016, at 5:18 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:
> Per Doug’s email, the core team agrees we should make a change here, but would like some bikeshedding to happen on the replacement name for private.

What we do with private setters is orthogonal from this proposal, so I’m going to ignore it in this thread. After SE-0025 is resolved, it would be great to have another thread/proposal that discusses reskinning private(set) - presumably as just a modifier on the setter.

Similarly, this proposal has nothing to do with “protected” or any other type based access control, so I don’t delve into that at all either.

I’ve seen several proposals that seem promising:

On Mar 14, 2016, at 5:49 PM, James Berry <jberry@rogueorbit.com> wrote:
> I like fileprivate, if that’s the only change. On the other hand, if we want to consider a broader change, what about:
>
> private symbol visible within the current declaration (class, extension, etc).
> private(module) symbol visible within the current module.
> private(file) symbol visible within the current file.

I love how this establishes a family with different levels of access control, and unites them under the idea of "levels of being private”. I also like how people would commonly only ever write public and private (because “private(module)” is the default, and "private(file)" is obscure). However, parenthesized modifiers that take a keyword (as opposed to an identifier) are a bit weird and awkward, so it would be nice to avoid them if possible.

On Mar 15, 2016, at 3:39 AM, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:
> public
> private-module
> private-file
> private

This follows the same sort of structure as James’ proposal, without the parens. It has the same advantages, but trades them with hyphenated decl modifiers. We don’t do that, but it is a good direction.

How about we continue this trend, and follow other existing Swift keywords that merge two lowercase words (associatedtype, typealias, etc), and use:

        public
        moduleprivate
        fileprivate
        private

The advantages, as I see them are:
1) We keep public and private meaning the “right” and “obvious” things.
2) The declmodifiers “read” correctly.
3) The unusual ones (moduleprivate and fileprivate) don’t use the awkward parenthesized keyword approach.
4) The unusual ones would be “googable”.
5) Support for named submodules could be “dropped in” by putting the submodule name/path in parens: private(foo.bar.baz) or moduleprivate(foo.bar). Putting an identifier in the parens is much more natural than putting keywords in parens.

What do you all think?

-Chris

_______________________________________________
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

In real life only public and private make sense. So it may be just private and everything else is public by default. Public may stay for compatibility :) And saying that I think there is no need to change anything as the current model is good enough.
What ever you do - don,t break existing code. Swift is not beta anymore...No one can invest in big projects if the syntax is unstable!

···

On Thursday, March 24, 2016 2:17 PM, Goffredo Marocchi via swift-evolution <swift-evolution@swift.org> wrote:

I think that supercalifragilisticexpialidocious may benefit from lowerCamelCasing ;).

[[iOS messageWithContent:webContent] broadcast]
On 24 Mar 2016, at 11:02, Dany St-Amant via swift-evolution <swift-evolution@swift.org> wrote:

Le 24 mars 2016 à 01:13, Chris Lattner via swift-evolution <swift-evolution@swift.org> a écrit :

<responding to several posts in this thread at once>

[..snip..]

How about we continue this trend, and follow other existing Swift keywords that merge two lowercase words (associatedtype, typealias, etc), and use:

public

moduleprivate

fileprivate

private

The advantages, as I see them are:

1) We keep public and private meaning the “right” and “obvious” things.

2) The declmodifiers “read” correctly.

3) The unusual ones (moduleprivate and fileprivate) don’t use the awkward parenthesized keyword approach.

4) The unusual ones would be “googable”.

5) Support for named submodules could be “dropped in” by putting the submodule name/path in parens: private(foo.bar.baz) or moduleprivate(foo.bar). Putting an identifier in the parens is much more natural than putting keywords in parens.

What do you all think?

The think I fear with moduleprivate and fileprivate, is that someone will one day suggest to lowerCamelCase them. The parenthesized version was de-facto preventing my fear from ever being reality.
Obviously, I am on the "all keywords should be all lowercases" team.

Dany
_______________________________________________
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 am not sure if consistency is a problem here. My primary concern is that
as long as the class or extension code itself hasn't changed, it's private
API stays hidden from anything else. If we can simply inject a class into a
class or extension and get access to all of its internals, that reduces the
protection level that private would provide. I'd like private to hide
implementation details completely.

That said, I am not sure if we need to discuss it as part of this proposal.

···

On Thu, Mar 24, 2016 at 10:28 AM Matthew Johnson <matthew@anandabits.com> wrote:

Sent from my iPad

On Mar 24, 2016, at 8:40 AM, Ilya Belenkiy <ilya.belenkiy@gmail.com> > wrote:

The discussion was about the other direction: whether a nested class
should have access to private members of the outer class.

In that case the answer seems clear as well. Everywhere in Swift's access
model nested scopes have visibility to all members visible in the
containing scope. For example, all scopes in a file can see any
"fileprivate" members contained in that file.

Following this semantic, all nested types would be able to see members of
their containing type, even those with the new "private" visibility because
the nested types are within the same scope where those members are
declared.

Semantic consistency is the most important concern IMO. All current
access modifiers are strictly based on nested scopes. Hiding members of a
containing type from a nested type would break this model and introduce
type-driven semantics, which I think (and hope) is beyond the scope of this
proposal (pun mildly intended).

Matthew

On Thu, Mar 24, 2016 at 9:35 AM Matthew Johnson <matthew@anandabits.com> > wrote:

Sent from my iPad

On Mar 24, 2016, at 5:07 AM, Ilya Belenkiy via swift-evolution < >> swift-evolution@swift.org> wrote:

It's very consistent with other keywords. I wish compound keywords were
joined with a dash or something that made them easier to read, but I guess
it's too late now. If we have associatedtype, it makes sense to use
moduleprivate (I saw that the name associatedtype was discussed extensively
but didn't participate in the discussion; I am sure that it was given a lot
of thought). If we could change this, I'd suggest keyword names with dashes
everywhere, but if not, these names work well and is a great compromise for
everything I've seen in this thread.

I am not worried about the length because the 2 most frequently written
keywords would be public and private. Moduleprivate is the default, and
file private will not be used as often as private.

One question: should the proposal be explicit about access control for
nested classes? We discussed it here briefly (I wanted private to be
completely private to the class or extension itself while 2 other people
wanted a nested class to have access to the outer class.)

I don't think it would make sense at all to allow an outer type to see
private members of a nested class. That would break the semantics of
private meaning "containing scope".

However, with Chris's suggestion of using identifiers as parameters,
maybe we could eventually have something like private(OuterTypeName) to
specify the precise level of access desired.

On Thu, Mar 24, 2016 at 1:13 AM Chris Lattner via swift-evolution < >> swift-evolution@swift.org> wrote:

<responding to several posts in this thread at once>

On Mar 14, 2016, at 5:18 PM, Chris Lattner via swift-evolution < >>> swift-evolution@swift.org> wrote:
> Per Doug’s email, the core team agrees we should make a change here,
but would like some bikeshedding to happen on the replacement name for
private.

What we do with private setters is orthogonal from this proposal, so I’m
going to ignore it in this thread. After SE-0025 is resolved, it would be
great to have another thread/proposal that discusses reskinning
private(set) - presumably as just a modifier on the setter.

Similarly, this proposal has nothing to do with “protected” or any other
type based access control, so I don’t delve into that at all either.

I’ve seen several proposals that seem promising:

On Mar 14, 2016, at 5:49 PM, James Berry <jberry@rogueorbit.com> wrote:
> I like fileprivate, if that’s the only change. On the other hand, if
we want to consider a broader change, what about:
>
> private symbol visible within the current
declaration (class, extension, etc).
> private(module) symbol visible within the current module.
> private(file) symbol visible within the current file.

I love how this establishes a family with different levels of access
control, and unites them under the idea of "levels of being private”. I
also like how people would commonly only ever write public and private
(because “private(module)” is the default, and "private(file)" is
obscure). However, parenthesized modifiers that take a keyword (as opposed
to an identifier) are a bit weird and awkward, so it would be nice to avoid
them if possible.

On Mar 15, 2016, at 3:39 AM, Thorsten Seitz via swift-evolution < >>> swift-evolution@swift.org> wrote:
> public
> private-module
> private-file
> private

This follows the same sort of structure as James’ proposal, without the
parens. It has the same advantages, but trades them with hyphenated decl
modifiers. We don’t do that, but it is a good direction.

How about we continue this trend, and follow other existing Swift
keywords that merge two lowercase words (associatedtype, typealias, etc),
and use:

        public
        moduleprivate
        fileprivate
        private

The advantages, as I see them are:
1) We keep public and private meaning the “right” and “obvious” things.
2) The declmodifiers “read” correctly.
3) The unusual ones (moduleprivate and fileprivate) don’t use the
awkward parenthesized keyword approach.
4) The unusual ones would be “googable”.
5) Support for named submodules could be “dropped in” by putting the
submodule name/path in parens: private(foo.bar.baz) or
moduleprivate(foo.bar). Putting an identifier in the parens is much more
natural than putting keywords in parens.

What do you all think?

-Chris

_______________________________________________
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 is why I'd like private to mean exactly that (no nested class should
get access). Then the meaning is clear: it's as private as it can be :-)

Private and public have well defined meaning. We

···

On Thu, Mar 24, 2016 at 11:33 AM Ross O'Brien via swift-evolution < swift-evolution@swift.org> wrote:

I agree that 'private' still feels too subjective on its own. It's
intuitively 'not public'; it's not intuitively the access term for
'declaration only'.

I'm not opposed to fileprivate and moduleprivate, if we like those terms.
I'd just prefer a corresponding scopeprivate or declarationprivate.

On Thu, Mar 24, 2016 at 3:21 PM, Brandon Knope via swift-evolution < > swift-evolution@swift.org> wrote:

> How about we continue this trend, and follow other existing Swift
keywords that merge two lowercase words (associatedtype, typealias, etc),
and use:
>
> public
> moduleprivate
> fileprivate
> private
>
> The advantages, as I see them are:
> 1) We keep public and private meaning the “right” and “obvious” things.
> 2) The declmodifiers “read” correctly.
> 3) The unusual ones (moduleprivate and fileprivate) don’t use the
awkward parenthesized keyword approach.
> 4) The unusual ones would be “googable”.
> 5) Support for named submodules could be “dropped in” by putting the
submodule name/path in parens: private(foo.bar.baz) or
moduleprivate(foo.bar). Putting an identifier in the parens is much more
natural than putting keywords in parens.
>
> What do you all think?
>
> -Chris
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

I'm not sure my wording will be perfect here, but I will try: I still
believe that private is implied in "module" and "file" and the problem is
in the name of the plain "private" keyword.

You may say private is obvious, but when you have moduleprivate and
fileprivate, the natural question I ask is "What remaining kind of private
is there?" so private's obviousness is muddied for me when next to
moduleprivate and fileprivate.

I will say I would prefer these keywords to the proposed parameter
keywords. I just think:

file -> implies file only
module -> implies module only

where adding private to them only adds noise (I.e. fileprivate and
moduleprivate)

Brandon
_______________________________________________
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

Perhaps internal is valuable here then?
Maybe: public, moduleinternal, fileinternal, private.
Or just: public, internal, fileinternal, private.
Or, more radically: public, internal, internal(#file), private.

···

On Thu, Mar 24, 2016 at 10:32 AM Ross O'Brien via swift-evolution < swift-evolution@swift.org> wrote:

I agree that 'private' still feels too subjective on its own. It's
intuitively 'not public'; it's not intuitively the access term for
'declaration only'.

I'm not opposed to fileprivate and moduleprivate, if we like those terms.
I'd just prefer a corresponding scopeprivate or declarationprivate.

On Thu, Mar 24, 2016 at 3:21 PM, Brandon Knope via swift-evolution < > swift-evolution@swift.org> wrote:

> How about we continue this trend, and follow other existing Swift
keywords that merge two lowercase words (associatedtype, typealias, etc),
and use:
>
> public
> moduleprivate
> fileprivate
> private
>
> The advantages, as I see them are:
> 1) We keep public and private meaning the “right” and “obvious” things.
> 2) The declmodifiers “read” correctly.
> 3) The unusual ones (moduleprivate and fileprivate) don’t use the
awkward parenthesized keyword approach.
> 4) The unusual ones would be “googable”.
> 5) Support for named submodules could be “dropped in” by putting the
submodule name/path in parens: private(foo.bar.baz) or
moduleprivate(foo.bar). Putting an identifier in the parens is much more
natural than putting keywords in parens.
>
> What do you all think?
>
> -Chris
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

I'm not sure my wording will be perfect here, but I will try: I still
believe that private is implied in "module" and "file" and the problem is
in the name of the plain "private" keyword.

You may say private is obvious, but when you have moduleprivate and
fileprivate, the natural question I ask is "What remaining kind of private
is there?" so private's obviousness is muddied for me when next to
moduleprivate and fileprivate.

I will say I would prefer these keywords to the proposed parameter
keywords. I just think:

file -> implies file only
module -> implies module only

where adding private to them only adds noise (I.e. fileprivate and
moduleprivate)

Brandon
_______________________________________________
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 it does. `module` could mean many things related to how Swift creates and consumes modules.
`moduleprivate` combines something about access levels (public/private) and scope (module), is easy to
Google, offers few "wrong" interpretations. By using a longer keyword, it is less flexible in meaning and
more fixed in purpose.

I hesitate to make this thread any longer but since it's already bikeshedding, I felt it was worth adding another few cents.

-- E

···

On Mar 24, 2016, at 4:10 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:
Honestly, though, I'm not sure why people are working so hard to cram `private` in there. Does `moduleprivate` or `private(module)` really convey more information than `module`? Particularly once you've looked it up and know that it's an access modifier?

This is why I like the idea of declaring private(file), private(module) or private(type), as all are a form of privacy as none are available externally, but the parameter clarifies in what way they are limited internally, though private(type) could be the default if no parameter is given.

···

On 24 Mar 2016, at 15:32, Ross O'Brien via swift-evolution <swift-evolution@swift.org> wrote:

I agree that 'private' still feels too subjective on its own. It's intuitively 'not public'; it's not intuitively the access term for 'declaration only'.

I'm not opposed to fileprivate and moduleprivate, if we like those terms. I'd just prefer a corresponding scopeprivate or declarationprivate.

I'm with you here too. I'm not opposed to it but it strikes me as being hypertechnical and unnecessarily verbose.

It's also not symmetrical: where is modulepublic and filepublic? Those don't make sense? Then module and file stand on their own if private is implied (you know people will wonder when they see moduleprivate if a public one exists)

Brandon

···

On Mar 24, 2016, at 6:10 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

Honestly, though, I'm not sure why people are working so hard to cram `private` in there. Does `moduleprivate` or `private(module)` really convey more information than `module`? Particularly once you've looked it up and know that it's an access modifier?

--
Brent Royal-Gordon
Architechies

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

That's for the explanation. I think this last part gets at the heart of my
question: Why isn't it important to highlight word boundaries in this case?

Swift is an “opinionated” language and we find snake case to be ugly (YMMV
of course).

My attempt to summarize/rephrase the overall answer: "We used up all the
word-boundary-highlighting conventions that we don't find ugly on other
parts of the language, and we don't want to reuse any of them due to the
potential for conflict and confusion."

As for snake case being ugly, my mileage does vary (obviously). Ithink
thereadability costofnot highlightingwordboundaries outweighsthe
aestheticconcerns. But them's the breaks when it comes to aesthetic issues,
I suppose. And in the grand scheme of things, at least the total number of
declaration modifiers should be small… :)

-John

···

On Fri, Mar 25, 2016 at 1:24 AM, Chris Lattner <clattner@apple.com> wrote:

public
internal
interfile
private

still googleable and very clear its scope and meaning, nice latin root. Doesn’t overload “private”, slightly shorter.

···

On Mar 30, 2016, at 9:46 PM, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:

Looks good to me.

-Thorsten

Am 31.03.2016 um 06:22 schrieb Chris Lattner via swift-evolution <swift-evolution@swift.org>:

On Mar 23, 2016, at 10:13 PM, Chris Lattner <clattner@apple.com> wrote:
How about we continue this trend, and follow other existing Swift keywords that merge two lowercase words (associatedtype, typealias, etc), and use:

  public
  moduleprivate
  fileprivate
  private

The advantages, as I see them are:
1) We keep public and private meaning the “right” and “obvious” things.
2) The declmodifiers “read” correctly.
3) The unusual ones (moduleprivate and fileprivate) don’t use the awkward parenthesized keyword approach.
4) The unusual ones would be “googable”.
5) Support for named submodules could be “dropped in” by putting the submodule name/path in parens: private(foo.bar.baz) or moduleprivate(foo.bar). Putting an identifier in the parens is much more natural than putting keywords in parens.

I’ve seen a number of concerns on this list about moduleprivate, and how it penalizes folks who want to explicitly write their access control. I’ve come to think that there is yes-another possible path forward here (which I haven’t seen mentioned so far):

public
internal
fileprivate
private

The advantages, as I see them are:
1) We keep public and private meaning the “right” and “obvious” things.
2) The declmodifiers “read” correctly.
3) Compared to Swift 2, there is almost no change. The only thing that changes is that some uses of Swift 2 “private” will be migrated to “fileprivate”, which makes the intent of the code much more clear.
4) fileprivate is the unusual and not-really-precedented-in-other-languages modifier, and it would still be “googable”.
5) The addresses the “excessively long” declmodifier problem that several people are concerned with.
6) Support for named submodules could be “dropped in” by parameterizing “internal”.

Thoughts?

-Chris
_______________________________________________
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

One bonus it is a real word so autocorrect doesn’t fix it! I checked the dictionary and there are no negative or misleading meaning.

It is a verb though, this is not being used as a verb in this case.

···

On Mar 30, 2016, at 10:04 PM, Paul Ossenbruggen <possen@gmail.com> wrote:

public
internal
interfile
private

still googleable and very clear its scope and meaning, nice latin root. Doesn’t overload “private”, slightly shorter.

On Mar 30, 2016, at 9:46 PM, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:

Looks good to me.

-Thorsten

Am 31.03.2016 um 06:22 schrieb Chris Lattner via swift-evolution <swift-evolution@swift.org>:

On Mar 23, 2016, at 10:13 PM, Chris Lattner <clattner@apple.com> wrote:
How about we continue this trend, and follow other existing Swift keywords that merge two lowercase words (associatedtype, typealias, etc), and use:

public
moduleprivate
fileprivate
private

The advantages, as I see them are:
1) We keep public and private meaning the “right” and “obvious” things.
2) The declmodifiers “read” correctly.
3) The unusual ones (moduleprivate and fileprivate) don’t use the awkward parenthesized keyword approach.
4) The unusual ones would be “googable”.
5) Support for named submodules could be “dropped in” by putting the submodule name/path in parens: private(foo.bar.baz) or moduleprivate(foo.bar). Putting an identifier in the parens is much more natural than putting keywords in parens.

I’ve seen a number of concerns on this list about moduleprivate, and how it penalizes folks who want to explicitly write their access control. I’ve come to think that there is yes-another possible path forward here (which I haven’t seen mentioned so far):

public
internal
fileprivate
private

The advantages, as I see them are:
1) We keep public and private meaning the “right” and “obvious” things.
2) The declmodifiers “read” correctly.
3) Compared to Swift 2, there is almost no change. The only thing that changes is that some uses of Swift 2 “private” will be migrated to “fileprivate”, which makes the intent of the code much more clear.
4) fileprivate is the unusual and not-really-precedented-in-other-languages modifier, and it would still be “googable”.
5) The addresses the “excessively long” declmodifier problem that several people are concerned with.
6) Support for named submodules could be “dropped in” by parameterizing “internal”.

Thoughts?

-Chris
_______________________________________________
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

If not interfile I can suggest infile again too.

···

On Mar 31, 2016, at 12:38 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

I’ve seen a number of concerns on this list about moduleprivate, and how it penalizes folks who want to explicitly write their access control. I’ve come to think that there is yes-another possible path forward here (which I haven’t seen mentioned so far):

public
internal
fileprivate
private

I don't like how this ends up penalizing `fileprivate` with an ugly compound keyword. I feel like, with the way I tend to factor my code, I would continue using it reasonably often, and it would suck to have to use an ugly keyword.

Consider some of the places where we're still going to need `fileprivate`:

* Members used by operators or other free functions.
* Members of nested types meant to be used only by the containing type.
* Code which splits a type up into extensions. (We want to encourage this.)
* Code which pairs a type with an extension adding an API using that type to another type. (We want to encourage this too.)

These are all things we want to encourage, and things where just making them `internal` is going to be tempting. Access control is a delicate thing; using tight access control imposes obvious short-term costs for subtle long-term gains, and so you're always tempted to cheat by making things broader than they should be for your own convenience. The only thing keeping you from cheating is your own discipline.

I worry that, if `fileprivate` is a long, ugly, obscure, and cumbersome keyword, and `internal` works just as well but requires no typing at all, a lot of people are going to do the wrong thing. We don't want that to happen.

--
Brent Royal-Gordon
Architechies

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

public
internal
interfile
private

Linguistically, I really like this direction. 'interfile' is one word, it
reads as an adjective, it can be used in conversation (this has interfile
visibility), and it's clear about where its visibility ends.

It just doesn't mean what you think it means.

'inter' means 'between'. See: 'intergalactic', 'interstellar',
'international', 'internet'. So 'interfile' would have to mean 'visible
between files' - i.e. an interfile symbol in one file is visible in another
file. The prefix you're looking for, meaning 'internal', is 'intra' (see:
'intravenous', 'intranet').

So the scale would become:

public / intermodule
internal / intramodule / interfile
intrafile
private

···

On Thu, Mar 31, 2016 at 6:04 AM, Paul Ossenbruggen via swift-evolution < swift-evolution@swift.org> wrote:

public
internal
interfile
private

still googleable and very clear its scope and meaning, nice latin root.
Doesn’t overload “private”, slightly shorter.

> On Mar 30, 2016, at 9:46 PM, Thorsten Seitz via swift-evolution < > swift-evolution@swift.org> wrote:
>
> Looks good to me.
>
> -Thorsten
>
>> Am 31.03.2016 um 06:22 schrieb Chris Lattner via swift-evolution < > swift-evolution@swift.org>:
>>
>>> On Mar 23, 2016, at 10:13 PM, Chris Lattner <clattner@apple.com> > wrote:
>>> How about we continue this trend, and follow other existing Swift
keywords that merge two lowercase words (associatedtype, typealias, etc),
and use:
>>>
>>> public
>>> moduleprivate
>>> fileprivate
>>> private
>>>
>>> The advantages, as I see them are:
>>> 1) We keep public and private meaning the “right” and “obvious” things.
>>> 2) The declmodifiers “read” correctly.
>>> 3) The unusual ones (moduleprivate and fileprivate) don’t use the
awkward parenthesized keyword approach.
>>> 4) The unusual ones would be “googable”.
>>> 5) Support for named submodules could be “dropped in” by putting the
submodule name/path in parens: private(foo.bar.baz) or
moduleprivate(foo.bar). Putting an identifier in the parens is much more
natural than putting keywords in parens.
>>
>> I’ve seen a number of concerns on this list about moduleprivate, and
how it penalizes folks who want to explicitly write their access control.
I’ve come to think that there is yes-another possible path forward here
(which I haven’t seen mentioned so far):
>>
>> public
>> internal
>> fileprivate
>> private
>>
>> The advantages, as I see them are:
>> 1) We keep public and private meaning the “right” and “obvious” things.
>> 2) The declmodifiers “read” correctly.
>> 3) Compared to Swift 2, there is almost no change. The only thing that
changes is that some uses of Swift 2 “private” will be migrated to
“fileprivate”, which makes the intent of the code much more clear.
>> 4) fileprivate is the unusual and
not-really-precedented-in-other-languages modifier, and it would still be
“googable”.
>> 5) The addresses the “excessively long” declmodifier problem that
several people are concerned with.
>> 6) Support for named submodules could be “dropped in” by parameterizing
“internal”.
>>
>> Thoughts?
>>
>> -Chris
>> _______________________________________________
>> 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