[swift-evolution] access control proposal
Drew Crawford
drew at sealedabstract.com
Thu Dec 10 12:56:22 CST 2015
The discussion so far seems to be between folks who think the existing model is obviously complete vs folks who think that it obviously isn’t, but there isn’t a lot of talk about the specific motivation for the feature.
I know a new access control modifier *looks like* a bell/whistle, but I believe *in practice* it is a *safety* feature, on the level of type safety or array-out-of-bounds. This result is counterintuitive.
I’d like to present my motivation, which I think is pretty compelling. In several codebases, I have
> final private class Foo { //this class is an implementation detail of Bar and is declared ‘private'
> private var _children : [Next] = [] //access only from special queue, as required by $EXTERNAL_REQUIREMENT
> let queue: dispatch_queue_t = dispatch_queue_create(“specialQueue", DISPATCH_QUEUE_SERIAL)
> func appendChild(n: Next) {
> dispatch_sync(queue) { _children.append(n) }
> }
> }
>
> final class Bar {
> let f = Foo()
> init() {
> f.appendChild(…)
> f._children[0].baz() //whoops: race condition
> }
> }
In words, the problem here is that:
1. Foo is an implementation detail of Bar, and so Foo should be private
- Ignored:
2. Foo has its own implementation detail, _children
3. Because Foo is already private, _children cannot be “more” private
4. Thus _children must be visible at the file level
5. Since it is visible at the file level, it may be used
6. If it is used, it will most likely cause a race condition
7. Race conditions are very hard to debug and I need all the help I can get not to write them in the first place
The solutions I see for this problem are as follows:
1. This thread’s proposal (e.g., to invent a new access modifier, restricting _children to visibility below the file level)
2. Vend a framework / module just for these two classes. I present this as silly for many realistic sizes of Foo and Bar.
3. Promote Foo to internal visibility, when it is really a private implementation detail
4. What I actually do in this codelisting, which is to use underscores as a naming convention, and pray nobody on the team screws it up, because the compiler is no help.
I would like to hear from the folks who don’t see the need of another access modifier, what solution to this problem they plan to maintain in their own projects. Because this design pattern (queue-controlled ivar) is not uncommon, and the lack of a fourth access control keyword has produced real race conditions that I have spent real time debugging, that is completely avoidable via a keyword like classified/local/secret.
Drew
More information about the swift-evolution
mailing list