- i do a search for, say, "foo" (all files in the module)
- let's say 50 usages will be legitimate use from within the class or it's
extensions
- another 10 usages will be wrong, that mistakenly treated it's "internal /
public" as a permission to use.
- i found those instances which shall not be there (that mistakenly use it
as it is effectively public)
- i ask developers who did it to not do this again / fix the problem / etc
- some time later i can do the same mistake myself again or other people
will do the same mistake again and the process repeats.
- compiler doesn't help as it can't check
- it becomes a manual and error prone process
"classprivate" helps to resolve this problem. if it is marked so developer
will at least think twice before making an extension to use it - similar to
how marking a method "protected" stops people from using it without
subclassing - (and creating an extension for the sole purpose of using
despite of it's access level would qualify as "cheating", which we can
leave aside). with "internal / public" there is nothing stopping them for a
second and they can use it without even realising they are doing something
wrong. all IMHO.
Mike
···
On 30 October 2017 at 22:38, Adam Kemp <adam_kemp@apple.com> wrote:
“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.
exactly. significantly fewer files or fragments of files - significantly
fewer entries in the search results in other words.
when in a pub:
public / internal:
- may i have a pint of lager please? - sure, here you are
classprivate / protected:
- may i have a pint of ale please?
- sure. are you a member of our club? we serve ale to members only
- errr. no. can i become a member?
- yes, it is free. just take a seat over there and fill this form
first, once done i will bring you your ale.
- errr, thanks. may i have lager instead please?
private:
- may i have a pint of potter please?
- sure. are you a member of our club?
- yes, i just filed the form, here it is.
- are you aware that we serve potter only in that "core members
only" private room?
- errr, no, how do i get there?
- ah, no sir, it is impossible. you would know if you can go there.
it is by invitation only system.
- damn!! lager!
i am dead sure they will serve much less ale than lager, don't you.
Mike
···
On 31 October 2017 at 00:36, Noah Desch <deschnl@icloud.com> wrote:
> 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:
>>
>> 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”.
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.
so you've used grep to search for "foo" in all files of the module (in case
of "internal func foo") and grep returned 50 files.
in case of "classprivate func foo" that would be, say, 10 files. or even 50
files - doesn't matter.
what matters is the actual number of hits of "foo" to review, in the former
case it would be, say "50 files * 10 hits in each" in the latter - "50
files with one hit in each". and in reality even "10 files with one hit in
each". thus the search set to review is much much smaller.
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.
i agree to disagree.
Mike
···
On 31 October 2017 at 02:29, Adam Kemp <adam.kemp@apple.com> wrote:
Why would they think twice, though? You’ve told them extensions can use it, and they’ve written an extension to use it. What did they do wrong? I don’t think the rules are nearly as clear as for protected.
···
On Oct 30, 2017, at 4:10 PM, Mike Kluev <mike.kluev@gmail.com> wrote:
"classprivate" helps to resolve this problem. if it is marked so developer will at least think twice before making an extension to use it
this is obvious: when they are writing a method in their own class and try
to call: some.foo() it will give them and access level error (or even
before that the autocomplete will not work as an early hint), they will
reveal foo's definition, see "classprivate" in there and at that very point
take a pause, think and make a conscious decision whether they really want
it or not. if they really want it they will make an extension (which would
be a legitimate use of it) if they don't need it really - they will find
another way without making an extension. the (reasonable) expectation is
that such a "classprivate" will reduce the number of instances where "foo"
is used thus reducing the "working set" of instances i have to review when
making a change to it.
Mike
···
On 30 October 2017 at 23:14, Adam Kemp <adam_kemp@apple.com> wrote:
> On Oct 30, 2017, at 4:10 PM, Mike Kluev <mike.kluev@gmail.com> wrote:
>
> "classprivate" helps to resolve this problem. if it is marked so
developer will at least think twice before making an extension to use it
Why would they think twice, though? You’ve told them extensions can use
it, and they’ve written an extension to use it. What did they do wrong? I
don’t think the rules are nearly as clear as for protected.
This idea has been discussed before and deemed inconsistent with Swift's
design for access levels. Any further access levels are pretty clearly out
of scope for Swift 5. I'll refer you to the list of focus areas here:
···
On Mon, Oct 30, 2017 at 20:30 Mike Kluev via swift-evolution < swift-evolution@swift.org> wrote:
On 31 October 2017 at 00:36, Noah Desch <deschnl@icloud.com> wrote:
> 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:
>>
>> 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”.
exactly. significantly fewer files or fragments of files - significantly
fewer entries in the search results in other words.
when in a pub:
public / internal:
- may i have a pint of lager please? - sure, here you are
classprivate / protected:
- may i have a pint of ale please?
- sure. are you a member of our club? we serve ale to members only
- errr. no. can i become a member?
- yes, it is free. just take a seat over there and fill this form
first, once done i will bring you your ale.
- errr, thanks. may i have lager instead please?
private:
- may i have a pint of potter please?
- sure. are you a member of our club?
- yes, i just filed the form, here it is.
- are you aware that we serve potter only in that "core members
only" private room?
- errr, no, how do i get there?
- ah, no sir, it is impossible. you would know if you can go there.
it is by invitation only system.
- damn!! lager!
i am dead sure they will serve much less ale than lager, don't you.
This is not the situation I was asking about. I was asking why would someone in a random file who is about to write an extension think twice about using this method? He wouldn’t, because you’ve told him using that method (in an extension) is fine. But you may not know about or approve of that code he’s writing, and you may later make a change that breaks that usage. The access level has not improved your ability to reason about what might break.
The root of our disagreement is in how we view extensions. There’s no real difference between code in an extension and code in some other class/struct/whatever. It’s still a client of the original class, not part of that class itself. It’s a separate thing. You’re thinking of an extension as part of the original class, but it’s not. Since anyone can write an extension, even in other modules, it has to be thought of as a separate thing, an external client. The author of the class has no control over or knowledge of extensions on that class, and the only way to be able to reason about whether a change to an API is safe is to use access levels that tell the author which files might be able to use that API.
···
On Oct 30, 2017, at 4:31 PM, Mike Kluev <mike.kluev@gmail.com> wrote:
On 30 October 2017 at 23:14, Adam Kemp <adam_kemp@apple.com <mailto:adam_kemp@apple.com>> wrote:
> On Oct 30, 2017, at 4:10 PM, Mike Kluev <mike.kluev@gmail.com <mailto:mike.kluev@gmail.com>> wrote:
>
> "classprivate" helps to resolve this problem. if it is marked so developer will at least think twice before making an extension to use it
Why would they think twice, though? You’ve told them extensions can use it, and they’ve written an extension to use it. What did they do wrong? I don’t think the rules are nearly as clear as for protected.
this is obvious: when they are writing a method in their own class and try to call: some.foo() it will give them and access level error (or even before that the autocomplete will not work as an early hint),