Pitch: Property Delegates

I like where this is going with custom attributes, but instead of treating every property delegate type a different attribute and having property delegates as a language feature, could this maybe be implemented as just another static attribute? Doug's custom static attribute suggestion seems to be a good enough abstraction to leverage for this.

A static attribute would be defined in the standard library that describes how the property is to be synthesized.

@staticAttribute(usage: [.property])
struct Delegated<Delegate: PropertyDelegate> {

    var delegate: Delegate
    var delegateAccess: Access

    init(to delegate: Delegate, delegateAccess: Access) { ... }
    init(to delegate: Delegate.Type, delegateAccess: Access) { ... }
}

enum Access {
    case `public`
    case `internal`
    case `fileprivate`
    case `private`
    case hidden
}

PropertyDelegate would become a normal protocol. Users could then describe the property synthesis by applying the attribute:

class Test {

    @Delegated(to: Lazy.self, delegateAccess: .public)
    public var data: Data
}

The Swift compiler would interpret the attribute. For the given example, it would synthesize the following:

class Test {

    public var $data: Lazy<Data>

    public var data: Data {
        get {
            return $data
        }
        set {
           $data = newValue
        }
    }
}

Delegated could be expanded with additional optional properties like delegateName if the user needs an alternative name, potentially not prefix with $.

The whole idea is very similar to ObjC way of synthesizing properties.

1 Like