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.
You can *guarantee* that nothing in the same file touches what it shouldn't
···
On Fri, Feb 17, 2017 at 1:11 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
On Fri, Feb 17, 2017 at 12:45 PM, Vladimir.S <svabox@gmail.com> wrote:
On 17.02.2017 20:48, Xiaodi Wu wrote:
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@swift.org <mailto:swift-evolution@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@swift.org <mailto:swift-evolution@swift.org>
<mailto:swift-evolution@swift.org <mailto:swift-evolution@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@gmail.com >>> <mailto:xiaodi.wu@gmail.com> >>> >>> <mailto:xiaodi.wu@gmail.com <mailto:xiaodi.wu@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@swift.org <mailto:swift-evolution@swift.org> >>> <mailto:swift-evolution@swift.org <mailto:swift-evolution@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@masters3d.com <mailto:cheyo@masters3d.com> >>> <mailto:cheyo@masters3d.com <mailto:cheyo@masters3d.com>>> wrote:
>>>>
>>>> Access Control and protected - Swift Blog - Apple Developer
>>>>
>>>>
>>>>
>>>> On Feb 16, 2017, at 10:05 PM, Charlie Monroe via
swift-evolution
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.
>
<mailto:swift-evolution@swift.org <mailto:swift-evolution@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@swift.org >>> <mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org >>> <mailto:swift-evolution@swift.org>>> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> Sent from my iPad
>>>>>>
>>>>>>> On Feb 16, 2017, at 8:36 PM, David Sweeris via
swift-evolution
>>>>>>> <swift-evolution@swift.org
<mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org
<mailto:swift-evolution@swift.org>>>
>>>>>>> wrote:
>>>>>>>
>>>>>>>
>>>>>>>> On Feb 16, 2017, at 14:34, Slava Pestov via
swift-evolution
>>>>>>>> <swift-evolution@swift.org
<mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org
<mailto:swift-evolution@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@swift.org
<mailto:swift-evolution@swift.org> <mailto:swift-evolution@swift.org
<mailto:swift-evolution@swift.org>>
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>>
>>>>>> _______________________________________________
>>>>>> swift-evolution mailing list
>>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.
>
<mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org
>>
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.
>
<mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org
>>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
<mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org
>>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
<mailto:swift-evolution@swift.org <mailto:swift-evolution@swift.org
>>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution