The discussion of private/fileprivate reminded me of other access modifier
issues that have been bugging me. I agree that the old system is better, but I
am ambivalent about changing it back…
What I pretty much constantly want is an access modifier which lets me access
something from an extension (which is potentially in a different file), but
otherwise have it be private. The vast majority of my use of “fileprivate” is
so that I can access internal properties/functions from an extension (which I
am forced to place in the same file).
Access from subclasses is a larger discussion, but I run into this most often
with Structs and their extensions.
The other pieces which seem to be missing are modifiers which allow finer
grained control of how class methods are overridden and used.
It is a fairly common pattern in cocoa, for example, to have customization
point methods which are designed to be overridden, but are not supposed to be
called directly. Right now, this is enforced via documentation. One potential
solution is to have a @noExternalCall attribute which says that it can only be
called from the class/subclass/extensions… but if you think about it, this is
basically another view of the first issue. If we could mark that method as only
visible within the class/subclasses/extensions, then the behavior we want just
falls out naturally. It can’t be called externally, because no one on the
outside can see it.
I also occasionally run into this with protocols. I find that I have a
property on the protocol which is needed for default implementations, but I
really want to make it private with respect to the protocol (and its
inheritors/extensions). That is, I want the implementor of the protocol to
have visibility for that property, but not the caller of the protocol. Right
now, I have to expose it to everyone (which clutters my external API), and then
note in documentation not to call those properties.
Basically, I want to do the following:
protocol P {
hidden var a:Int
var b:Int
}
extension P {
var c:Int { return self.a + self.b}
}
struct A:P {
private var a:Int = 5 // ‘A’ must implement, but it doesn’t
have to expose it externally
var b:Int = 2
}
struct B:P{
var a:Int = 3 // ‘B’ chooses to expose, which is ok too
var b:Int = 4
}
let ans = A().c // 7
let ohNo = A().a // Error!
Basically ‘hidden’ in the protocol means that the implementor must implement
the property, but it is not required to expose it to the world. I don’t really
care whether that is spelled hidden, protected, or private, but I would use
this fairly often.
Thanks,
Jon
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution