What still strikes me as odd is that we now seem to have a plethora of
visibilities, some of which do not provide for a given context, some of which
seem to be looking for a context to justify their existence.
Whatever it is called, I find the idea of a file scope visibility somewhat
bizarre and at odds with the principle of standard OO class encapsulation.
The two main reasons I can see for the perceived need for fileprivate are :
1. being able to separate out "sections" of a class into various extensions
2. giving global junkies the ability to write all their code in one unit
Surely, there are members of a type that the writer wants to remain private,
even if an extension were declared in the same file. Fine, we have private for
that and, even if the writer declares members to be fileprivate, there is no
way that any extension declared outside of the file can see those members.
Now, I have a problem with that. If I want to access non-public members when I
extend a type, either I declare those extensions in the same unit and declare
those members as fileprivate, or if I want to declare those extensions in
another file, I have to move up to the next suitable scope, which is internal.
But internal is too "open" because it allows, not only my chosen extensions to
see those members but, also, any other code in the entire module.
Having made use of the "friend" concept in C++, this "all or next to nothing"
approach to visibility seems to leave me in much the same place as Objective-C,
where I could only have private or public, unless I did some tricky stuff with
class extensions, something which really didn't look that pretty.
There are some parts of a type that I would want to remain really, really
private to the type, not even visible to an extension.
There are other parts of a type that I would want to be private to that type
but also visible in, but only in, extensions explicitly written against that
type.
Which is why I am suggesting the "extensible" scope : private to the declaring
type but also and only visible within any extension to that type.
Here follows a highly contrived example :
// Person.swift
public struct Person
{
public var name: String
public extensible(set) var dateOfBirth: Date
public var age: Int
{
// return calculated age as of today
}
init(name: String, dateOfBirth: Date)
{
self.name = name
self.dateOfBirth = dateOfBirth // accessible as if it were private
}
// Registrar.swift
extension Person
{
func correct(dateOfBirth: Date)
{
self.dateOfBirth = …
}
}
// Test.swift
{
let person = Person()
person.dateOfBirth = … // compilation error, not visible
}
IMHO, this then removes one use case for fileprivate in that it allows
privileged visibility to private members of a type in extensions, both in the
same file and in any other file. But, it also ensures that not other code is
allowed access, whether that be in non-extension code in the same file or other
non-extension code anywhere else.
As for case 2. for fileprivate, if a developer wants to put all sorts of
globals and other code in one file, then I doubt if they are even going to
bother to use fileprivate, especially when they get internal visibility with
less typing ;)
Now, if someone could help me prepare this as a proposal…
--
Joanna Carter
Carter Consulting
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution