Swift evolution proposal: introduce typeprivate access control level

@Daniel:

Very good idea because and it makes access control much more flexible.

@Tino:

Couldn't agree with you more about the usage of "swifty". I think it's
applicable here because communication is something that everyone agrees is
a essential in swift and access control is one of the many ways developers
have to properly describe (and communicate) an API.

···

On Thu, Dec 1, 2016 at 10:22 AM, João David via swift-evolution < swift-evolution@swift.org> wrote:

Exactly. Totally agree Tino.

Sent from my iPhone. Erroneous words are a feature, not a typo.

On 1 Dec 2016, at 09:31, Tino Heth <2th@gmx.de> wrote:

It also means that anybody who want to access your private var will just
have to write an extension to expose it.

imho this is wrong thinking:
Access control is no tool to offer real "protection" — it can't stop
someone who wants to break a system.
Especially in the world of open source, it is merely an advice from the
author not to do certain things.

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

- Typeprivate would allow to abandon the odd fileprivate. Access level would be constrained to swift constructs (structs, classes and extensions) and not to a compiler artifact (file).

Actually, imho fileprivate isn't odd or "unswift"* — it's one of the three original levels, which all rely on the layout of the filesystem ("same file?" and "same folder/module?").
Even if there was a change of mind, fileprivate is still needed for essential things like implementing Equatable.

But I'm not arguing against typeprivate at all (nor against access control in general ;-)

- Tino

* I tend not to use attributes like "swifty"… most of the time, it just means "I think this is the right choice"

private(scope) decl

Where scope is optional and defaults to full private. Can take "file" and "type" values. I.e:

private (file) var i = 1
private func a()
private (type) func b()

This way we can have a very fine grained access levels and maintain a better structure. Who knows maybe in Swift 5 there will be need for more.

There might be submodules someday, which could be incorporated as well:
private(submodule)
or even
private(module: "MyLib", file: "Helpers.swift", type: Foo)
for a declaration that can be accessed from several locations.

We could even go further with
overridable(module) callable(subclass) func foo()

The question for me is how much complexity should be accepted as a tradeoff for increased expressiveness?
"private, internal, public" was quite simple, but the current system is already quite complicated, and it doesn't scale well.

The whole topic has come up several times, and I keep referring to file access rights in Unix… so afaics, we are basically talking about ACLs for source.

- Tino

Hi,

···

Am 2016-12-01 11:08, schrieb Álvaro Monteiro via swift-evolution:

- Typeprivate would allow to abandon the odd fileprivate. Access level
would be constrained to swift constructs (structs, classes and
extensions) and not to a compiler artifact (file).

Files are not compiler artifacts but design artifacts.
They group related stuff which was designed together and which should be reviewed together.

I really like `fileprivate` and how Swift currently handles access control.

--
Martin

@Adrian

I do agree with you when you state "But instead of introducing even more
access modifiers we probably should fix some of the existing ones". As I
mentioned in the proposal, typeprivate level could somehow
replace fileprivate which, in my opinion, falls short in promoting good
design practices. While I'm sure that's not it's intent, it surely creates
conditions for some dodgy patterns to emerge.

Also, would you be so kind to provide an example where typepublic would be
useful? Maybe you're thinking of allowing member access to subclasses?
Would that fall into a possible "protected" realm?

I agree we should handle protocol access control as well. In fact, I
believe protocols in general should be subject of focus if we're to promote
a protocol oriented programming environment. I believe there's some aspects
within protocol usage which also lack robustness which lead, for instance,
to type erasure solutions, which in my opinion feel like some somehow hacky.
Still, I believe there's so much we can add to protocol access control
level, one can actually build a proposal out of it (I'd gladly take part of
this discussion as well!), otherwise we'd be adding so much more to this
proposal's intent than what it's essence demands: a way to access private
members on extensions placed on separate files.

@Rien

"And the funny thing is, we don’t actually _need_ access control levels."
I tend do disagree. I believe we do profit from access control levels in
many many ways. One does profit from clearer and safer API communication. I
assume you consider that's vital as well since you do suggest a finer
grained list of access control levels.

"I consider it dangerous by default to open up a scope just because another
class needs occasional".
Couldn't agree more!

Best,
Gonçalo

···

2016-12-02 10:43 GMT+00:00 Adrian Zubarev via swift-evolution < swift-evolution@swift.org>:

There is some really deep talk going on here again. But instead of
introducing even more access modifiers we probably should fix some of the
existing ones.

Don’t get me wrong, I understand what the authors of the proposal are
trying to introduce to the language, but even if such a proposal would be
accepted, there will be people who would beg for typepublic access
modifier.

I tried to get some attention from the community after we introduced open
to the language, because we literally created an inconsistent area for
protocols.

Now we have open vs public classes, where open means you can subclass
your type from module A in module B, and public prevents this.

What’s up with protocols?

(protocol) conforming == abstract subtyping (classes)

Fixing this area would prevent the API user from using protocols which are
public but not meant to be used there (at least not to be conformed to),
because there was some implementation artifact that prevented the framework
author from hiding such a protocol.

Something like “hands off from _SomeName protocols” could be enforced by
the language rather than some convention, which some API users might not
even read.

That said, some hacks like this should be prevented:

struct A : _ExpressibleByBuiltinIntegerLiteral {
    init(_builtinIntegerLiteral value: _MaxBuiltinIntegerType) {}
}

struct B : ExpressibleByIntegerLiteral {
    init(integerLiteral value: A) {
        print(type(of: value))
    }
}

let b: B = 42 // prints "A"

We introduced an exclusive access modifier for classes which is really odd
to be honest. We should extend it to protocols as well.

In Module A:

   - open protocol X - can be conformed to from module B
   - public protocol Y - cannot be confronted to from module B, but
   instead might be used as an interface

--
Adrian Zubarev
Sent with Airmail

Am 2. Dezember 2016 um 09:56:49, Rien via swift-evolution (
swift-evolution@swift.org) schrieb:

And the funny thing is, we don’t actually _need_ access control levels.

The only purpose of access control is to enhance security/reliability by
imposing restrictions on other programmers (API users).

It seems to me that in almost all discussions the arguments are mostly
backwards: i.e. formulated from the perspective of the API users. Maybe
because just about all programmers are API users of the OS-API? Anyway…

What I would like to see is a complete overhaul of the access control and
rewrite it entirely from the perspective of the API provider.
I.e. give a more fine grained control to the API writer in the sense that
he can specify exactly which other piece of code has access. I consider it
dangerous by default to open up a scope just because another class needs
occasional access. (i.e. give -for example- module access just because
there is 1 other class in the module that needs that access. Inadvertently
opening up access to all other classes in that module.)

An access control list could do just that. Perhaps something like:

access(type, MyFriendClass(get))

The above would provide access to the entire type (but not any children)
and read-only from MyFriendClass.

A quick -off the cuff- list of access levels:

local: access only to local scope (default)
type: Only the type in which it is defined (no children)
child: The type and its children
<type-name>: Access is granted to the type named
file: Access is limited to this file only
<file-name>: Access is granted to the named file
module: Access is granted to the entire module
<module-name>: Access is granted to the module with the given name
public: Access is granted to everybody

Further access specification could be made possible through the use of the
dot-notation:

<type-name>.<function-name>
<file-name>.<class-name | function-name>
<module-name>.<class-name>.<function-name>

Read/write control through a parameter passing notation:

<type-name>.<function-name>([[get],][set])

Examples:

access(type) var count: Int // entire type can read/write
access(type(get), type.incrementer) var count: Int // Entire type can
read, only the incrementer function has read/write
access(module, FriendType, public(get)) var count: Int // Entire module
can read/write, FriendType can read/write, others can only read

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: Swiftrien (Rien) · GitHub
Project: http://swiftfire.nl

> On 01 Dec 2016, at 21:38, Brandon Knope via swift-evolution < > swift-evolution@swift.org> wrote:
>
> Is anyone starting to think the current access control model will become
more burdensome over time?
>
> People will want to add and subtract to it for years to come...which
tells me it's not very flexible. I'm beginning to feel like it is an old
style model trying to fit into a modern language.
>
> For example, fileprivate and private encourage stuffing a lot of code
into one file just to use that access control level. If you want to break
this into more manageable chunks you have to make it internal or move it
into a new module which is very complicated to do in Xcode (I.e requiring a
new target like a framework).
>
> This keeps leading me back to having submodules or creating modules on
demand. I think that would open up this system to great complexity.
>
> Want to keep something private to a specific class but private to
anything outside of it? Make it internal to the same "submodule".
>
> I think we could keep tacking on things to access control, but I don't
think it is really solving everyone's needs. I think a more flexible system
would allow people to adapt it to their needs instead of structuring
everything around a rigid system that forces you to do it swift's way.
>
> On Nov 29, 2016, at 10:24 AM, Gonçalo Alvarez Peixoto via > swift-evolution <swift-evolution@swift.org> wrote:
>
>> Hello, everyone!
>>
>> I would like to introduce a new proposal to swift evolution, but first
I would love to run it by all of you so I get everyone's feedback and
enrich it.
>>
>> This proposal consists of introducing a new typeprivate access control
level which allows for members to be accessed in all extensions of a given
type, whether lying within or in another file.
>>
>> You'll find the proposal draft in:
>> GitHub - goncaloalvarez/swift-evolution: This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
proposals/NNNN-introduce-typeprivate-access-control-level.md
>>
>> Thanks in advance for taking the time to evaluate the proposal.
>>
>> Best regards,
>> Gonçalo
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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

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

Folks, it really gets intense (and I really like it, while not being
satisfied with current system) and looks like reconsidering from scratch.
To make the further communication productive let's first bring the bigger
picture into context.

Let's bring some history first.

Initially Swift adapted the model from Obj-C. The main argument from Apple
was compatibility and "it's not bad, just different; try to adapt". There
was a blog article about it on Apple's site. Sorry don't have a link.

Well, anyways, with Swift 3 it no longer is as simple as it is in Obj-C.
New modifiers were introduced by request. I feel it's good and means
everybody agrees Obj-C modifiers aren't sufficient for Swift. What I mean,
initial arguments should apply no more and I hope Apple will not be too
rigid with current status.

What I mean, though, the new introductions of access modifiers feel quite
some "patchy".

Let's bring the discussion to why we need access control into the first
place. As for me it is:
1. Possibility to provide a clean, safe API from middleware (frameworks)
2. While working as a team on a single project, restrict others from misuse
of your APIs.

The other breakdown is what types of APIs we might have:
1. Simple "allocate and use"
2. APIs that require some kind of inheritance, protocol implementations,
overriding, etc.

I'm not pretending these lists are complete, so please feel free to add
your use cases.

As a framework developer I personally suffer quite some from inability to
have protected (or any alternative) methods in protocols. It comes from
absence of multiple inheritance (which I'm completely fine with) and
inability to fully replace it with protocols.

One of the simple examples would be: you need an API that requires
overriding? Make it accessible for ancestors only (even in protocols).
Despite the argument "ancestors can open it to public" (there are a lot of
dangerous things to do) it makes the API much more clean and hides
implementation complexity. Otherwise you just have to explain it in the doc
"please don't call this method, it's an internal" which feels wrong.

So, what I suggest:
1. Keep public/open which is cool
2. Add protected which should solve the inheritance issue
3. Add "inner" which is a bit wider than protected and allows to access
members from extension
4. Keep internal, but make it an "additional marker" which keeps anything
from being visible outside of the module. I mean like a member can be at
the same time protected and internal
5. Apply the very same thing to protocols (I know it's controversial; still
I believe the language should be consistent and solid. The same rules
should apply everywhere). It will add more flexibility for API devs (keep
in mind we don't have other way of multiple inheritance)
6. Please add your use cases

It is not a replacement of proposal with fine grained tunable custom
modifiers, but rather a try to rethink from scratch what we need
considering we are already far from the initial concept.

···

On Fri, 2 Dec 2016 at 13:36 Gonçalo Alvarez Peixoto via swift-evolution < swift-evolution@swift.org> wrote:

@Adrian

I do agree with you when you state "But instead of introducing even more
access modifiers we probably should fix some of the existing ones". As I
mentioned in the proposal, typeprivate level could somehow
replace fileprivate which, in my opinion, falls short in promoting good
design practices. While I'm sure that's not it's intent, it surely creates
conditions for some dodgy patterns to emerge.

Also, would you be so kind to provide an example where typepublic would be
useful? Maybe you're thinking of allowing member access to subclasses?
Would that fall into a possible "protected" realm?

I agree we should handle protocol access control as well. In fact, I
believe protocols in general should be subject of focus if we're to promote
a protocol oriented programming environment. I believe there's some aspects
within protocol usage which also lack robustness which lead, for instance,
to type erasure solutions, which in my opinion feel like some somehow hacky.
Still, I believe there's so much we can add to protocol access control
level, one can actually build a proposal out of it (I'd gladly take part of
this discussion as well!), otherwise we'd be adding so much more to this
proposal's intent than what it's essence demands: a way to access private
members on extensions placed on separate files.

@Rien

"And the funny thing is, we don’t actually _need_ access control levels."
I tend do disagree. I believe we do profit from access control levels in
many many ways. One does profit from clearer and safer API communication. I
assume you consider that's vital as well since you do suggest a finer
grained list of access control levels.

"I consider it dangerous by default to open up a scope just because
another class needs occasional".
Couldn't agree more!

Best,
Gonçalo

2016-12-02 10:43 GMT+00:00 Adrian Zubarev via swift-evolution <
swift-evolution@swift.org>:

There is some really deep talk going on here again. But instead of
introducing even more access modifiers we probably should fix some of the
existing ones.

Don’t get me wrong, I understand what the authors of the proposal are
trying to introduce to the language, but even if such a proposal would be
accepted, there will be people who would beg for typepublic access
modifier.

I tried to get some attention from the community after we introduced open
to the language, because we literally created an inconsistent area for
protocols.

Now we have open vs public classes, where open means you can subclass
your type from module A in module B, and public prevents this.

What’s up with protocols?

(protocol) conforming == abstract subtyping (classes)

Fixing this area would prevent the API user from using protocols which are
public but not meant to be used there (at least not to be conformed to),
because there was some implementation artifact that prevented the framework
author from hiding such a protocol.

Something like “hands off from _SomeName protocols” could be enforced by
the language rather than some convention, which some API users might not
even read.

That said, some hacks like this should be prevented:

struct A : _ExpressibleByBuiltinIntegerLiteral {
    init(_builtinIntegerLiteral value: _MaxBuiltinIntegerType) {}
}

struct B : ExpressibleByIntegerLiteral {
    init(integerLiteral value: A) {
        print(type(of: value))
    }
}

let b: B = 42 // prints "A"

We introduced an exclusive access modifier for classes which is really odd
to be honest. We should extend it to protocols as well.

In Module A:

   - open protocol X - can be conformed to from module B
   - public protocol Y - cannot be confronted to from module B, but
   instead might be used as an interface

--
Adrian Zubarev
Sent with Airmail

Am 2. Dezember 2016 um 09:56:49, Rien via swift-evolution (
swift-evolution@swift.org) schrieb:

And the funny thing is, we don’t actually _need_ access control levels.

The only purpose of access control is to enhance security/reliability by
imposing restrictions on other programmers (API users).

It seems to me that in almost all discussions the arguments are mostly
backwards: i.e. formulated from the perspective of the API users. Maybe
because just about all programmers are API users of the OS-API? Anyway…

What I would like to see is a complete overhaul of the access control and
rewrite it entirely from the perspective of the API provider.
I.e. give a more fine grained control to the API writer in the sense that
he can specify exactly which other piece of code has access. I consider it
dangerous by default to open up a scope just because another class needs
occasional access. (i.e. give -for example- module access just because
there is 1 other class in the module that needs that access. Inadvertently
opening up access to all other classes in that module.)

An access control list could do just that. Perhaps something like:

access(type, MyFriendClass(get))

The above would provide access to the entire type (but not any children)
and read-only from MyFriendClass.

A quick -off the cuff- list of access levels:

local: access only to local scope (default)
type: Only the type in which it is defined (no children)
child: The type and its children
<type-name>: Access is granted to the type named
file: Access is limited to this file only
<file-name>: Access is granted to the named file
module: Access is granted to the entire module
<module-name>: Access is granted to the module with the given name
public: Access is granted to everybody

Further access specification could be made possible through the use of the
dot-notation:

<type-name>.<function-name>
<file-name>.<class-name | function-name>
<module-name>.<class-name>.<function-name>

Read/write control through a parameter passing notation:

<type-name>.<function-name>([[get],][set])

Examples:

access(type) var count: Int // entire type can read/write
access(type(get), type.incrementer) var count: Int // Entire type can
read, only the incrementer function has read/write
access(module, FriendType, public(get)) var count: Int // Entire module
can read/write, FriendType can read/write, others can only read

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: Swiftrien (Rien) · GitHub
Project: http://swiftfire.nl

> On 01 Dec 2016, at 21:38, Brandon Knope via swift-evolution < > swift-evolution@swift.org> wrote:
>
> Is anyone starting to think the current access control model will become
more burdensome over time?
>
> People will want to add and subtract to it for years to come...which
tells me it's not very flexible. I'm beginning to feel like it is an old
style model trying to fit into a modern language.
>
> For example, fileprivate and private encourage stuffing a lot of code
into one file just to use that access control level. If you want to break
this into more manageable chunks you have to make it internal or move it
into a new module which is very complicated to do in Xcode (I.e requiring a
new target like a framework).
>
> This keeps leading me back to having submodules or creating modules on
demand. I think that would open up this system to great complexity.
>
> Want to keep something private to a specific class but private to
anything outside of it? Make it internal to the same "submodule".
>
> I think we could keep tacking on things to access control, but I don't
think it is really solving everyone's needs. I think a more flexible system
would allow people to adapt it to their needs instead of structuring
everything around a rigid system that forces you to do it swift's way.
>
> On Nov 29, 2016, at 10:24 AM, Gonçalo Alvarez Peixoto via > swift-evolution <swift-evolution@swift.org> wrote:
>
>> Hello, everyone!
>>
>> I would like to introduce a new proposal to swift evolution, but first
I would love to run it by all of you so I get everyone's feedback and
enrich it.
>>
>> This proposal consists of introducing a new typeprivate access control
level which allows for members to be accessed in all extensions of a given
type, whether lying within or in another file.
>>
>> You'll find the proposal draft in:
>>
https://github.com/goncaloalvarez/swift-evolution/blob/master/proposals/NNNN-introduce-typeprivate-access-control-level.md
>>
>> Thanks in advance for taking the time to evaluate the proposal.
>>
>> Best regards,
>> Gonçalo
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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

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

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

IMO there is no need for something like typepublic to even exist, but in theory it would be something like where a subclass has more visibility of the internal stuff of its super type. I’m just saying that someone will want this, because that person might thing that typepublic and typeprivate would be consistent.

In general I’m for anything that adds flexibility, but flexibility means also more complexity.

The thing is, typeprivate cannot replace fileprivate, just because fileprivate adds internal visibility to other scopes inside the same file and does not restrict it to the same type. And I really love that aspect of Swift. :)

It already has been discussed thousands of times but I cannot resist and also state my preference to something like:

private // like `private(scope)`
private(file) // like `internal(file)`
private(type) // in your case
This is a POP language right? So lets focus on fixing and improving protocols. :) We should start with open/public protocol.

PS: I also cannot wait for existentials to drop typealias ProtoB = Any<Proto> where Proto.A == B where B comes from a generic parameter list and A is an associated type.

···

--
Adrian Zubarev
Sent with Airmail

Am 2. Dezember 2016 um 12:36:45, Gonçalo Alvarez Peixoto (goncalo.alvarezpeixoto@gmail.com) schrieb:

Also, would you be so kind to provide an example where typepublic would be useful? Maybe you're thinking of allowing member access to subclasses? Would that fall into a possible "protected" realm?

Assuming that this is true (I tend to agree), why do we need any extra syntax at all? Couldn’t we just make everything accessible to extensions?

Alternatively, if we do want to hide some things from extensions by default (to prevent accidental use), I had a proposal a while back which had a very simple way to control what is shared. Basically, you could have a special import statement which allows you to extend knowledge/access of the hidden parts to another file (you were also able to limit the range of this ability if needed).

Most of the feedback at the time seemed to want submodules instead, but I still think there will still eventually be a need for something like this. As others have mentioned, the current system is inflexible (especially to the common use cases), causing people to keep requesting additions… and forcing them to give wider access than they want to in the mean time. Even if we have sub-modules, someone will want to share with a specific other sub-module, but not make things public.

···

On Dec 1, 2016, at 1:31 AM, Tino Heth via swift-evolution <swift-evolution@swift.org> wrote:

It also means that anybody who want to access your private var will just have to write an extension to expose it.

imho this is wrong thinking:
Access control is no tool to offer real "protection" — it can't stop someone who wants to break a system.
Especially in the world of open source, it is merely an advice from the author not to do certain things.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

@Tino: Regarding the following statement - "Even if there was a change of mind, fileprivate is still needed for essential things like implementing Equatable.”
How exactly is that so? Am I missing something?

> - Typeprivate would allow to abandon the odd fileprivate. Access level would be constrained to swift constructs (structs, classes and extensions) and not to a compiler artifact (file).
Actually, imho fileprivate isn't odd or "unswift"* — it's one of the three original levels, which all rely on the layout of the filesystem ("same file?" and "same folder/module?").
Even if there was a change of mind, fileprivate is still needed for essential things like implementing Equatable.

But I'm not arguing against typeprivate at all (nor against access control in general ;-)

- Tino

* I tend not to use attributes like "swifty"… most of the time, it just means "I think this is the right choice"

João David
iOS Developer / Researcher
CIAFEL<https://ciafel.fade.up.pt/&gt; - University of Porto
Rua Dr Plácido Costa, 91
4200-450 Porto
Portugal

+351 93 363 19 27 | Skype: joaotdavid
joaodav@fade.up.pt<mailto:joaodav@fade.up.pt>

Please visit the iSOPARC<http://ciafel.fade.up.pt/isoparc&gt; and iSOFIT<http://ciafel.fade.up.pt/isofit&gt; for iPad application website.

···

--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.

@Tino: Regarding the following statement - "Even if there was a change of mind, fileprivate is still needed for essential things like implementing Equatable.”
How exactly is that so? Am I missing something?

> - Typeprivate would allow to abandon the odd fileprivate. Access level would be constrained to swift constructs (structs, classes and extensions) and not to a compiler artifact (file).
Actually, imho fileprivate isn't odd or "unswift"* — it's one of the three original levels, which all rely on the layout of the filesystem ("same file?" and "same folder/module?").
Even if there was a change of mind, fileprivate is still needed for essential things like implementing Equatable.

But I'm not arguing against typeprivate at all (nor against access control in general ;-)

- Tino

* I tend not to use attributes like "swifty"… most of the time, it just means "I think this is the right choice"

João David
iOS Software Architect
LinkedIn <http://pt.linkedin.com/in/joaotdavid&gt; | +351 933631927 | Skype: joaotdavid

Please visit the iSOPARC <http://ciafel.fade.up.pt/isoparc&gt; and iSOFIT <http://ciafel.fade.up.pt/isofit&gt; for iPad application website.

@Aron, I did take a look at that document while developing the proposal. As
you stated, it's a little old, however the principles of access control and
their purpose remain pretty much the same.

".keep private details of a class hidden from the rest of the app
.keep interna details of a framework hidden from the client app"

Both these rules still get respected with the introduction of a new level
of access control. *typeprivate *would not allow for member access within
any other then the *type* itself.

@Jay, while I do appreciate your idea, I'm afraid this proposal aims at
something a lot less complex. One may argue the changes in Swift's design
to accommodate it may facilitate and open door to more complex changes like
the one you suggest, still I believe those changes are most welcome in the
name creating a safer and easier to handle access control policy. This
proposal aims only at opening access to private members to any extension
over that type.

···

2016-12-01 17:47 GMT+00:00 Martin Waitz via swift-evolution < swift-evolution@swift.org>:

Hi,

Am 2016-12-01 11:08, schrieb Álvaro Monteiro via swift-evolution:
> - Typeprivate would allow to abandon the odd fileprivate. Access level
> would be constrained to swift constructs (structs, classes and
> extensions) and not to a compiler artifact (file).

Files are not compiler artifacts but design artifacts.
They group related stuff which was designed together and which should be
reviewed together.

I really like `fileprivate` and how Swift currently handles access control.

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

I agree that there is a major problem with “subclasses must override these methods”. We have no capability to describe this in Swift, and frankly, it feels like something that ought to be enforced. It’s almost like we were really asked to conform to a protocol, but the protocol was a class. Maybe this is an artifact from previous Obj-C development? I.E. if it were designed in scratch in Swift it wouldn’t be a class with required overrides, but a protocol where every other method already had a default implementation?

···

One of the simple examples would be: you need an API that requires overriding? Make it accessible for ancestors only (even in protocols). Despite the argument "ancestors can open it to public" (there are a lot of dangerous things to do) it makes the API much more clean and hides implementation complexity. Otherwise you just have to explain it in the doc "please don't call this method, it's an internal" which feels wrong.

"The thing is, typeprivate cannot replace fileprivate, just because
fileprivate adds internal visibility to other scopes inside the same file
and does not restrict it to the same type. And I really love that aspect of
Swift. :)"

While I do see the advantages in exposing members within the same file, we
must agree that can promote somehow odd patterns of chunking code into the
same file. As I said before, that's definitely not the intent, however
there's no mechanism of preventing it. I believe typeprivate would
definitely help in scoping and improving code readability while we're at it!

private // like `private(scope)`
private(file) // like `internal(file)`
private(type) // in your case

I must say I am very fond of this solution as well. It clearly conveys the
idea.

"PS: I also cannot wait for existentials to drop typealias ProtoB =
Any<Proto> where Proto.A == B where B comes from a generic parameter list
and A is an associated type."
Same here!

Best,
Gonçalo

···

2016-12-02 11:58 GMT+00:00 Adrian Zubarev <adrian.zubarev@devandartist.com>:

IMO there is no need for something like typepublic to even exist, but in
theory it would be something like where a subclass has more visibility of
the internal stuff of its super type. I’m just saying that someone will
want this, because that person might thing that typepublic and typeprivate
would be consistent.

In general I’m for anything that adds flexibility, but flexibility means
also more complexity.

The thing is, typeprivate cannot replace fileprivate, just because
fileprivate adds internal visibility to other scopes inside the same file
and does not restrict it to the same type. And I really love that aspect of
Swift. :)

It already has been discussed thousands of times but I cannot resist and
also state my preference to something like:

private // like `private(scope)`
private(file) // like `internal(file)`
private(type) // in your case

------------------------------

This is a POP language right? So lets focus on fixing and improving
protocols. :) We should start with open/public protocol.
------------------------------

PS: I also cannot wait for existentials to drop typealias ProtoB =
Any<Proto> where Proto.A == B where B comes from a generic parameter list
and A is an associated type.

--
Adrian Zubarev
Sent with Airmail

Am 2. Dezember 2016 um 12:36:45, Gonçalo Alvarez Peixoto (
goncalo.alvarezpeixoto@gmail.com) schrieb:

Also, would you be so kind to provide an example where typepublic would be
useful? Maybe you're thinking of allowing member access to subclasses?
Would that fall into a possible "protected" realm?

I agree that there is a major problem with “subclasses must override these methods”. We have no capability to describe this in Swift, and frankly, it feels like something that ought to be enforced. It’s almost like we were really asked to conform to a protocol, but the protocol was a class. Maybe this is an artifact from previous Obj-C development? I.E. if it were designed in scratch in Swift it wouldn’t be a class with required overrides, but a protocol where every other method already had a default implementation?

In Java and C++ you would implement this with an abstract method. i.e. a method that has a declaration and no body. A proposal was made to introduce these but was deferred. Reading the rationale for the decision, it looks like the dev team were generally favourable but didn’t have time to do the implementation, plus there were some details that needed to be nailed down.

···

On 2 Dec 2016, at 14:07, Benjamin Spratling via swift-evolution <swift-evolution@swift.org> wrote:

One of the simple examples would be: you need an API that requires overriding? Make it accessible for ancestors only (even in protocols). Despite the argument "ancestors can open it to public" (there are a lot of dangerous things to do) it makes the API much more clean and hides implementation complexity. Otherwise you just have to explain it in the doc "please don't call this method, it's an internal" which feels wrong.

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

Well, anyways, with Swift 3 it no longer is as simple as it is in Obj-C. New modifiers were introduced by request. I feel it's good and means everybody agrees Obj-C modifiers aren't sufficient for Swift.

Well… no ;-)
I'm not sure if there is a single thing in the universe where really everybody agrees on — right now, there is nothing more than a small group that has a vague agreement that there is room for improvement with the current access levels; most Swift users aren't even aware of this discussion at all (and most likely never will be ;-)
[In situations like this, I really dislike the restrictions of this medium… with something like a Wiki, it would be much easier to set up a table so that we could at least collect the opinions from the people discussing now.]

What I mean, initial arguments should apply no more and I hope Apple will not be too rigid with current status.

I agree on the latter — but it might be the case that fundamental changes to Swift won't be considered anymore

What I mean, though, the new introductions of access modifiers feel quite some "patchy".

Yes… but imho your suggestion which adds additional levels makes it even more patchy:
"protected" might be familiar to some developers, but "inner" is just a new magic word tacked onto the language.
For me, this is actually the worst direction to take: Adding more and more new modifiers instead of really rethinking the topic from scratch.

is a POP language right? So lets focus on fixing and improving protocols. :) We should start with open/public protocol.
No, this is not a POP language only, OOP is neither discourage nor unwelcome and it is a first class citizen.
Telling people there are better ways in some / many scenarios and that deep inheritance hierarchies are bad is not the same thing: composition as spatter was not born with Swift.

I do not want to offend, but it is getting a bit irritating that whenever someone wants to improve object oriented patterns the answer resembles a "why bother? Isn't it an unsupported feature anyway?" :P.

People want to improve POP patterns? Good, it does not and should not upset or come at the expenses of other first class features... everybody is happy then... almost :).

···

PS: I also cannot wait for existentials to drop typealias ProtoB = Any<Proto> where Proto.A == B where B comes from a generic parameter list and A is an associated type.

--
Adrian Zubarev
Sent with Airmail

Am 2. Dezember 2016 um 12:36:45, Gonçalo Alvarez Peixoto (goncalo.alvarezpeixoto@gmail.com) schrieb:

Also, would you be so kind to provide an example where typepublic would be useful? Maybe you're thinking of allowing member access to subclasses? Would that fall into a possible "protected" realm?

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

I'm not sure why that last scenario couldn't be accommodated by submodules.
Why wouldn't you put those two specific submodules in the same parent
submodule?

···

On Fri, Dec 2, 2016 at 15:35 Jonathan Hull via swift-evolution < swift-evolution@swift.org> wrote:

Assuming that this is true (I tend to agree), why do we need any extra
syntax at all? Couldn’t we just make everything accessible to extensions?

Alternatively, if we do want to hide some things from extensions by
default (to prevent accidental use), I had a proposal a while back which
had a very simple way to control what is shared. Basically, you could have
a special import statement which allows you to extend knowledge/access of
the hidden parts to another file (you were also able to limit the range of
this ability if needed).

Most of the feedback at the time seemed to want submodules instead, but I
still think there will still eventually be a need for something like this.
As others have mentioned, the current system is inflexible (especially to
the common use cases), causing people to keep requesting additions… and
forcing them to give wider access than they want to in the mean time. Even
if we have sub-modules, someone will want to share with a specific other
sub-module, but not make things public.

On Dec 1, 2016, at 1:31 AM, Tino Heth via swift-evolution < > swift-evolution@swift.org> wrote:

It also means that anybody who want to access your private var will just
have to write an extension to expose it.

imho this is wrong thinking:
Access control is no tool to offer real "protection" — it can't stop
someone who wants to break a system.
Especially in the world of open source, it is merely an advice from the
author not to do certain things.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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

typeprivate is confusing. Would we allow access to extension in the same file, in the same module, everywhere ?

If a ‘typeprivate’ is accessible anywhere, it look more like a public var than a private one.

Maybe we should also introduce a typeinternal and typepublic modifier in such case to explicitly define who can access the var.

···

Le 1 déc. 2016 à 18:54, Gonçalo Alvarez Peixoto via swift-evolution <swift-evolution@swift.org> a écrit :

@Aron, I did take a look at that document while developing the proposal. As you stated, it's a little old, however the principles of access control and their purpose remain pretty much the same.

".keep private details of a class hidden from the rest of the app
.keep interna details of a framework hidden from the client app"

Both these rules still get respected with the introduction of a new level of access control. typeprivate would not allow for member access within any other then the type itself.

@Tino: Regarding the following statement - "Even if there was a change of mind, fileprivate is still needed for essential things like implementing Equatable.”
How exactly is that so? Am I missing something?

class Eq: Equatable {
  private var value = 0
}

func ==(lhs: Eq, rhs: Eq) -> Bool {
  return lhs.value == rhs.value
}

This doesn't compile — but it works fine when you declare value to be fileprivate.
There are other cases where fileprivate is the best choice, but this is quite common (of course, it's always possible to use internal instead… but we could as well remove all levels and keep nothing but public)

We really need a place for discussions that apply to deferred issues. Some
previous suggestions from myself and others have been:

   - A Discourse board
   - Tag emails [4.1] (or something else) if they are known to relate to
   deferred proposals.
   - A ‘deferred’ directory for complete proposals in the swift-evolution
   repo to give deferred topics more visibility and a central place for
   discussion around

Until then, I’ll just pile on…

I’ve previously suggested an idea similar to this where a type can define
its own named access groups and then use them for access control. I didn’t
flesh it out in full (as this is a deferred topic anyway) but the concept
was something along these lines…

A class might define a group called Subclasses and that would then be
available to use on properties/functions like access(Subclasses) and
another group called Friends used with access(Friends). This would give the
most flexibility and allow a potentially complex combination of access
controls to be moved elsewhere and re-used in the function definitions that
use it.

Here’s some throw-away syntax to demonstrate a few possibilities:

accessgroup Subclasses {
    type: Self
    extensions: true // Extensions of types matching 'type' can access
    file: true // Anything in this file can access
}accessgroup Friends {
    type: UIView, Bob!, Jeff // Any UIView or Jeff type (including
subtypes) and Bob (not including subtypes) can access.
}

This would be defined inside a type - so named groups are type-specific.
This structure can then be used to define whatever type of access we decide
would be useful - access by named modules / submodules? access by direct
subtypes only? access only from specific functions? access from
protocol-conforming types - only the functions of that protocol or any
function in the conforming class? etc.

You can go wild of course with what can be defined in an accessgroup - the
idea here is that we start simple and then discussions about adding other
access control features become a lot easier. We could even go so far as to
say that existing private internal etc. keywords are synonyms for
access(private), access(internal) where private and internal are
always-defined (reserved) accessgroup names.