Band-Aids: Swift, fileprivate, and #169

A bit of a rant…

Well… I was pretty disappointed that proposal #159 – Fix Private Access Levels was voted down. But when #169 – Improve Interaction Between Private Declarations an Extensions was approved… seriously?

Why? Why another band-aid? Why another special case rule that I need to learn about? Why introduce more inconsistency in the language?

I just cannot get behind a change where I need to explain to someone why this won’t work:


struct A {
private var foo: Int = 10
}
extension A {
func bar() -> Int {
return self.foo // this will work after #169
}
}
class C {
private var foo: Int = 10
}
class D: C {
func bar() -> Int {
return self.foo. // this will be a compiler error after #169 still
}
}

view raw

access.swift

hosted with ❤ by GitHub

Or why if you want to move an extension from one file to another, you need to change from “private” to “internal“.

See, access control is still deficient for proper modeling if we revert back to Swift v2’s model, but at least there were no special rules to consider.

“Well, you see, private only allows access to those private bits if you’re in the same file.”

“Oh, well, then what does fileprivate do?”

“Well… it allows you to access that from anywhere within the file.”

“Wait, so what’s the difference?”

“You see, private allows only the extensions to see, but not everything else like other types or free functions.”

“Oh, cool, so I’ll just use that to poke into the private stuff in this class I’m subclassing too…”

“Um, actually… you can’t do that.”

“I thought extensions…”

“Right, subclassing isn’t an extension.”

“Ok. So how do I make those private bits only available to my subclasses in this file and not the other functions and types?”

“You can’t.”

“Wait, what? So the private keyword only has this special meaning in the context of protocol extension?”

“Yes.”

Good times.

P.S. Don’t forget about the already existing special case for private on internal types… 🙄

 

Band-Aids: Swift, fileprivate, and #169