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

Reply via email to