<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">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. <div class=""><br class=""></div><div class="">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:</div><div class=""><br class=""></div><div class="">private (file scope)</div><div class="">internal (module scope)</div><div class="">protected (subclass scope)<br class=""><div class="">public</div><div class=""><br class=""></div><div class="">Best,</div><div class=""><br class=""></div><div class=""> Taras</div><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 24 Jan 2016, at 09:44, Thorsten Seitz via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span></div><div class=""><div class=""><blockquote type="cite" class=""><div class="">Am 23.01.2016 um 16:56 schrieb Ilya Belenkiy via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>>:</div><br class="Apple-interchange-newline"><div class=""><div class="">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.<br class=""><br class="">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). </div></div></blockquote><div class=""><br class=""></div><div 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).<div class=""><br class=""></div></div><br class=""><blockquote type="cite" class=""><div class=""><div class="">It’s also impossible to hide APIs that are meant only for customization points of subclasses.<br class=""></div></div></blockquote><div class=""><br class=""></div><div class=""><div class="">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. </div><div class=""><br class=""></div><div class="">Example (shortened and simplified to just show the relevant parts):</div><div class=""><br class=""></div><div class=""><font face="Menlo" class="">public protocol StandardGraphTraversal {</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>// push() and pop() are implementation details and not part of the API</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>protected func push(vertex: Vertex)</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>protected func pop() -> Vertex?</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>public func next() -> Vertex?</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">public extension StandardGraphTraversal {</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>// leaving out things like visitor callbacks and coloring the visited vertices</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>public func next() -> Vertex? {</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>guard let source = pop() else {<span class="Apple-tab-span" style="white-space: pre;">                </span>// using pop() here</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">                        </span>return nil</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>}</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>for target in graph.neighborsOf(source) {</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">                        </span>if shouldFollowVertex(target) {</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">                                </span>push(vertex)<span class="Apple-tab-span" style="white-space: pre;">                </span>// using push() here</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">                        </span>}</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">                </span>}</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">// supplying the implementation detail: using a queue results in breadth first traversal</font></div><div class=""><font face="Menlo" class="">public struct BreadthFirstTraversal : StandardGraphTraversal {</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>var queue: Queue<Vertex> = Queue()</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>protected func push(vertex: Vertex) { return queue.push(vertex) }</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>protected func pop() -> Vertex? { return queue.pop() }</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">// supplying the implementation detail: using a stack results in depth first traversal</font></div><div class=""><font face="Menlo" class="">public struct DepthFirstTraversal : StandardGraphTraversal {</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>var stack: Stack<Vertex> = Stack()</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>protected func push(vertex: Vertex) { return stack.push(vertex) }</font></div><div class=""><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>protected func pop() -> Vertex? { return stack.pop() }</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span></div><div class=""><br class=""></div><div class="">Currently I cannot express that in Swift and have to make push() and pop() public :-(</div><div class=""><br class=""></div><div class="">(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).</div><div class=""><br class=""></div></div><br class=""><blockquote type="cite" class=""><div class=""><div class="">.NET has a good solution that respects the OOP terminology and deals with accessibility in modules and at the API level:<br class=""><a href="https://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx" class="">https://msdn.microsoft.com/en-us/library/wxh6fsc7.aspx</a></div></div></blockquote><div class=""><br class=""></div><div class="">`public` and `internal` seem to be quite the same as in Swift.</div><div class="">`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.</div><div class="">`protected` is what I’m missing as well</div><div class="">`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.</div><div class=""><br class=""></div><div class="">In short the only thing which is missing IMO is `protected`.</div><div class=""><br class=""></div><div class="">-Thorsten</div></div><br class=""></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></div></body></html>