This revised draft is much improved. Thanks for taking all of the feedback into account!
By default, the synthesized storage property will have
internal access or the access of the original property, whichever is more restrictive.
It seems like this rule also needs to take into account the visibility of the property delegate type. For example, what if the property delegate type is
fileprivate but the original property is public and the value type is
Int? The rule above says the storage should be
internal but the property delegate type isn’t visible internally.
Hashable , and
Equatable follows the same rules, using the underlying
value of the property delegate type contains an
init(initialValue:) and the synthesized storage property's type otherwise.
This rule kind of makes sense for consistency with memberwise initializers and because
Decodable will require initialization with the encoded value (and of course
Encodable must use the same rule). I do wonder though if this makes sense for
Hashable. Is there any reason other than consistency with the others to adopt this rule? If not, how important is this consistency relative to other considerations?
Currently, identifiers starting with a
$ are not permitted in Swift programs. Today, such identifiers are only used in LLDB, where they can be used to name persistent values within a debugging session.
This is not strictly true. We already have the
$0 shorthand in closures. The existence of that shorthand is what made the
$ prefix make sense as a compiler-owned identifier space in my mind. It is probably worth mentioning this in the proposal itself.
A property with a delegate can declare accessors explicitly (
willSet ). If either
set is missing, it will be implicitly created by accessing the storage property (e.g.,
Property observers make sense but I’m less convinced that “overriding” the getter or setter makes much sense. Since property delegates will usually be an implementation detail I think it’s fine to allow it but I am curious what the use cases might be.
A property delegate type delegate access to the storage property (
$foo ) by providing a property named
storageValue . As with the
value property and (also optional)
init(initialValue:) , the
storageValue property must have the same access level as its property delegate type. When present,
storageValue is used to delegate accesses to the synthesized storage property.
This paragraph is not completely clear to me. Is this an optional feature that allows a property delegate to support direct access to the storage of the value (for optimization, etc)?
Like other declarations, the synthesized storage property will be
internal by default, or the access level of the original property if it is less than
internal . However, we could provide separate access control for the storage property to make it more or less accessible using a syntax similar to that of
Given that property delegates will often be an implementation detail I really think this should be supported immediately.