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.
Synthesis for Encodable
, Decodable
, 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 Equatable
and 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 ( get
, set
, didSet
, willSet
). If either get
or set
is missing, it will be implicitly created by accessing the storage property (e.g., $foo
).
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 private(set)
Given that property delegates will often be an implementation detail I really think this should be supported immediately.