SE-0025: Scoped Access Level, next steps

Why is it important to highlight word boundaries in so many other conventions in Swift but not in this one? What would be lost with this alternative?

public
module_private
file_private
private

Is it just the extra (chorded, on US keyboards) keystroke? I think the readability benefits of clear word boundaries far outweigh the keystroke cost (especially with good editor auto-complete).

Swift style, deriving from Objective-C style, seems to disfavor underscores in general, except as a "formally public but informally private" marker at the beginning of an identifier. We're in the process of removing the last underscored language constructs, `@warn_unused_result` and its `mutable_variant` parameter, and replacing them with alternatives without underscores.

So if we wanted to mark a word boundary, we'd probably use camelCase. And to me, camelCase just feels wrong for keywords, particularly ones as common as access modifiers. I think it's because identifiers are camelCase too; you really want keywords to disappear into the background, but in something like this:

  modulePrivate func spinWicket() {

That `modulePrivate` looks like an identifier—maybe a return type or something—rather than a keyword.

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

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

Nothing is impossible, but I consider the odds of typealias and associatedtype becoming lower camel cased to be extremely near zero.

-Chris

···

On Mar 24, 2016, at 4:02 AM, Dany St-Amant via swift-evolution <swift-evolution@swift.org> wrote:

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.

Hi John,

Great question. The core team has discussed this (extensively, on multiple occasions, sigh.. :-). The conclusion is to standardize on a simple and consistent schema of:

1. Keywords & declaration modifiers all lower case, conjoined when multi-word.
2. Attributes and values (which includes methods and enum cases) being lower camel case.
3. Types being upper camel case.

This approach eliminates the “snake" case we had before, but “camel fans" often raise the question of why we don’t apply lower camel case to keywords. There are a couple of reasons for this:

1. Keywords, as part of the language, are extremely carefully considered and scrutinized by a large community of smart folks on swift-evolution. Taking a word (e.g. “in” or “for”) is something that has to be carefully balanced vs the impact on real world code in various domains. It isn’t done lightly.

2. Lower camel case is already used for values. Keyword/value conflicts are a real thing, particularly when it comes to expressive APIs. We have solved this for keyword arguments to methods, but conflicts on property names are still a very real thing.

3. We have a few conjoined keywords already (typealias, associatedtype, fallthrough). In the discussion about these terms, we decided that these read best when all lowercase, because they are treated as atomic concepts by programmers. It is reasonable to expect a Swift programmer to grok (as they incrementally gain mastery of the language) the builtin language keywords. Syntax highlighting and other IDE features also help here.

That said, to be fair, there is more work to be done here in Swift 3, because we still have the legacy dynamicType keyword - it should be renamed to “dynamictype" IMO.

4. Declaration modifiers (like public/private/moduleprivate/etc) don’t have to live by the same rules as keywords necessarily (the grammar of Swift allows us to precisely disambiguate decl-modifiers based on the keyword they hang off of), but Swift programmers think of them as keywords, and so it is most consistent for them to follow the naming scheme of keywords.

5. In contrast, attributes are intentionally “demoted” in prominence for various reasons, and require an @ prefix. We also expect and hope to support user defined attributes at some point. As such, lower-camel-case (when not containing a framework prefix like NS or UI) is the best approach for them.

These are all reasons why we go with conjoined keywords instead of lower-camel-case. If you are really asking why we don’t go with *snake* case, the answer is somewhat simpler: Swift is an “opinionated” language and we find snake case to be ugly (YMMV of course).

-Chris

···

On Mar 24, 2016, at 6:02 AM, John Siracusa 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

Why is it important to highlight word boundaries in so many other conventions in Swift but not in this one? What would be lost with this alternative?

public
module_private
file_private
private

Is it just the extra (chorded, on US keyboards) keystroke? I think the readability benefits of clear word boundaries far outweigh the keystroke cost (especially with good editor auto-complete).

I also think the precedent of nameslikethis is a dangerous one for readability. It's easy to say this is "just for this limited area of the language," but witness how associatedtype is already used to support moduleprivate and friends. Precedents matter, and I think this is not a good one.

Why is it important to highlight word boundaries in so many other conventions in Swift but not in this one? What would be lost with this alternative?

public
module_private
file_private
private

Is it just the extra (chorded, on US keyboards) keystroke? I think the readability benefits of clear word boundaries far outweigh the keystroke cost (especially with good editor auto-complete).

The keywords, unlike identifiers, are always the same. You don't need to parse them every time; ‘on an infinite timescale’, you get used to them and recognize them at a glance. So the value of adding an underscore (or, heaven forbid, camel case style) to a keyword is a lot less than with identifiers.

My personal completely subjective opinion is that the underscored ones look gross and pull too much attention onto themselves, rather than helping to focus on the identifiers. To me, this actually detracts from the overall readability of the entire line.

In other words: nothing says “nothing to see here, move along” quite like abunchofgibberishthrowntogether.

A.

+1 for this. The only reason I was thinking 'external' was because 'module' seems to clash with the identity of the actual module but i am for the order and introducing a new word for module access.

···

On Mar 14, 2016, at 7:38 PM, Sean Heber via swift-evolution <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

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

We already had a very long discussion about all of these topics.

I am not suggesting you change the design. I am suggesting you clarify the description of your existing design so that everyone understands what it means, because confusion is rampant.

I'd like to keep "private" to be completely private and not allow class injection to gain access, but this is an edge case that could be argued either way. I can definitely live with a pure scoped access for consistency and don't want to argue the edge case in a never ending discussion.

So what you're saying is, you are purposefully writing the proposal vaguely so that everyone can assume it says whatever they imagine it says, and thus more people will support the proposal?

This is no way to design a programming language.

···

--
Brent Royal-Gordon
Architechies

this is more in line with other naming conventions, but the names in the
updated proposal seem to match the closest to everything else in Swift. I
waited for about a week to get everyone's opinion, but I think that we are
past the name discussions at this point.

···

On Sun, Mar 27, 2016 at 11:50 PM Matthew Judge via swift-evolution < swift-evolution@swift.org> wrote:

> On Mar 24, 2016, at 01:13, 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.

If we borrow the "drop in" from below of private(foo.bar.baz), then maybe:

private(module) // expands to current module
private(#file) // expands to current file

This is slightly more awkward/one character longer, but now it's an
identifier in parentheses (or something that expands to an identifier).

I'm not sure I like this in practice unless it is fairly rare to actually
have to type. If "private" at the top level of a file meant fileprivate (as
I suggested in my other reply a few minutes ago) that would significantly
reduce the need to type something other than just private.

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

The proposal is not vague. Most questions / misunderstanding is not due to
the proposal itself but due to how these terms are used in other languages.

It does have one unintended conclusion (the potential class injection to
get access). My position on it is not to change it because it's an edge
case that some people want and that makes the design simpler and more
consistent with the terms that it uses (scope).

If my proposal was to disallow adding an inner class to gain access to
outer class, I'd make it explicit. But I am not proposing it, so there
doesn't seem to be a need to include it and cause more confusion (we
already had plenty of emails about the most common use cases). Also, the
core team did not request a clarification on this, so I think it is clear
to anybody who wants to go to that level of detail.

···

On Mon, Mar 28, 2016 at 7:27 AM Brent Royal-Gordon <brent@architechies.com> wrote:

> We already had a very long discussion about all of these topics.

I am not suggesting you change the design. I am suggesting you clarify the
description of your existing design so that everyone understands what it
means, because confusion is rampant.

> I'd like to keep "private" to be completely private and not allow class
injection to gain access, but this is an edge case that could be argued
either way. I can definitely live with a pure scoped access for
consistency and don't want to argue the edge case in a never ending
discussion.

So what you're saying is, you are purposefully writing the proposal
vaguely so that everyone can assume it says whatever they imagine it says,
and thus more people will support the proposal?

This is no way to design a programming language.

--
Brent Royal-Gordon
Architechies

Maybe it's good thing that we just discussed it. After replying to Matthew,
this meaning private feels so wrong that I will update the proposal
to disallow this. Private should mean private.

···

On Mon, Mar 28, 2016 at 7:27 AM Brent Royal-Gordon <brent@architechies.com> wrote:

> We already had a very long discussion about all of these topics.

I am not suggesting you change the design. I am suggesting you clarify the
description of your existing design so that everyone understands what it
means, because confusion is rampant.

> I'd like to keep "private" to be completely private and not allow class
injection to gain access, but this is an edge case that could be argued
either way. I can definitely live with a pure scoped access for
consistency and don't want to argue the edge case in a never ending
discussion.

So what you're saying is, you are purposefully writing the proposal
vaguely so that everyone can assume it says whatever they imagine it says,
and thus more people will support the proposal?

This is no way to design a programming language.

--
Brent Royal-Gordon
Architechies

I really like this. +1 for the following:

public
internal
fileprivate
private

-Jesse

···

On Wed, Mar 30, 2016 at 9:22 PM, Chris Lattner via swift-evolution < swift-evolution@swift.org> wrote:

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

--
Jesse Squires

*blog* | jessesquires.com <http://www.jessesquires.com>
*github* | github.com/jessesquires <http://www.github.com/jessesquires&gt;
*hexedbits* | hexedbits.com <http://www.hexedbits.com>

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

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

I love those. And internal corresponds to the meaning it has in other languages.

+1

···

On 31 Mar 2016, at 06:22, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

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

+1, I like it.

There's one source of confusion though: at file scope, `private` would have the same meaning as `fileprivate`.

// At file scope, these keywords are synonymous unless we specify otherwise:
private let someConstant = "foo"
fileprivate let anotherConstant = "bar"

That can be seen in positive light too—the shorter keyword is tempting—, but wouldn't it make things clearer if `private` was only allowed inside data types?

Then, file-wide constants, helper functions, and types would then all be at least `fileprivate`, and never `private`. I think that would best document their intent. Maybe just a warning with a fixit to use `fileprivate` would be enough.

— Pyry Jahkola

···

On 31 Mar 2016, at 07:22, Chris Lattner 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

Or maybe we could just abolish of file-private. It's not like it'd be 100% gone: private declarations at the root of a file will always be equivalent to file-private. For non-root things that need to be accessible within the file you can use `internal`, which is more accessible than before but still bounded to the current module.

···

Le 31 mars 2016 à 0:22, Chris Lattner via swift-evolution <swift-evolution@swift.org> a écrit :

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

--
Michel Fortin
https://michelf.ca

Yes. I see no need to get rid of “internal”.

Cheers,
Guillaume Lessard

···

On 30 mars 2016, at 22:22, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

public
internal
fileprivate
private

I'd be okay with this, but I do think having a private and fileprivate will confuse people considering they both have private in their names

Brandon

···

Sent from my iPad

On Mar 31, 2016, at 12:22 AM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

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

I have to say, I'm not very happy with the progress of this topic ..
Let me explain:
I'm Swift user from day 1. A few weeks after, even with the limitations of
language, had an application in production.

One of the "cool" features that regularly use in my application is the
"file private" access level. Is very better (in practice) than C++
friendly, and enable a lot of different manners to think in our code design.

For example: I have a "hand shake" file, wen two specific types extension
knows about specift (and private) functions to do this "hand shake".

So, my problem is, after almost two years using Swift, "public", "internal"
and "private" is just "so obvious" and very easy to understand, change the
"old" private to something else is not very good.

I can understand the need to "more private" than current private, but who
need this feature?
* devs which do not want declare this "important" type in a different file.
* devs which want to declare more than one type per file to make some "
*friendly*" relationship, but not share some other specific information.
* devs which want to declare more than one type per file and *not* make any
relationship with these types different than public.

Also, I'm not expert, but the actual swift access control appear to enable
some good compiler optimizations, and works very well with top level
objects.

So my proposal is:

- *public* (do not change)
- *internal* (do not change)
- *private* (do not change)
- *protect* (new)

Why protect?

*First*, I believe that is a good word to identify a property that will be
accessed in a specific scope.
*Second*, it will only be used when the person declaring more than one type
in a single file and does not want to share any specific property. I think
this person opt to share the same file for more than one type, the "scope"
access control will be less used than current private (file based) because
a think there less "super private" properties between between those types
for the rest of the module.
*Third*, although I believe that Swift not need (and will not get) access
control only to subtypes, simply update this "protect" is enough (task for
another proposal). And even if the protect switch to "also" share
properties between subtypes, only those who want to put all subtypes in the
same file will lose.

Is impossible to make everyone happy anyway... And i think is good choose
the path which "extends" the rationale of the Swift access control over
these two years instead say "file based access control is now not so
important".

···

Em qui, 31 de mar de 2016 às 01:22, Chris Lattner via swift-evolution < swift-evolution@swift.org> escreveu:

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

With these names we lose consistency. The current scheme makes it very
clear that each next level is a subset of the previous level. With
"internal", fileprivate looks out of place.

We have several goals for all the names:
1) obvious
2) using standard terms
3) short
4) consistent

This discussion shows that we cannot have all of them. We have to pick
something at the expense of something else.

For me, the order of importance is 2, 4, 1, 3, and I am pretty sure that
with this order

public
moduleprivate
fileprivate
private

is the best so far.

public
internal
fileprivate
private

is not as consistent. It's also not as obvious, given that many people
proposed to use internal to mean fileprivate. The biggest advantages of
these names are that there is less change and short words. If these are the
most important goals, then my original proposal is even better:

public
internal
private
scoped

It's a non-breaking change, everything retains its meaning, the added name
is very clear, and all the names are very short. The biggest problem here
is "private" -- it's not the most private that the language provides, and
most people would expect that.

Here is another one like that (it solves the "private" problem at the
expense of using non-standard terms):

public
internal
local
scoped

My main point is that we cannot have everything. We have to pick the order
of importance.

We heard many times that "short" is not the goal of Swift. Instead, it's
clarity. If this is the case, then I think

public
moduleprivate
fileprivate
private

is the clearest we've seen. Nobody could possibly be confused about the
meaning of these names. I doubt that moduleprivate will be required to
spell out in any style guide, but even so, it's not so bad. We have many
frequently used class names that are much longer.

···

On Thu, Mar 31, 2016 at 12:22 AM Chris Lattner via swift-evolution < swift-evolution@swift.org> wrote:

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