Let's start with: I much prefer including the word 'file' in the file
access level, to not including it. The bikeshedding discussions proposed
too many permutations of 'public' 'external' 'internal' 'private' for me,
not to mention the potential additions of 'secret', 'hidden', 'closed'... I
think single-word adjectives would be nice if there was a ready hierarchy
available in English, but there isn't, and inventing one for this purpose
makes learning and readability difficult.
So, burrowing back into the bike shed...
I think the three features you've listed - readability, fewer keywords,
extensibility - work within the dimension of access levels we have now, as
long as private(module) is implicitly the default. I'm curious about the
setter-specific access where that isn't the case, though - suppose the
getter-specific access level for your example wasn't 'internal'. How would
we declare this?
public(open: get), private(file: set) var someValue: Int = 0
private(file: get, scope: set) var someValue: Int = 0
Orthogonal extensions, such as 'protected', multiply the problem. How do
you restrict which access levels get 'type' access?
I think perhaps you reverse the arguments:
private(set: scope, get: file, type: module)
Perhaps, by default:
These four are equivalent:
var someValue: Int = 0
private var someValue: Int = 0
private(module) var someValue: Int = 0
private(get: module) var someValue: Int = 0
'set' defaults to 'get' level unless explicitly restricted further, e.g.
these two are equivalent
private(set: file) var someValue: Int = 0
private(get: module, set: file) var someValue: Int = 0
Perhaps 'type' access is 'set' level unless explicitly exposed:
private(get: file, set: scope, type: module)
... It doesn't make sense to me that 'type' would be more restricted than
'set', but offhand I haven't figured out if 'type' can be more exposed than
'get'. If there are restrictions like this the compiler can complain that
the access levels specified are inconsistent.
This still seems a bit clunky to me if you have a public and a private on
the same line, but perhaps someone can suggest something for that.
Ross
···
On Mon, Feb 20, 2017 at 11:42 AM, Haravikk via swift-evolution < swift-evolution@swift.org> wrote:
So discussion of the exact naming convention for access modifiers has been
discussed multiple times, especially when fileprivate was being introduced.
It's now been a while since fileprivate was added, so we've all had more
time to actually work with it, so I wanted to raise the discussion again to
see what people now think.
Specifically, during the debate over access modifiers I really didn't like
the propose fileprivate, as I don't like conjoined lower-case key-"words"
(to me a keyword should always be a single word, I still don't like
associatetype or typealias either, and neither does macOS' auto-correct
). And to be honest my opinion hasn't changed; if anything I hate it even
more.
The proposal I preferred was to use only the public and private keywords
and use parameters to provide greater specificity, like so:
public as it is now
private(module) equivalent to internal, which is private to the current
module/project
private(file) equivalent to fileprivate
private(scope) equivalent to current private
The actual parameters are up for debate, but I still feel this a lot
clearer. I also generally prefer the parameterised version for several
reasons:
- Readability: I know not everyone will agree on this one, but I much
prefer the separation to having conjoined keywords.
- Fewer Keywords: Maybe I'm a keyword purist or something, but I just
don't like having too many keywords in the language, especially four for
what amounts to a single feature (access).
- Extensibility: It is easier and cleaner to add more parameters in
future. For example, private(type) could be an equivalent to protected
access in other languages. It can also be used to more easily group
external extension modifiers under public such as public(final),
public(open) etc.
For setter-specific access it might look something like:
private(file:set) var someValue:Int = 0
I know it might not seem that important to some people, but this is one
area of Swift's syntax that still bothers me, perhaps unreasonably so, but
I don't get to pick what annoys me! I'd also seek to replace associatedtype
and typealias (and any other conjoined keyword I've forgotten) but I
haven't thought of any alternatives that I like for those yet.
Anyway, just wanted to discuss how others felt having used fileprivate and
such for a while, and whether it's worth revisiting, or if I just have to
live with it.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution