[swift-evolution] access control

Dave Abrahams dabrahams at apple.com
Sat Jan 23 16:43:06 CST 2016

on Sat Jan 23 2016, Ilya Belenkiy <ilya.belenkiy-AT-gmail.com> wrote:

>> Anyone who can "add more code to the same file" can just as easily modify/extend the class.  
> Yes, but with an API based access control, 

I don't know what that term means, sorry.

> anyone modifying / extending the class can instantly see the author’s
> intent from the API declaration, 

I don't see how that's different from what we have in Swift.  Private
APIs are the ones you don't want anyone to touch because they can break
your invariants.

> and the compiler can prevent *accidental* misuse. Deliberate misuse
> cannot be stopped no matter what access control is in place (as long
> as the coder can modify the code in the module). But at least with an
> API based access control, a deliberate misuse is very easy to spot
> when debugging / reviewing the code. With a file based access control,
> the only way to tell if an API is really private or can be safely used
> anywhere in the same file is to read the comments / source code. 

Seeing the keyword “private” isn't enough for you in Swift, but it is in
C++?  Why?

> And it’s much easier to miss in maintenance, debugging, or code
> reviews. The only way to make it obvious in the current model is to
> adopt a convention like _ in front of methods.

The only reason we're doing that in the standard library is that we're
currently forced to make some implementation details formally public,
and we can't use “private” because <reasons>.  If it weren't for these
limitations, we'd be very happy with “private.”  Defining one type per
file is usually a good practice anyway.

>> There's nothing about extending a class that ought to raise a red
>> flag in Swift, because it's perfectly legit to do so and use only
>> the class' public APIs.
> Unless the programmer extends a class in the same file. Then he can
> call anything marked private, and it’s impossible to tell without
> reading the code whether it violates the class invariants. 

Without prohibiting class extensions from being made in the same file
where the class is defined—a capability we want to keep available to
class authors—that will always be the case.  Therefore, you have the
same scenario as in C++: anyone who modifies the file where a class is
defined might be violating its invariants.  It's just that in C++ the
violator has to write code between a particular set of braces.  When
reviewing diffs it's very common not to have enough context to see those
braces anyway.

> There is no way to express this in Swift today. My proposal for local
> / scoped access control would solve this.
>>  we didn't do file-level access control because it was easier; we
>> did it because we thought it was a better model for Swift, where
>> types are liberally open for extension.
> That’s what I assumed until I saw someone say it in this list when
> someone else raised a similar concern. Types in C++ and C# are also
> liberally open for extension, 

Not at all in the same way.  In C++, you can't add methods to a class
outside the file where it's declared unless there's some really horrible
preprocessor stuff going on, and even then the class author would have
had to explicitly left that door open for you.


More information about the swift-evolution mailing list