classprivate protection level?

there are two very different use cases for which we use extensions.

1) the extensions i use to split implementation of my own classes into
different parts and / or files. for the sake of this discussion let's call
this type of extensions a "continuation".

2) the extensions that are used to extend other people classes or system
classes. this matches what we have now.

speaking of (1) the naïve newcomers from C++ land would consider these
continuations the same as splitting their C++ class implementation into
separate files. e.g. the expectation is having an ability to access
"private" members. if such a thing existed in swift at all it wouldn't be
unimaginable having an ability to add variables in these continuations the
same way as in the class itself. here "protected" access level would be a
reasonable addition, and if we want to be totally nitpicky "protected"
would be for subclasses and some other keyword, say, "extensionprivate" or
"domestic" for continuations.

an interesting challenge would be somehow prohibiting external people
adding continuations to your own classes :slight_smile:

Mike

···

On 29 October 2017 at 16:04, Adam Kemp <adam.kemp@apple.com> wrote:

Internal is the right choice here. If it gives too much access then you
might consider pulling this code into a separate module.

If “private” gave access to every extension then any code outside your
module could make a new extension and access that method. That would make
it effectively public in that you wouldn’t have any ability to limit who
can call it.

Internal is the right choice here. If it gives too much access then you might consider pulling this code into a separate module.

If “private” gave access to every extension then any code outside your module could make a new extension and access that method. That would make it effectively public in that you wouldn’t have any ability to limit who can call it.

there are two very different use cases for which we use extensions.

1) the extensions i use to split implementation of my own classes into different parts and / or files. for the sake of this discussion let's call this type of extensions a "continuation".

Internal is sufficient for this use case.

2) the extensions that are used to extend other people classes or system classes. this matches what we have now.

There’s no need for a new access level here. If it’s in the same module then you use internal. If it’s not then you shouldn’t be able to access anything other than public API.

speaking of (1) the naïve newcomers from C++ land would consider these continuations the same as splitting their C++ class implementation into separate files. e.g. the expectation is having an ability to access "private" members. if such a thing existed in swift at all it wouldn't be unimaginable having an ability to add variables in these continuations the same way as in the class itself. here "protected" access level would be a reasonable addition, and if we want to be totally nitpicky "protected" would be for subclasses and some other keyword, say, "extensionprivate" or "domestic" for continuations.

Protected is a different concept entirely. I’m not sure what the reasoning was for leaving it out. Personally I do think protected is a useful access level so that you can clearly define API intended for subclasses. However, protected has nothing to do with extensions. It doesn’t solve that use case.

an interesting challenge would be somehow prohibiting external people adding continuations to your own classes :slight_smile:

That was my original point. This is what internal does. We don’t need any new access levels for extensions. Internal solves these use cases. Code in the same module can be maintained in lockstep so you can make things internal as needed for extensions. Anything beyond that is effectively indistinguishable from public so just call it that.

···

On Oct 29, 2017, at 5:29 PM, Mike Kluev <mike.kluev@gmail.com> wrote:

On 29 October 2017 at 16:04, Adam Kemp <adam.kemp@apple.com> wrote:

Mike

if I have N big classes, each split across M files to keep size
manageable, do I need to have N different modules if i want to achieve a
good separation between classes? (same level of protection that private
gives for a class that fits in a single file) i.e. one module per one class?

Mike

···

On 30 October 2017 at 02:54, Adam Kemp <adam.kemp@apple.com> wrote:

That was my original point. This is what internal does. We don’t need any
new access levels for extensions. Internal solves these use cases. Code in
the same module can be maintained in lockstep so you can make things
internal as needed for extensions. Anything beyond that is effectively
indistinguishable from public so just call it that.

Access levels exist for encapsulation. They don’t mean anything unless they actually allow you to reason about which code can break if you make a change. Given that, here is how each existing access level is useful:

    Public means a change could break any code.

    Internal means only code in the module can break so you can audit all usages in that module and fix as needed.

    File private means only code within the file can break so you only have to audit the one file.

    Private means only code within the class or extensions in the same file can break so you only have to audit part of that one file.

What would a proposed new access level mean for which code has to be audited when making a change?

    If any extension can access something even across modules then that makes it the same as public. You can’t make any change without risking breaking a client.

    If any extension can access something within the same module then it’s the same as internal. You have to audit the whole module.

If your new access level doesn’t make a new bucket for what code to audit then it’s not adding any value.

···

On Oct 29, 2017, at 8:40 PM, Mike Kluev <mike.kluev@gmail.com> wrote:

On 30 October 2017 at 02:54, Adam Kemp <adam.kemp@apple.com> wrote:

That was my original point. This is what internal does. We don’t need any new access levels for extensions. Internal solves these use cases. Code in the same module can be maintained in lockstep so you can make things internal as needed for extensions. Anything beyond that is effectively indistinguishable from public so just call it that.

if I have N big classes, each split across M files to keep size manageable, do I need to have N different modules if i want to achieve a good separation between classes? (same level of protection that private gives for a class that fits in a single file) i.e. one module per one class?

Mike

Module1

    Class A in it's own file
    extension A in it's own file

    Class B in it's own file
    extension B in it's own file

    Class C in it's own file
    extension C in it's own file

Module 2
    ....

obviously i do not want guys from team B and C accessing anything "team A
private".

is my understanding of your words then correct that you suggest to have
this:

Module1

    Class A in it's own file
    extension A in it's own file

Module2

    Class B in it's own file
    extension B in it's own file

Module3

    Class C in it's own file
    extension C in it's own file

Module 4
    ....

···

On 30 October 2017 at 04:04, Adam Kemp <adam.kemp@apple.com> wrote:

Access levels exist for encapsulation. They don’t mean anything unless
they actually allow you to reason about which code can break if you make a
change. Given that, here is how each existing access level is useful:

    Public means a change could break any code.

    Internal means only code in the module can break so you can audit all
usages in that module and fix as needed.

    File private means only code within the file can break so you only
have to audit the one file.

    Private means only code within the class or extensions in the same
file can break so you only have to audit part of that one file.

What would a proposed new access level mean for which code has to be
audited when making a change?

    If any extension can access something even across modules then that
makes it the same as public. You can’t make any change without risking
breaking a client.

    If any extension can access something within the same module then it’s
the same as internal. You have to audit the whole module.

If your new access level doesn’t make a new bucket for what code to audit
then it’s not adding any value.

On Oct 29, 2017, at 8:40 PM, Mike Kluev <mike.kluev@gmail.com> wrote:

On 30 October 2017 at 02:54, Adam Kemp <adam.kemp@apple.com> wrote:

That was my original point. This is what internal does. We don’t need any
new access levels for extensions. Internal solves these use cases. Code in
the same module can be maintained in lockstep so you can make things
internal as needed for extensions. Anything beyond that is effectively
indistinguishable from public so just call it that.

if I have N big classes, each split across M files to keep size
manageable, do I need to have N different modules if i want to achieve a
good separation between classes? (same level of protection that private
gives for a class that fits in a single file) i.e. one module per one class?

Mike

Module1

    Class A in it's own file
    extension A in it's own file

    Class B in it's own file
    extension B in it's own file

    Class C in it's own file
    extension C in it's own file

Module 2
    ....

obviously i do not want guys from team B and C accessing anything "team A private".

Then your proposal cannot help you accomplish that goal. If any extension of class A can access a method then someone writing code in the same file as B or C can write an extension of class A and expose it to other code in the same file as B or C. That means when you are making a change to that method you have to assume that there may be code relying on it, and you have to audit that code.

It’s worse than that, though. If that method is accessible even to extensions in other modules then that means any external client of this module could also rely on that behavior, and that means you cannot safely change it at all. You have effectively made it public. You have lost all control. It is no longer encapsulated at all.

When you choose an access level you are deciding which code you are allowing to depend on it, and thus which code you will have to fix if you change it. If a change might break any client of the whole module then it’s public. You’re only fooling yourself if you call it something else.

is my understanding of your words then correct that you suggest to have this:

Module1

    Class A in it's own file
    extension A in it's own file

Module2

    Class B in it's own file
    extension B in it's own file

Module3

    Class C in it's own file
    extension C in it's own file

Module 4
    ....

No. There are two reasonable options:

1. Make it public. If it’s needed outside the module then this is an accurate description of its access level.

2. Make it internal and accept that any code in the same module can access it. Again, that is effectively what your proposed scope allows anyway so internal is an accurate description of its actual access level. Call it what it is.

Either way the answer is basically the same: don’t obfuscate the effective access level and pretend you’re being strict when you’re really not. It’s like putting a lock on the door with the key hanging from the doorknob. You may as well just keep it unlocked.

···

On Oct 29, 2017, at 9:22 PM, Mike Kluev <mike.kluev@gmail.com> wrote:

On 30 October 2017 at 04:04, Adam Kemp <adam.kemp@apple.com> wrote:
Access levels exist for encapsulation. They don’t mean anything unless they actually allow you to reason about which code can break if you make a change. Given that, here is how each existing access level is useful:

    Public means a change could break any code.

    Internal means only code in the module can break so you can audit all usages in that module and fix as needed.

    File private means only code within the file can break so you only have to audit the one file.

    Private means only code within the class or extensions in the same file can break so you only have to audit part of that one file.

What would a proposed new access level mean for which code has to be audited when making a change?

    If any extension can access something even across modules then that makes it the same as public. You can’t make any change without risking breaking a client.

    If any extension can access something within the same module then it’s the same as internal. You have to audit the whole module.

If your new access level doesn’t make a new bucket for what code to audit then it’s not adding any value.

On Oct 29, 2017, at 8:40 PM, Mike Kluev <mike.kluev@gmail.com> wrote:

On 30 October 2017 at 02:54, Adam Kemp <adam.kemp@apple.com> wrote:

That was my original point. This is what internal does. We don’t need any new access levels for extensions. Internal solves these use cases. Code in the same module can be maintained in lockstep so you can make things internal as needed for extensions. Anything beyond that is effectively indistinguishable from public so just call it that.

if I have N big classes, each split across M files to keep size manageable, do I need to have N different modules if i want to achieve a good separation between classes? (same level of protection that private gives for a class that fits in a single file) i.e. one module per one class?

Mike

No. There are two reasonable options:

1. Make it public. If it’s needed outside the module then this is an
accurate description of its access level.

2. Make it internal and accept that any code in the same module can access
it. Again, that is effectively what your proposed scope allows anyway so
internal is an accurate description of its actual access level. Call it
what it is.

Adam, i fail to see why you say "No" to "one module per class approach" if
the goal is to make the individual multi-file classes as isolated as
possible (i.e. not see each other "internal" stuff). which (this goal) is
considered the "way to go" approach in other languages and the "default"
behaviour.

this:

SingleFileClass1.swift // with bunch of "privates" inside

SingleFileClass2.swift // with bunch of "privates" inside

SingleFileClass3.swift // with bunch of "privates" inside

is equivalent to this:

Module solely for Class1
   Class1.swift // with bunch of "internals inside
   Class1+Extension.swift // with bunch of "internals" inside

Module solely for Class2
   Class2.swift // with bunch of "internals" inside
   Class2+Extension.swift // with bunch of "internals" inside

Module solely for Class3
   Class3.swift // with bunch of "internals" inside
   Class3+Extension.swift // with bunch of "internals" inside

still "no" ?

i mean, it's fine (although a bit odd) that a mere change from a
single-file to a multi-file class leads to such drastic consequences.
different to what i saw before. but I can adapt of course.

Either way the answer is basically the same: don’t obfuscate the effective

access level and pretend you’re being strict when you’re really not. It’s
like putting a lock on the door with the key hanging from the doorknob. You
may as well just keep it unlocked.

nice analogy :slight_smile:

Mike

···

On 30 October 2017 at 07:30, Adam Kemp <adam.kemp@apple.com> wrote:

Access levels are not a security mechanism. You have to trust your (fellow) programmers. Lots of good software has been created in Smalltalk and other languages without "private" access levels.

···

--
C. Keith Ray

* https://leanpub.com/wepntk <- buy my book?
* http://www.thirdfoundationsw.com/keith_ray_resume_2014_long.pdf
* http://agilesolutionspace.blogspot.com/

On Oct 30, 2017, at 5:34 AM, Mike Kluev via swift-evolution <swift-evolution@swift.org> wrote:

On 30 October 2017 at 07:30, Adam Kemp <adam.kemp@apple.com> wrote:

No. There are two reasonable options:

1. Make it public. If it’s needed outside the module then this is an accurate description of its access level.

2. Make it internal and accept that any code in the same module can access it. Again, that is effectively what your proposed scope allows anyway so internal is an accurate description of its actual access level. Call it what it is.

Adam, i fail to see why you say "No" to "one module per class approach" if the goal is to make the individual multi-file classes as isolated as possible (i.e. not see each other "internal" stuff). which (this goal) is considered the "way to go" approach in other languages and the "default" behaviour.

this:

SingleFileClass1.swift // with bunch of "privates" inside

SingleFileClass2.swift // with bunch of "privates" inside

SingleFileClass3.swift // with bunch of "privates" inside

is equivalent to this:

Module solely for Class1
   Class1.swift // with bunch of "internals inside
   Class1+Extension.swift // with bunch of "internals" inside
   
Module solely for Class2
   Class2.swift // with bunch of "internals" inside
   Class2+Extension.swift // with bunch of "internals" inside

Module solely for Class3
   Class3.swift // with bunch of "internals" inside
   Class3+Extension.swift // with bunch of "internals" inside
   
still "no" ?

i mean, it's fine (although a bit odd) that a mere change from a single-file to a multi-file class leads to such drastic consequences. different to what i saw before. but I can adapt of course.

Either way the answer is basically the same: don’t obfuscate the effective access level and pretend you’re being strict when you’re really not. It’s like putting a lock on the door with the key hanging from the doorknob. You may as well just keep it unlocked.

nice analogy :slight_smile:

Mike

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

No. There are two reasonable options:

1. Make it public. If it’s needed outside the module then this is an accurate description of its access level.

2. Make it internal and accept that any code in the same module can access it. Again, that is effectively what your proposed scope allows anyway so internal is an accurate description of its actual access level. Call it what it is.

Adam, i fail to see why you say "No" to "one module per class approach" if the goal is to make the individual multi-file classes as isolated as possible (i.e. not see each other "internal" stuff). which (this goal) is considered the "way to go" approach in other languages and the "default" behaviour.

I didn’t mean “no, you can’t do that”. You can if you want to. What I meant was “no, I’m not suggesting that you should do that”. I don’t think it’s necessary.

Which other language has an access level like the one being proposed?

···

On Oct 30, 2017, at 5:34 AM, Mike Kluev <mike.kluev@gmail.com> wrote:
On 30 October 2017 at 07:30, Adam Kemp <adam.kemp@apple.com <mailto:adam.kemp@apple.com>> wrote:

this:

SingleFileClass1.swift // with bunch of "privates" inside

SingleFileClass2.swift // with bunch of "privates" inside

SingleFileClass3.swift // with bunch of "privates" inside

is equivalent to this:

Module solely for Class1
   Class1.swift // with bunch of "internals inside
   Class1+Extension.swift // with bunch of "internals" inside
   
Module solely for Class2
   Class2.swift // with bunch of "internals" inside
   Class2+Extension.swift // with bunch of "internals" inside

Module solely for Class3
   Class3.swift // with bunch of "internals" inside
   Class3+Extension.swift // with bunch of "internals" inside
   
still "no" ?

i mean, it's fine (although a bit odd) that a mere change from a single-file to a multi-file class leads to such drastic consequences. different to what i saw before. but I can adapt of course.

Either way the answer is basically the same: don’t obfuscate the effective access level and pretend you’re being strict when you’re really not. It’s like putting a lock on the door with the key hanging from the doorknob. You may as well just keep it unlocked.

nice analogy :slight_smile:

Mike

I didn’t mean “no, you can’t do that”. You can if you want to. What I
meant was “no, I’m not suggesting that you should do that”. I don’t think
it’s necessary.

as you said before the benefit of keeping private things private is
minimizing the amount of code that can break once you change a variable. if
it's "internal" - the whole module must be checked. if it is "internal"
rather than "private":
it is done because otherwise i'd have to keep the (big) class in a single
file

···

On 30 October 2017 at 16:34, Adam Kemp <adam_kemp@apple.com> wrote:

Which other language has an access level like the one being proposed?

this:

SingleFileClass1.swift // with bunch of "privates" inside

SingleFileClass2.swift // with bunch of "privates" inside

SingleFileClass3.swift // with bunch of "privates" inside

is equivalent to this:

Module solely for Class1
   Class1.swift // with bunch of "internals inside
   Class1+Extension.swift // with bunch of "internals" inside

Module solely for Class2
   Class2.swift // with bunch of "internals" inside
   Class2+Extension.swift // with bunch of "internals" inside

Module solely for Class3
   Class3.swift // with bunch of "internals" inside
   Class3+Extension.swift // with bunch of "internals" inside

still "no" ?

i mean, it's fine (although a bit odd) that a mere change from a
single-file to a multi-file class leads to such drastic consequences.
different to what i saw before. but I can adapt of course.

Either way the answer is basically the same: don’t obfuscate the effective

access level and pretend you’re being strict when you’re really not. It’s
like putting a lock on the door with the key hanging from the doorknob. You
may as well just keep it unlocked.

nice analogy :slight_smile:

Mike

sorry, hit "Sent" too early

I didn’t mean “no, you can’t do that”. You can if you want to. What I
meant was “no, I’m not suggesting that you should do that”. I don’t think
it’s necessary.

as you said before the benefit of keeping private things private is
minimizing the amount of code that can break once you change a variable. if
it's "internal" - the whole module must be checked. if it is "internal"
rather than "private":

- it is done because otherwise i'd have to keep the (big) class in a single
file
- shows the limitation in the language in regards to one-file-class vs
multi-file-class
- forces me to use one module per file if I want to mimic the "private"
keyword as close as possible
- or forces me to keep my class in a single file.

Which other language has an access level like the one being proposed?

i am not aware of such a language. C++'s "private" comes close as it can be
used in multiple files but then C++ doesn't have extensions. C++
"protected" comes close for something I can use in subclasses.

Mike

···

On 30 October 2017 at 16:34, Adam Kemp <adam_kemp@apple.com> wrote:

The goal isn’t to entirely avoid having to audit any code while making a change. The goal is to allow you to reason about which code you would have to audit. A new access level should lead to a new bucket of code that needs to be audited, but none of the proposals here would do that. They’re all equivalent to existing access levels.

···

On Oct 30, 2017, at 10:10 AM, Mike Kluev <mike.kluev@gmail.com> wrote:

On 30 October 2017 at 16:34, Adam Kemp <adam_kemp@apple.com <mailto:adam_kemp@apple.com>> wrote:

I didn’t mean “no, you can’t do that”. You can if you want to. What I meant was “no, I’m not suggesting that you should do that”. I don’t think it’s necessary.

as you said before the benefit of keeping private things private is minimizing the amount of code that can break once you change a variable. if it's "internal" - the whole module must be checked. if it is "internal" rather than "private”:
it is done because otherwise i'd have to keep the (big) class in a single file

the new bucket would be "class and all of its extensions be them in the
same file or in different files".

back to your example with the locked door and the keys on the doorstep, i
can violate "protected" in C++:

developer 1:
class Base { protected void foo(); }

developer 2:
class Derived: Base { public void not_so_protected_foo() { foo() }

but that doesn't mean that "protected" in C++ shall be ditched!

this is similar to what you said before about writing an extension and
exposing the private functionality as public violating protection.

Mike

···

On 30 October 2017 at 17:22, Adam Kemp <adam_kemp@apple.com> wrote:

The goal isn’t to entirely avoid having to audit any code while making a
change. The goal is to allow you to reason about which code you would have
to audit. A new access level should lead to a new bucket of code that needs
to be audited, but none of the proposals here would do that. They’re all
equivalent to existing access levels.

The goal isn’t to entirely avoid having to audit any code while making a change. The goal is to allow you to reason about which code you would have to audit. A new access level should lead to a new bucket of code that needs to be audited, but none of the proposals here would do that. They’re all equivalent to existing access levels.

the new bucket would be "class and all of its extensions be them in the same file or in different files”.

That’s not a new bucket. It is equivalent to either internal or public, depending on whether you want to extend this beyond the module boundary. The set of code you would have to audit is the same.

back to your example with the locked door and the keys on the doorstep, i can violate "protected" in C++:

developer 1:
class Base { protected void foo(); }

developer 2:
class Derived: Base { public void not_so_protected_foo() { foo() }

but that doesn't mean that "protected" in C++ shall be ditched!

In terms of reasoning about code that might break, protected is equivalent to public. The only advantage to protected over public is that it tells clients how to properly use it.

What does marking a method as “specialprivate” (my made up name for this new access level) tell clients about who can use it or how it can be used?

···

On Oct 30, 2017, at 10:57 AM, Mike Kluev <mike.kluev@gmail.com> wrote:
On 30 October 2017 at 17:22, Adam Kemp <adam_kemp@apple.com <mailto:adam_kemp@apple.com>> wrote:

this is similar to what you said before about writing an extension and exposing the private functionality as public violating protection.

Mike

the new bucket would be "class and all of its extensions be them in the
same file or in different files”.

That’s not a new bucket. It is equivalent to either internal or public,
depending on whether you want to extend this beyond the module boundary.
The set of code you would have to audit is the same.

it is different, see below:

=== file: Some.swift

class Some {
   internal func foo() {
      bar()
   }
   classprivate func better() {
      good()
    }
}

=== file: Some+Bar.swift

extension Some {
  internal func bar() {
      foo()
  }
  classprivate func good() {
      better()
   }
}

=== any other file (same module)

class Other {
    func x() {
        let some = Some()

        some.foo() // ************** UNWANTED!!!!!!

        some.better() // error. ****** WANTED!
    }
}

I do not want to audit the class Other when I make a change to "foo" or
"bar", which are essentially "private" and only made "internal" because of
the language limitation in regards to "private" vs "multi-file class" issue.

What does marking a method as “specialprivate” (my made up name for this
new access level) tell clients about who can use it or how it can be used?

it tells them: "you can't use this, unless you are writing an extension to
this class or making changes to this class itself"

Mike

···

On 30 October 2017 at 18:07, Adam Kemp <adam_kemp@apple.com> wrote:

On Oct 30, 2017, at 10:57 AM, Mike Kluev <mike.kluev@gmail.com> wrote:

the new bucket would be "class and all of its extensions be them in the same file or in different files”.

That’s not a new bucket. It is equivalent to either internal or public, depending on whether you want to extend this beyond the module boundary. The set of code you would have to audit is the same.

it is different, see below:

=== file: Some.swift

class Some {
   internal func foo() {
      bar()
   }
   classprivate func better() {
      good()
    }
}

=== file: Some+Bar.swift

extension Some {
  internal func bar() {
      foo()
  }
  classprivate func good() {
      better()
   }
}

=== any other file (same module)

class Other {
    func x() {
        let some = Some()

        some.foo() // ************** UNWANTED!!!!!!
        
        some.better() // error. ****** WANTED!
    }
}

How do you know there’s not an extension in this file without looking? If you don’t know then you have to check. That puts it in the same bucket as internal or public. The set of files you have to search through for usages is the same.

I do not want to audit the class Other when I make a change to "foo" or "bar", which are essentially "private" and only made "internal" because of the language limitation in regards to "private" vs "multi-file class" issue.

What does marking a method as “specialprivate” (my made up name for this new access level) tell clients about who can use it or how it can be used?

it tells them: "you can't use this, unless you are writing an extension to this class or making changes to this class itself”

There’s nothing special about an extension. Anyone can write an extension to any class. You shouldn’t need any special privileges to enable people to write extensions. You’re not gaining anything by introducing an interface only usable by extensions.

···

On Oct 30, 2017, at 11:19 AM, Mike Kluev <mike.kluev@gmail.com> wrote:
On 30 October 2017 at 18:07, Adam Kemp <adam_kemp@apple.com <mailto:adam_kemp@apple.com>> wrote:

On Oct 30, 2017, at 10:57 AM, Mike Kluev <mike.kluev@gmail.com <mailto:mike.kluev@gmail.com>> wrote:

Mike

I'd just search for "extension SomeClass", Xcode search result window will
list all files that have it.
or I will list all the users of "foo" if that's the one I am changing.

the good guideline from Obj-C was (and still is) using
"SomeClass+ExtensionName" file naming convention that also helps.

Mike

···

On 30 October 2017 at 19:49, Adam Kemp <adam_kemp@apple.com> wrote:

How do you know there’s not an extension in this file without looking? If
you don’t know then you have to check. That puts it in the same bucket as
internal or public. The set of files you have to search through for usages
is the same.

How do you know there’s not an extension in this file without looking? If you don’t know then you have to check. That puts it in the same bucket as internal or public. The set of files you have to search through for usages is the same.

I'd just search for "extension SomeClass", Xcode search result window will list all files that have it.
or I will list all the users of "foo" if that's the one I am changing.

When you do that search, which files do you include in the search? That’s the key.

the good guideline from Obj-C was (and still is) using "SomeClass+ExtensionName" file naming convention that also helps.

That’s not sufficient because there’s nothing in the language that would force people to follow this convention, and you can have extensions in any file for any class.

The point I’m trying to make, again, is that the set of files that you would have to search through is the same. Once you know the set of files that need to be searched you can just search for actual usages of the API you’re changing (the method or property or whatever). The important thing is to know which files need to be searched in the first place. That’s what access level really controls.

Each access level implies a unique set of files that have to be searched. Public = all files in all clients. Internal = all files in this module. File private = just one file. Private = just one part of one file.

“specialprivate", by allowing any extension to access the API, would imply the same set of files as either internal or public. You can’t know ahead of time whether some random file in your module might make an extension that access that API so you have to search all files within that module. You would perform the search exactly the same way. It doesn’t help you as a library maintainer. You’re not going to save work by making something “specialprivate” instead of internal. Worst case is you actually convince yourself that you don’t have to search the whole module, and then you break something because of that misunderstanding. That’s why internal is better. It avoids obfuscating the actual implications of that access level.

···

On Oct 30, 2017, at 2:23 PM, Mike Kluev <mike.kluev@gmail.com> wrote:
On 30 October 2017 at 19:49, Adam Kemp <adam_kemp@apple.com <mailto:adam_kemp@apple.com>> wrote:

If I’m concerned with how much work I’ll have to do, no that’s not the key. The key is how many files do I have to read myself (only those containing a subclass or extension of my base class).

Why would you read any file before searching for usages and figuring out which files use that API? And the scope of that search is defined by the access level.

You seem to be conflating a near instantaneous search in an IDE

No, grep would be sufficient as well. The issue is still which files to grep in the first place. Everything else comes after that. If you manually read files looking for usages of an API you’re changing then I feel sorry for you. You’re doing things the hard way.

There doesn’t need to be anything in the language, I just need to have a defined coding convention that contributors follow. As someone else said upthread you have to be able to trust your fellow developers.

If you trust your fellow developers then you don’t need a new access scope. Use internal or public.

I’m not going to go back and forth on this any longer. We’re going in circles. We just don’t agree, and this doesn’t appear to be going anywhere.

···

On Oct 30, 2017, at 5:36 PM, Noah Desch <deschnl@icloud.com> wrote:

How do you know there’s not an extension in this file without looking? If you don’t know then you have to check. That puts it in the same bucket as internal or public. The set of files you have to search through for usages is the same.

I'd just search for "extension SomeClass", Xcode search result window will list all files that have it.
or I will list all the users of "foo" if that's the one I am changing.

When you do that search, which files do you include in the search? That’s the key.

If I’m concerned with how much work I’ll have to do, no that’s not the key. The key is how many files do I have to read myself (only those containing a subclass or extension of my base class). You seem to be conflating a near instantaneous search in an IDE with manually evaluating a change’s impact to other source files in the module. “Classprivate" makes significantly fewer files that I have to manually review compared to “internal”.

the good guideline from Obj-C was (and still is) using "SomeClass+ExtensionName" file naming convention that also helps.

That’s not sufficient because there’s nothing in the language that would force people to follow this convention, and you can have extensions in any file for any class.

There doesn’t need to be anything in the language, I just need to have a defined coding convention that contributors follow. As someone else said upthread you have to be able to trust your fellow developers.

-Noah

···

On Oct 30, 2017, at 6:38 PM, Adam Kemp via swift-evolution <swift-evolution@swift.org> wrote:

On Oct 30, 2017, at 2:23 PM, Mike Kluev <mike.kluev@gmail.com> wrote:
On 30 October 2017 at 19:49, Adam Kemp <adam_kemp@apple.com> wrote: