[swift-evolution] private(call) and internal(call)

Félix Cloutier felixcca at yahoo.ca
Tue Jan 12 00:36:17 CST 2016


>> The reason internal or private can't be called from outside an executable is that no data about it exists in the final executable
> 
> Actually, I believe internal symbols *are* in the final executable. (If they aren't now, they certainly were for a while.)


The LLVM bitcode for internal symbols has the "hidden" visibility style <http://llvm.org/docs/LangRef.html#visibilitystyles> (you can test with swift -emit-ir). It's possible that the symbol will show up in debug executables, but the intent is to get rid of it at release.

> Le 12 janv. 2016 à 00:28:55, cocoadev at charlessoft.com a écrit :
>> The great thing about using the linker to implement access control is
>> that it can be enforced. The reason internal or private can't be
>> called from outside an executable is that no data about it exists in
>> the final executable As a matter of fact, the symbol itself might not
>> even exist in the fully optimized executable.
> 
> Access modifiers aren't just across linker boundaries. Private, private(set), and, if implemented, private(call) would help enforce boundaries between classes within a single module as well.

Currently, access modifiers *are* just across linker boundaries. The translation unit (single file) level is a linker boundary. Private is very close to C's static.

>> I also think that it's fundamentally the same as protected, because
>> nothing prevents you from sharing the logic outside. You can forward
>> the protected call to a public call, which is exactly the same as a
>> public call forwarding to a protected call in terms of encapsulation.
> 
> Um, if that's your metric, then private is fundamentally the same as internal is the same as public, and there's no such thing as access modifiers at all. *Anything* can be forwarded to a public call, whether it's private, public, internal, my proposed private(call), or protected, if it's done within the class that owns it. However, code from outside the class (or struct, or enum, or whatever) wouldn't be able to access something defined as private(call), even if it's a class and they're a subclass of it, whereas with protected, if you're a subclass it's basically open season.

They're not, because as the writer of the Swift library, *you* are in control of internal and private members. I believe that the worry has never been what you could do with your own code, but rather what others can do with your own code, and in the case of a `private(call)` member, if the person really wants that logic to be callable, they have means to do it (whereas they don't have the means to call an internal or private symbol).

The only un-abusable justification for the feature is to document that a symbol shouldn't be used directly, hence the suggestion to use documentation features to achieve that goal.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160112/305205c1/attachment.html>


More information about the swift-evolution mailing list