[swift-evolution] access control

Taras Zakharko taras.zakharko at googlemail.com
Mon Jan 25 07:13:17 CST 2016


I disagree with Ilya on his stance on ‘private’. I do understand the argumentation, but the reasoning seems overly formal to me and the classical solution (private visible only within the class) also comes with a number of drawbacks that result in things like friends declarations in C++. It is nice to have relationships between entities explicit, but one can go overboard with the rigidity. 

However, I also strongly agree with Thorsten that a subclass (but not public) visible modifier has a lot of uses. I would prefer to have four levels of access:

private (file scope)
internal (module scope)
protected (subclass scope)
public

Best,

 Taras


> On 24 Jan 2016, at 09:44, Thorsten Seitz via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 	
>> Am 23.01.2016 um 16:56 schrieb Ilya Belenkiy via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>>:
>> 
>> I hope that access control can be revisited. It is the number one complaint about Swift that I hear from experienced developers. The current solution came as a complete surprise to every ObjC developer I've talked to. The natural expectation was that a strong access control system would be part of a strong type system. I already submitted a pull request with a proposal for this after a lengthy discussion here, but so far it was ignored. I hope that this can be revisited. Even if most people who responded earlier in this list decided that they were happy with the current state, it represents a tiny fraction of people using the language, and at least all the people I talked to strongly disagree but just aren’t on the list.
>> 
>> Right now access control is file based and not API based. This is much easier to implement but useless to express that certain elements of a class are implementation details that are not meant to be used anywhere else (someone can add more code to the same file and get access to the implementation details without modifying the class).
> 
> I think the file based approach for `private` has advantages because it allows putting several things that have to know each other deeply into the same file (C++ would use friend access for that).
> 
> 
>> It’s also impossible to hide APIs that are meant only for customization points of subclasses.
> 
> Here I agree. What I am really missing is the ability to declare something „protected“ in a protocol (or class) which is not part of the public API but which I then can use in its default implementation but which has to be provided by implementors of the protocol. 
> 
> Example (shortened and simplified to just show the relevant parts):
> 
> public protocol StandardGraphTraversal {
> 	// push() and pop() are implementation details and not part of the API
> 	protected func push(vertex: Vertex)
> 	protected func pop() -> Vertex?
> 
> 	public func next() -> Vertex?
> }
> 
> public extension StandardGraphTraversal {
> 
> 	// leaving out things like visitor callbacks and coloring the visited vertices
> 	public func next() -> Vertex? {
> 		guard let source = pop() else {		// using pop() here
> 			return nil
> 		}
> 		for target in graph.neighborsOf(source) {
> 			if shouldFollowVertex(target) {
> 				push(vertex)		// using push() here
> 			}
> 		}
> 	}
> }
> 
> // supplying the implementation detail: using a queue results in breadth first traversal
> public struct BreadthFirstTraversal : StandardGraphTraversal {
> 	var queue: Queue<Vertex> = Queue()
> 
> 	protected func push(vertex: Vertex) { return queue.push(vertex) }
> 	protected func pop() -> Vertex? { return queue.pop() }
> }
> 
> // supplying the implementation detail: using a stack results in depth first traversal
> public struct DepthFirstTraversal : StandardGraphTraversal {
> 	var stack: Stack<Vertex> = Stack()
> 
> 	protected func push(vertex: Vertex) { return stack.push(vertex) }
> 	protected func pop() -> Vertex? { return stack.pop() }
> }
> 	
> 
> Currently I cannot express that in Swift and have to make push() and pop() public :-(
> 
> (Allowing `internal` in public protocols would be sufficient in my example but would not help in more general cases where the implementors would have to be provided in another module by the framework user).
> 
> 
>> .NET has a good solution that respects the OOP terminology and deals with accessibility in modules and at the API level:
>> https://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx <https://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx>
> `public` and `internal` seem to be quite the same as in Swift.
> `private` is based on the type instead of the file. I think Swift’s file based `private` is better because it allows to express the same by putting a type into its file alone and allows to create strongly interdependent types by putting them together into the same file.
> `protected` is what I’m missing as well
> `protected internal` seems to be the union of `protected` and `internal`. I think that is not needed and is probably there to allow testing for which Swift has a nicer solution with @testable imports.
> 
> In short the only thing which is missing IMO is `protected`.
> 
> -Thorsten
> 
> _______________________________________________
> 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/20160125/5a309a47/attachment.html>


More information about the swift-evolution mailing list