[swift-evolution] final + lazy + fileprivate modifiers

Xiaodi Wu xiaodi.wu at gmail.com
Fri Feb 17 15:56:54 CST 2017


On Fri, Feb 17, 2017 at 3:46 PM, Charlie Monroe <charlie at charliemonroe.net>
wrote:

>
> On Feb 17, 2017, at 8:21 PM, Xiaodi Wu via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> On Fri, Feb 17, 2017 at 1:11 PM, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
>> On Fri, Feb 17, 2017 at 12:45 PM, Vladimir.S <svabox at gmail.com> wrote:
>>
>>> On 17.02.2017 20:48, Xiaodi Wu wrote:
>>>
>>>> What you are really asking for is a way of flexibly designating a "unit
>>>> of
>>>> code" within a module, for which the general solution is submodules. The
>>>> objection is that, instead of tackling that issue, these are
>>>> suggestions to
>>>> invent ad-hoc units of code (scope + extensions only in the same file,
>>>> scope + extensions only in the same module, class + extensions only in
>>>> the
>>>> same file + subclasses only in the same module), and it is possible to
>>>> invent arbitrary many of these.
>>>>
>>>
>>> No, sorry, I don't agree with you.
>>> Current situation forces us to generate huge source files or write each
>>> type in its own submodule/file. IMO it is very naturally to have a need to
>>> protect access to some details *even* in the same file(please find David
>>> Sweeris's answer in previous email in this thread. with current 'private'
>>> he can *guarantee* that no code touches internal props even in the same
>>> file), also many of us need a way to share some details only for
>>> extensions/subtypes in other files in the same module/submodule even just
>>> to organize code as *one* need/want and to express intention about who
>>> should "touch" this code and get help from compiler when accidentally try
>>> to use protected method/prop.
>>>
>>
>> I reject the premise that it is a goal of the Swift compiler to protect
>> you from yourself.
>>
>
> I should clarify, it should certainly protect you from unintentional
> accidents that you make, where those are foreseeable, etc. But here we're
> talking about _you_ invoking functions that _you_ wrote, which is a pretty
> darn clear demonstration of intentionality. And so what I mean to say is
> that the Swift compiler, IMO, has no real business trying to protect your
> intentions from your other intentions.
>
>
> With all due respect (and I do respect you as a person with quite an
> insight), why does Swift then (by default) check for (U)Int overflows,
> against nil values, etc, etc. These are all things that are quite
> protecting you from yourself. In a perfect world, you code your stuff in a
> way where you don't need these checks as you'd write code that would handle
> these scenarios. Oh wait, that's Objective-C...
>

Overflow, nil values, etc., all go to Swift's promising of memory safety by
default. They also reflect errors of omission: we unintentionally forget to
handle these cases. Here, a function call is an _intentional_ act. Writing
a function not meant to be called is an _intentional_ act. It is strange
that you would demand the compiler to stand between two of your own
intentional acts.


> In a similar sense, I believe the compiler/language should prevent you
> from accidently accessing members that are not designed to be accessed from
> out of certain scope.
>
> It's not just to protect _you_ from invoking something not being meant to
> invoke, but others as well.
>

Others that are part of the collective "you" working on the project, the
group of people who have permissions to touch the source code.


> Documentation is perfect only in a perfect world. I can't count how many
> times I've come to a project without a single line of comment, not to
> mention a comment indicating whether the member is meant to be called
> outside of the file, or if it's marked as internal due to current
> limitations in access control and it's simply because you needed to split
> the class amongst several files logic-wise to prevent a bloated single file.
>
> Documentation is not the answer.
>

If documentation is not the answer, then by that line of reasoning, neither
is access control. An author who can't be bothered to document that
something shouldn't be used won't be bothered to determine what an
appropriate access modifier would be, either. My point is that additional
access modifiers don't help you express yourself any more than
documentation does. Put another way, the access modifiers you advocate for
are simply an alternative spelling for a comment.


You can *guarantee* that nothing in the same file touches what it shouldn't
>> touch *by your own eyes*; `private` makes it "easier" but it is by no means
>> necessary. Indeed I argue that reading code should be the go-to way reason
>> about the behavior of code, and that compiler help is justified only when
>> such a method of reasoning is unusually hard or error-prone.
>>
>> Likewise, you can express intention by documentation. Indeed I argue that
>> reading the documentation should be the go-to way for a reader to learn how
>> to use unfamiliar code. Since a user will consult the documentation if he
>> or she is wondering, "how or when should I use this method?", it is
>> perfectly sufficient and elegant to put a sentence in the documentation
>> that says, "actually, you should never use this method." It is self-evident
>> why one might _want_ compiler help, but it is unclear to me why one _needs_
>> compiler help for this: after all, if you call an internal method that
>> doesn't behave as intended, you can read the source code to find out
>> exactly why--you can even change it!
>>
>> Someone, who want just internal/public can use only them in own code, no
>>> problems. But many feels that they need a more detailed access levels to
>>> structure their code, they find current situation not comfortable.
>>>
>>
>> As I said, there are arbitrarily many ways to structure your code. If you
>> insist that the compiler should help you to control, perfectly, exactly
>> what lines of code can call what other lines of code, and that the way to
>> spell this desire is through access levels, then you will need many more
>> access levels. My point is that, taken to its logical end, you would need
>> infinitely many access levels. Although it would be unnecessary for the
>> language to active prohibit certain styles of organizing code, I believe
>> very strongly it is a non-goal of Swift to actively support, by the
>> addition of new features, all imaginable styles of organizing code.
>>
>>
>>
>>>
>>>
>>>> There is, objectively, an actual minimum number of access modifiers,
>>>> which
>>>> is two. Those two are: visible only inside the unit of code, or visible
>>>> both inside and outside the unit of code. In Swift, those are spelled
>>>> internal and public. Everything else here is really talking about
>>>> better or
>>>> more flexible ways of defining a unit of code.
>>>>
>>>>
>>>> On Fri, Feb 17, 2017 at 06:21 Vladimir.S via swift-evolution
>>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>
>>>>     On 17.02.2017 11:29, Slava Pestov via swift-evolution wrote:
>>>>     >
>>>>     >> On Feb 17, 2017, at 12:09 AM, Charlie Monroe via swift-evolution
>>>>     >> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org
>>>> >>>
>>>>
>>>>     wrote:
>>>>     >>
>>>>     >> True, what I meant was a wider feedback - let's face it, there
>>>> are many
>>>>     >> more Swift developers now than 2 years ago.
>>>>     >>
>>>>     >> My objection is not to the documentation itself, but to the fact
>>>>     that I'm
>>>>     >> unnecessarily exposing an internal implementation detail to the
>>>> rest of
>>>>     >> the module. Being able to hide it from the rest IMHO leads to
>>>> better
>>>>     >> though-through API that is indeed meant to be exposed; whereas
>>>> exposing
>>>>     >> internal details leads to allowing various quick hacks instead.
>>>> We know
>>>>     >> these quick hacks very well from the ObjC world by accessing
>>>> private
>>>>     >> parts of the object via duck typing or setting values via KVO.
>>>>     >>
>>>>     >> At least this is my experience with which the less
>>>> implementation
>>>>     details
>>>>     >> are exposed to the outer world, the better.
>>>>     >
>>>>     > I think the fundamental disagreement we’re seeing in this thread
>>>> is the
>>>>     > meaning of “outer world”; to some, it means “users of your
>>>> module”. To
>>>>     > others, it also means “other developers on my team who are
>>>> working on
>>>>     other
>>>>     > files in the module”.
>>>>     >
>>>>     > Personally I feel enforced encapsulation of implementation
>>>> detail to the
>>>>     > latter group is less important than the former, and can be
>>>> handled by
>>>>     > convention. Whereas other users of your module definitely
>>>> benefit from
>>>>     > access control and being able to consume a clearly-defined
>>>> interface.
>>>>
>>>>     I assume we are discussing access modifiers mainly for the former
>>>> group,
>>>>     i.e. when we are "inside" the module (even when this module is
>>>> written by
>>>>     the same one person, and especially when it is written by the
>>>> group).
>>>>
>>>>     "handled by convention" - are we talking about something like
>>>> declaring
>>>>     props and methods as __privateprop , m_privateprop etc and write
>>>> comments
>>>>     to mark that they should not be used outside of some scope? Is it
>>>> really
>>>>     Swifty and acceptable for the modern language? Will this help to
>>>> prevent
>>>>     some mistakes with incorrect access? Is it better than simple and
>>>> clean
>>>>     schema for access modifiers and compiler's help?  I don't
>>>> understand this.
>>>>
>>>>     IMO, access modifiers is very known and handy abstraction to
>>>> distinct
>>>>     levels of access and to structure code many developers knows about
>>>> and use
>>>>     in other languages.
>>>>     At the end, if one wants to keep all internal - no problems!, you
>>>> can do
>>>>     this right now, just don't use fileprivate/private/etc.
>>>>
>>>>     Yes, I agree we need a simple and clean schema, not
>>>> over-complicated, we
>>>>     need nice&clean keywords, we need a required minimum of access
>>>> modifiers,
>>>>     not more, and I do believe currently we don't have this minimum.
>>>>
>>>>     Was already suggested, trying again(I do believe this could be a
>>>>     compromised solution to suit needs of the main part of developers):
>>>>     * (as currently) public/open -> outside of the module
>>>>     * (as currently) internal -> inside module
>>>>     * private -> inside file (instead of fileprivate)
>>>>     * protected(or *other* keyword) -> inside file +
>>>> subtype&extensions in the
>>>>     *same module*
>>>>
>>>>     What objections could be made for this?
>>>>     Thank you.
>>>>
>>>>     >
>>>>     > Slava
>>>>     >
>>>>     >>
>>>>     >>> On Feb 17, 2017, at 8:54 AM, Xiaodi Wu <xiaodi.wu at gmail.com
>>>>     <mailto:xiaodi.wu at gmail.com>
>>>>     >>> <mailto:xiaodi.wu at gmail.com <mailto:xiaodi.wu at gmail.com>>>
>>>> wrote:
>>>>     >>>
>>>>     >>> That blog post starts out right away to say that it's a
>>>> response to
>>>>     >>> community feedback. Moreover, the scenario you describe was
>>>> just as
>>>>     >>> possible in 2014 as it is now. Finally, then as now, it's
>>>> unclear why
>>>>     >>> you consider documentation to be "not pretty." After all, your
>>>> reader
>>>>     >>> would need to consult the documentation before using a
>>>> variable anyway.
>>>>     >>> On Fri, Feb 17, 2017 at 01:04 Charlie Monroe via
>>>> swift-evolution
>>>>     >>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org
>>>> >>>
>>>>     wrote:
>>>>     >>>
>>>>     >>>     I'm aware of this, but that's fairly a long time ago -
>>>> before Swift
>>>>     >>>     was open source and had community feedback and before
>>>> Swift was
>>>>     used
>>>>     >>>     widely among developers.
>>>>     >>>
>>>>     >>>     To me, real-world use of the language has shown some flaws
>>>> of
>>>>     >>>     missing a protected access control, mainly having to
>>>> decide between
>>>>     >>>     having a variable internal or cramming all of the class
>>>> extension
>>>>     >>>     into one file, making it a 3KLOC mess. Either solution is
>>>> not
>>>>     pretty
>>>>     >>>     - now I have it split among several files with an internal
>>>> variable
>>>>     >>>     commented as "Do not use, for private use of this class
>>>> only."
>>>>     >>>
>>>>     >>>>     On Feb 17, 2017, at 7:47 AM, Jose Cheyo Jimenez
>>>>     >>>>     <cheyo at masters3d.com <mailto:cheyo at masters3d.com>
>>>>     <mailto:cheyo at masters3d.com <mailto:cheyo at masters3d.com>>> wrote:
>>>>     >>>>
>>>>     >>>>     https://developer.apple.com/swift/blog/?id=11
>>>>     >>>>
>>>>     >>>>
>>>>     >>>>
>>>>     >>>>     On Feb 16, 2017, at 10:05 PM, Charlie Monroe via
>>>> swift-evolution
>>>>     >>>>     <swift-evolution at swift.org <mailto:swift-evolution at swift.o
>>>> rg>
>>>>     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org
>>>> >>>
>>>>     wrote:
>>>>     >>>>
>>>>     >>>>>     How about removing fileprivate, getting Swift 2 meaning
>>>> of
>>>>     private
>>>>     >>>>>     (as most people here now suggest) and add additional
>>>> @protected
>>>>     >>>>>     annotation for those who want a more fine-grained
>>>> solution:
>>>>     >>>>>
>>>>     >>>>>     @protected private - members accessable only from the
>>>>     >>>>>     class/struct/enum/... and their extensions within the
>>>> file
>>>>     >>>>>
>>>>     >>>>>     @protected internal - again, but you can access it even
>>>> from
>>>>     >>>>>     extensions and subclasses outside of the file within the
>>>> entire
>>>>     >>>>>     module.
>>>>     >>>>>
>>>>     >>>>>     @protected public/open - the same as above, but outside
>>>> the
>>>>     modules.
>>>>     >>>>>
>>>>     >>>>>     To me, this way most people here will be happy:
>>>>     >>>>>
>>>>     >>>>>     - those wishing the access control gets simplified - it
>>>> in fact
>>>>     >>>>>     does, you don't need to use @protected, if you don't want
>>>>     to/need to.
>>>>     >>>>>     - those who need a fine-grained solution, here it is.
>>>>     >>>>>
>>>>     >>>>>
>>>>     >>>>>
>>>>     >>>>>>     On Feb 17, 2017, at 3:49 AM, Matthew Johnson via
>>>> swift-evolution
>>>>     >>>>>>     <swift-evolution at swift.org
>>>>     <mailto:swift-evolution at swift.org> <mailto:swift-evolution at swift.
>>>> org
>>>>     <mailto:swift-evolution at swift.org>>> wrote:
>>>>     >>>>>>
>>>>     >>>>>>
>>>>     >>>>>>
>>>>     >>>>>>     Sent from my iPad
>>>>     >>>>>>
>>>>     >>>>>>>     On Feb 16, 2017, at 8:36 PM, David Sweeris via
>>>> swift-evolution
>>>>     >>>>>>>     <swift-evolution at swift.org
>>>>     <mailto:swift-evolution at swift.org> <mailto:swift-evolution at swift.
>>>> org
>>>>     <mailto:swift-evolution at swift.org>>>
>>>>     >>>>>>>     wrote:
>>>>     >>>>>>>
>>>>     >>>>>>>
>>>>     >>>>>>>>     On Feb 16, 2017, at 14:34, Slava Pestov via
>>>> swift-evolution
>>>>     >>>>>>>>     <swift-evolution at swift.org
>>>>     <mailto:swift-evolution at swift.org> <mailto:swift-evolution at swift.
>>>> org
>>>>     <mailto:swift-evolution at swift.org>>>
>>>>     >>>>>>>>     wrote:
>>>>     >>>>>>>>
>>>>     >>>>>>>>     While we’re bikeshedding, I’m going to add my two
>>>> cents. Hold
>>>>     >>>>>>>>     on to your hat because this might be controversial
>>>> here.
>>>>     >>>>>>>>
>>>>     >>>>>>>>     I think both ‘private’ and ‘fileprivate’ are
>>>> unnecessary
>>>>     >>>>>>>>     complications that only serve to clutter the language.
>>>>     >>>>>>>>
>>>>     >>>>>>>>     It would make a lot more sense to just have internal
>>>> and
>>>>     public
>>>>     >>>>>>>>     only. No private, no fileprivate, no lineprivate, no
>>>>     protected.
>>>>     >>>>>>>>     It’s all silly.
>>>>     >>>>>>>
>>>>     >>>>>>>     Eh, I've used `private` to keep myself honest in terms
>>>> of going
>>>>     >>>>>>>     through some book-keeping functions instead of directly
>>>>     >>>>>>>     accessing a property.
>>>>     >>>>>>
>>>>     >>>>>>     This is exactly the kind of thing I like it for and why
>>>> I
>>>>     hope we
>>>>     >>>>>>     might be able to keep scoped access even if it gets a
>>>> new name
>>>>     >>>>>>     that ends up as awkward as fileprivate (allowing
>>>> private to
>>>>     >>>>>>     revert to the Swift 2 meaning).
>>>>     >>>>>>
>>>>     >>>>>>>
>>>>     >>>>>>>     - Dave Sweeris
>>>>     >>>>>>>     _______________________________________________
>>>>     >>>>>>>     swift-evolution mailing list
>>>>     >>>>>>>     swift-evolution at swift.org
>>>>     <mailto:swift-evolution at swift.org> <mailto:swift-evolution at swift.
>>>> org
>>>>     <mailto:swift-evolution at swift.org>>
>>>>     >>>>>>>     https://lists.swift.org/mailm
>>>> an/listinfo/swift-evolution
>>>>     >>>>>>
>>>>     >>>>>>     _______________________________________________
>>>>     >>>>>>     swift-evolution mailing list
>>>>     >>>>>>     swift-evolution at swift.org <mailto:
>>>> swift-evolution at swift.org>
>>>>     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org
>>>> >>
>>>>     >>>>>>     https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>     >>>>>
>>>>     >>>>>     _______________________________________________
>>>>     >>>>>     swift-evolution mailing list
>>>>     >>>>>     swift-evolution at swift.org <mailto:swift-evolution at swift.o
>>>> rg>
>>>>     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org
>>>> >>
>>>>     >>>>>     https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>     >>>
>>>>     >>>     _______________________________________________
>>>>     >>>     swift-evolution mailing list
>>>>     >>>     swift-evolution at swift.org <mailto:swift-evolution at swift.org
>>>> >
>>>>     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org
>>>> >>
>>>>     >>>     https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>     >>>
>>>>     >>
>>>>     >> _______________________________________________
>>>>     >> swift-evolution mailing list
>>>>     >> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>     <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org
>>>> >>
>>>>     >> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>     >
>>>>     >
>>>>     >
>>>>     > _______________________________________________
>>>>     > swift-evolution mailing list
>>>>     > swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>     > https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>     >
>>>>     _______________________________________________
>>>>     swift-evolution mailing list
>>>>     swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>     https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>
>>>>
>>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170217/1943ccbf/attachment.html>


More information about the swift-evolution mailing list