Swift Access Controls are like C's (and that isn't necessarily a bad thing)

Apple introduced access controls to Swift with the release of Xcode 6 Beta 4 and accompanying documentation (revision history).. The approach they have taken contrasts strongly with that taken by languages like C++, C# and Java in that the controls do not limit access based on the class hierarchy but instead limit based on the file and module.

Even variables declared private can be accessed from other classes and functions that reside within the same file. This allows properties and functions to be declared private but still accessible to free functions and operators defined particularly to operate with that class. It avoids some of the complexity that has C++ having "friend" classes and functions.

Swift Access Controls

The iBook hasn't been updated to match Beta 4 yet but The iBook was updated shortly after this post was written and the online version is updated with full access control information. I'm going to describe the effect of the different modifiers but not the way you can combine them or apply them to particular declarations. If you want those details please look at the official documentation.

internal

This is actually the default access level and means that the class/variable/type is available from all files within the same framework (or from anywhere within the application if that is what you are writing).

The C equivalent is variables and structures defined within internal project header files. Well structured C projects have normally had a header (.h) file for each source (.c) file but these header files were only meant to be imported by from within the project.

private

The most restrictive level of control limits the access to the variables/classes/types to only be accessed from within the same file.

The C equivalent would be variables and structures declared within the .c file and not exposed in any header files.

public

These are the functions/classes/types that are exposed to client libraries. Only things defined with this access modifier are available to clients of the framework. This forms the public API to your framework. Things defined as public are also pulled into a header file which is exposed and forms the interface particularly for Objective C/C code to import and access the library with.

The equivalent in C is to manually create a public header for a library exposing the public API necessary to use the library.

Where is "protected"?

There is no "protected" modifier. In Swift you get no special access to classes that you inherit from. This means that the access modifiers are not suitable or helpful for creating abstract classes. At this time (Beta 4) there is no mechanism to enforce that subclasses must implement particular methods or to prevent a class that you want to abstract from being created.

Does You Need Abstract Classes?

Discussion on the forums seems to weigh towards most people thinking that while Abstract classes may be overused in Java but they are generally a good option to have. However, this is something that I'm not yet sure about.

Most of the Apple libraries use delegates to customise behaviour without having to subclass. There are exceptions one of which was raised as an example is the UIGestureRecognizer class. As it stands Apple provides several concrete subclasses but you can actually create your own recognizer by subclassing UIGestureRecognizer. The UIGestureRecognizer already has a delegate that receives the messages but instead of subclassing I think that it could have been designed so that it required a second delegate to process the touches and respond to recognised(I'm British and I'm going to spell properly) gestures. You could still subclass UIGestureRecognizer and specialise it by fixing the recognition delegate (possibly as self) within the subclass.

The fact that you can do without abstract classes doesn't necessarily mean that you are better off without them (and this is the area where I'm not confident). Generally abstract classes mix the requirements of implementing a protocol and how it should be implemented by requiring the subclassing so I think I'm leaning towards discouraging them in Swift.

There are other mechanisms than the access controls that could be used to support Abstract classes and I don't know if Chris Lattner and the Apple team are planning to add them. Examples could be indicating with a keyword that particular methods (possibly including initialisers) must be overridden.


Update (20th August 2014) - Apple have a new blog post that responds to the requests for protected and largely dismisses them.

What Else Aren't People Happy With?

One of the issues that has been raised on the forum is that frameworks aren't the right level to break the automatic inclusion on especially since unlike in C everything is automatically imported within the framework. I'm fairly ambivalent on this. The answer might be to develop with lots of fairly small frameworks and if Apple makes it easy enough to divide the code into frameworks it might not be a problem. My iOS apps have been developed as a solo developer (I have worked on major C++ projects in the past) so I'm not sure whether this would work well or have problems. It would certainly be a change in style for most iOS projects but with the improved support for Frameworks I think that it could work really well. I would be interested to hear what others think about this and whether an intermediate module level would be worthwhile.

Is Swift and Object Oriented Language?

I might make a separate post soon to go into more details but I would describe Swift as a language that supports both Functional, Imperative and Object Oriented approaches. I think that the way the access controls are implemented is an indicator (along with others) that objects and classes are not on a pedestal over other approaches. The access control approach that they have used is one that is fully usable without objects and classes.

At the moment lots of people are writing Swift code in the same object orientated way as they wrote Objective-C code but with stricter type checking and nicer syntax. I think it will be very interesting to learn from Haskell and ML developers how to develop in other ways to fully exploit the power of Swift and how to combine them with object oriented and imperative code. I'm going to buy the Functional Programming in Swift book the objc.io guys are writing and see if it inspires me.

Summary of Open Questions on my Mind

  • Are protected methods needed?
  • Are abstract classes a good approach in Swift or are delegates a better approach?
    • Do they need language support?
  • Should code be split into small Frameworks?
    • Is there a strong need for modules or directory/group based access rather than full access across a whole Framework?
  • How do I really incorporate Functional techniques and immutable data?

If you have any answers, comments, questions feel free to comment or email me directly. My email address is on the main Human Friendly site.