Pitch: Property Delegates

I really like the simplicity of this being just syntactic sugar for a wrapper type. It’s a very straightforward approach and echoes the design for user-defined attributes that @hartbit recently suggested. Like some of the others, I’m not sure of the usage syntax but discussion of that can wait.

This is just my immediate intuition without deep thought, but it seems like it might be a good idea to restrict @propertyDelegate to value types. Does anyone know of good use cases that would require @propertyDelegate class? Everything I can think of would use value types, even if a class was used in the implementation, for example:

@propertyDelegate
struct Indirect<Value> {
    private class Box { 
        var value: Value
        init(value: Value) { 
           self.value = value
        }

        func copy() -> Box {
             return box(value: value)
        }
    }

    let box: Box

    init(initialValue value: Value) {
        box = Box(value: value)
    }

    var value: Value {
        get { 
              return box.value 
        }

        set { 
           if !isKnownUniquelyReferenced(&box) { 
               box = box.copy() 
           }
           box.value = newValue
        }
    }
}

The above example makes me wonder if it would be possible to have general syntax for initializing a delegated property using an existing value of the delegate type. For example:

var int: Int by Indirect = 42

// this is only possible if the property delegate has a “copy initializer”
var other1: Int by Indirect($int)

// this might be possible, but is probably not a great idea as $int is not of type Int
// is there an alternative that does not have potential for confusion or implementation
// complexity but also does not require manually writing a copy initializer?
var other2: Int by Indirect = $int

With respect to SE-0030, I especially miss its composability. I wonder if the direction @Paul_Cantrell suggested of using an additional generic parameter might be a viable way to approach composition. I would really like to see this direction explored further.

If composition via generics is viable I think it pushes us in the direction of using a PropertyDelegate protocol - we would need a way to constrain the wrapped property delegate and a protocol is the natural way to do that. This would necessarily be a “magic” protocol as it isn’t expressible directly in the language, but I’m ok with that if it allows us to support composition of property delegates.