Actually, now that I think about it, a much simpler model overall would be:
-
The programmer doesn't have access to the storage at all unless they create it themselves and assign it to the property. (i.e. there is no $foo only a nameless compiler variable)
-
Within a type which is a property delegate, you would be allowed to create functions who's name starts with a $, and those functions could be called on the property when needed.
struct MyDelegate<T,S> : PropertyDelegate {
typealias Value = T //Having this as an associated value lets us limit the values it can be used with. For example, we may have a delegate that only works with strings
typealias Enclosing = S //Having this as an associated value lets us limit the types our delegates can be placed on
func delegateValue(enclosingSelf:S)->T {...}
mutating func setDelegateValue(_ newValue:T, enclosingSelf:S) {...}
func myFunc() {...} //Only callable to those that create the type
func $reset() {...} //This can be called from the property
}
myType.foo.$reset() //We can call the $func on the delegate using it's name (which we know won't conflict)
The advantage of this design is that it lets the designer of the delegate choose what needs to be exposed as part of controlling the delegate. If you needed/wanted to call one of the non-$functions, you would create the delegate yourself and then assign it to the property.