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

Michel Fortin michel.fortin at michelf.ca
Tue Jan 12 16:34:04 CST 2016

> Le 12 janv. 2016 à 16:43, cocoadev at charlessoft.com a écrit :
> On 2016-01-12 13:50, Michel Fortin wrote:
>> Le 11 janv. 2016 à 19:53, Charles Srstka via swift-evolution
>> <swift-evolution at swift.org> a écrit :
>>> What do you think?
>> The idea looks good to me on the surface. But the details are awkward.
>> First, if you can't call the super implementation from an override,
>> there is no need to require that the overriding function be
>> private(call) because all it will contain is client code that can't
>> call the library's implementation. So the derived class can make the
>> function more visible by reimplementing it.
> My thinking is that if the subclass wants to make the functionality behind the method more visible, it's better to just spin it off into a separate method rather than ask callers to get used to calling a method that, according to the API contract of the superclass, is more an implementation detail than a part of the external interface.

True. In any case, this case isn't the problematic one.

>> But that's not the common case. In general you want to allow the
>> overriding function to call the super implementation. So...
>> Second, if you allow a call to the super implementation from an
>> override, then you need to make that overriding function uncallable by
>> anyone. Only the base class can call it using virtual dispatch. You
>> can't call it even from the same file, so it's *less visible than
>> private*.
>> That's a bit weird.
> It may be a bit weird, but it is what the API contract is already asking the class to do. It's just that currently, it's not enforced other than in documentation.

What I meant here is that you can't even mandate `private` at the override point because it's *less visible than private*. So writing `private` or `private(call)` at the override point is a lie. You can't define `private(call)` to mean "private access for calling this but if there is a override keyword next to it then it means less visible than private and you can't call it", that's too awkward.

I understand what the API contract is, but all I'm saying is that I wonder if there is a syntax that can express all this sanely.

> I should point out that we, essentially, already have methods like this; Swift initializers, unlike init methods in Objective-C, are similarly invisible; they cannot be called by any other code, even in the same file, unless that code is marked as a convenience initializer. Deinit, likewise, can't be called by anything except for the Swift runtime itself.

Sure, but `init` and `deinit` in Swift are function-like constructs that aren't quite functions in order to accommodate all this. Surely you don't want to go that far here.

Michel Fortin

More information about the swift-evolution mailing list