[swift-evolution] [swift-evolution-announce] [Review] SE-0159: Fix Private Access Levels

Xiaodi Wu xiaodi.wu at gmail.com
Tue Mar 21 22:42:56 CDT 2017


On Tue, Mar 21, 2017 at 10:36 PM, Charles Srstka <cocoadev at charlessoft.com>
wrote:

> On Mar 21, 2017, at 10:15 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
>
> On Tue, Mar 21, 2017 at 9:40 PM, Charles Srstka <cocoadev at charlessoft.com>
>  wrote:
>
>> On Mar 21, 2017, at 9:17 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>
>>
>> On Tue, Mar 21, 2017 at 8:31 PM, Charles Srstka <cocoadev at charlessoft.com
>> > wrote:
>>
>>>
>>> On Mar 21, 2017, at 8:15 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>>
>>> On Tue, Mar 21, 2017 at 8:00 PM, Charles Srstka <cocoadev at charlessoft.c
>>> om> wrote:
>>>
>>>> On Mar 21, 2017, at 7:49 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>>>>
>>>>
>>>> On Tue, Mar 21, 2017 at 6:46 PM, Charles Srstka <cocoadev at charlessoft.c
>>>> om> wrote:
>>>>
>>>>> On Mar 21, 2017, at 5:26 PM, Xiaodi Wu via swift-evolution <
>>>>> swift-evolution at swift.org> wrote:
>>>>>
>>>>>
>>>>> So, if four/five access modifiers are too many, which one is carrying
>>>>> the least weight? Which one could be removed to simplify the scheme while
>>>>> maintaining the most expressiveness? Which one doesn't fulfill even its own
>>>>> stated goals? Well, one of the key goals of `private` was to allow members
>>>>> to be encapsulated within an extension, hidden even from the type being
>>>>> extended (and vice versa for members defined in the type). It says so in
>>>>> the first sentence of SE-0025. As seen above in my discussion with Charles
>>>>> Srstka, even supporters of `private` disagree with that motivation to begin
>>>>> with. The kicker is, _it also doesn't work_. Try, for instance:
>>>>>
>>>>> ```
>>>>> struct Foo {
>>>>>   private var bar: Int { return 42 }
>>>>> }
>>>>>
>>>>> extension Foo {
>>>>>   private var bar: Int { return 43 }
>>>>> }
>>>>> ```
>>>>>
>>>>> The code above should compile and does not. If I understood correctly
>>>>> the explanation from a core team member on this list, it's unclear if it
>>>>> can be made to work without changing how mangling works, which I believe
>>>>> impacts ABI and is not trivial at all. Thus, (a) even proponents of new
>>>>> `private` disagree on one of two key goals stated for new `private`; (b)
>>>>> that goal was never accomplished, and making it work is not trivial; (c) no
>>>>> one even complained about it, suggesting that it was a low-yield goal in
>>>>> the first place.
>>>>>
>>>>>
>>>>> Multiple people have already brought up cases in which they are using
>>>>> ‘private’. The repeated mention of another, unrelated use case that was
>>>>> mentioned in the SE-0025 proposal does not invalidate the real-world use
>>>>> cases which have been presented. In fact, it rather makes it appear as if
>>>>> the motivation to remove ‘private’ is based on a strange invocation of the
>>>>> appeal-to-authority fallacy, rather than an actual improvement to the
>>>>> language.
>>>>>
>>>>
>>>> I'm not sure how to respond to this. SE-0025, as designed, is not fully
>>>> implemented. And as I said above, IIUC, it cannot be fully implemented
>>>> without ripping out a lot of mangling code that is unlikely to be ripped
>>>> out before Swift 4. _And there is no evidence that anyone cares about this
>>>> flaw; in fact, you are saying as much, that you do not care at all!_ If
>>>> this is not sufficient indication that the design of SE-0025 does not fit
>>>> with the overall direction of Swift, what would be?
>>>>
>>>>
>>>> Because there are other uses cases for ‘private', *not* involving
>>>> extensions, which I *do* care about. The fact that part of the proposal was
>>>> badly written (and really, that’s all this is
>>>>
>>>
>>> Huh? The code above *should compile*--that is a primary aim for SE-0025.
>>> It does not compile and there is not a timeline (afaict) for its compiling.
>>> It does not bother you that the 25th proposal considered in the Swift
>>> evolution process, already once revised, is not fully implemented and may
>>> never be?
>>>
>>>
>>> Someone finding a bug/oversight in the compiler behavior does not compel
>>> me to throw out the baby with the bathwater, no.
>>>
>>
>> You're not hearing the argument. No one "accidentally" included this
>> design as part of SE-0025; it's sentence number one.
>>
>>
>> Or not. Here’s the actual text of the introductory paragraph:
>>
>> "Scoped access level allows hiding implementation details of a class or a
>> class extension at the class/extension level, instead of a file. It is a
>> concise expression of the intent that a particular part of a class or
>> extension definition is there only to implement a public API for other
>> classes or extensions and must not be used directly anywhere outside of the
>> scope of the class or the extension.”
>>
>> So here we have “class or extension”, or some variant thereof, five
>> separate times. It honestly reads like it originally just said “class”, and
>> the author systematically went through it and added “or extension” to each
>> of them to make sure his/her bases were covered.
>>
>
> The meaning of that sentence is made quite clear by the example in code
> given in that proposal:
>
> ```
>
> class A {
>    private var counter = 0
>
>    // public API that hides the internal state   func incrementCount() { ++counter }
>
>    // hidden API, not visible outside of this lexical scope   private func advanceCount(dx: Int) { counter += dx }
>
>    // incrementTwice() is not visible here}
> extension A {
>    // counter is not visible here   // advanceCount() is not visible here
>    // may be useful only to implement some other methods of the extension   // hidden from anywhere else, so incrementTwice() doesn’t show up in    // code completion outside of this extension   private func incrementTwice() {
>       incrementCount()
>       incrementCount()
>    }
> }
>
> ```
>
> If `counter` is not visible in `extension A { ... }`, then I must be able
> to define my own `counter` in extension A. That is just how visibility
> works in Swift; no other understanding of "visibility" can be admitted
> here. Unless you mean to argue that, in reading this proposal, you honestly
> think it's correct that `counter` may or may not be declared in `extension
> A { ... }` depending on where `class A` is declared.
>
>
> Yes, the meaning *is* made quite clear. Specifically by the comments,
> which explain exactly what the goal is: to make those functions not
> callable from outside their respective lexical scopes. As someone else
> already pointed out, the bug you found doesn’t affect the main way people
> use this feature, which is why no one complains about it.
>
> And didn’t quite succeed; the wording doesn’t account for value types.
>>
>> And anyway, I’m not sure how you even get “extensions should be able to
>> shadow private members” as Priority Number One™, based on that sentence.
>> Which part of the sentence does your code example violate? The sentence
>> says that implementation details are hidden, and so they are. The struct
>> can’t access the extension’s private members, or vice versa. The
>> name-mangling issue that causes the compiler to choke is simply a *bug*, an
>> unintended consequence that the author didn’t consider. And as I said
>> before, I’d be perfectly fine with striking all the “or extension”s from
>> that paragraph and having ‘private’ only restrict things inside the types
>> themselves (within a module, of course).
>>
>
> Whether you're fine with that is neither here nor there. It was not the
> proposal reviewed and approved by the community, and it's not the proposal
> considered here.
>
>
> Well, you’ve convinced me. Next time I find a trivial bug in the Finder,
> I’ll be sure to demand that instead of just fixing the bug, Apple toss out
> the whole kit and kaboodle and go back to the bash shell as the primary
> interface to the file system.
>

The argument is that this is _not_ a trivial issue. If Finder makes your
files disappear on a regular basis, would you not demand that Apple toss
out the whole kit?

> Or, just fixing the mangling so that works. Honestly, I don’t understand
>> what kind of point the above is supposed to make, other than pointing
>> fingers and laughing at somebody for making a mistake.
>>
>
> The point I'm making is that `private` is *very* hard to reason about and
> likely even harder to implement. This is not the mistake of the author or
> the implementor of the proposal. The entire Swift community reviewed the
> document not once but twice, and we are still discovering pitfalls. This
> certainly backs up testimony that it is a difficult feature to learn and
> teach. Does such a difficult feature hold its own weight? The argument made
> in this proposal is that it overwhelmingly does not, and therefore the
> complexity it adds to Swift is harmful.
>
>
> Oh, come *on.*
>

Hmm?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170321/9fbed672/attachment.html>


More information about the swift-evolution mailing list