[swift-evolution] [Proposal] Property behaviors

Curt Clifton curt at omnigroup.com
Sun Jan 17 22:29:29 CST 2016


On Jan 14, 2016, at 10:33 AM, Joe Groff via swift-evolution <swift-evolution at swift.org> wrote:

>> One more thing: should there be a way to pass arbitrary data, rather than initializers or accessors, into a behavior? For instance, it would be nice if you could do something like:
>> 
>>    var behavior backedByJSON<Value: JSONRepresentable where Self: JSONObjectRepresentable>: Value {
>>        var key: String
>>        
>>        init(key: String) {
>>            backedByJSON.key = key
>>        }
>>        
>>        get {
>>            return Value(JSON: self.JSON[key])
>>        }
>>        set {
>>            self.JSON[key] = newValue.JSON
>>        }
>>    }
>>    
>>    struct User: JSONObjectRepresentable {
>>        var JSON: [String: JSONType]
>>        
>>        var [backedByJSON(key: "id")] ID: Int
>>        var [backedByJSON(key: "name")] name: String
>>        
>>        var [backedByJSON(key: "posts")] posts: [Post]
>>    }
> 
> 
> That parameterization could be achieved, somewhat more verbosely, using an accessor 'key { return "id" }'. If behaviors could be parameterized in-line, I wouldn't do it by passing the params to `init`, since that again imposes the need for per-instance storage to carry `key` from the behavior initialization to the property implementation.

It would be very handy to have access to the property's name inside the behavior. As proposed, we have Self and self for referring to the type and instance of the container and newValue for referring to the new value in the core getter. A predefined local variable "name" of type String, bound to the name of the decorated property, would be handy for implementing things like Brent's backedByJSON behavior:

   var behavior backedByJSON<Value: JSONRepresentable where Self: JSONObjectRepresentable>: Value {
       get {
           return Value(JSON: self.JSON[name])
       }
       set {
           self.JSON[name] = newValue.JSON
       }
   }

A "name" property could also be used for an object-level observation system that included the name of the changed property in published notifications. Such a system can be useful, for example, in constructing delta transaction for sending to a remote API. (E.g., we could notify a server that the due date of a task has changed rather than sending the whole task object or performing a diff.)

Adding this bit of magic would go a long way toward letting us implement something like OAAppearance[1] in Swift instead of importing runtime.h and dynamically reifying methods[2]. 

Cheers,

Curt

Curt Clifton, PhD
Software Developer
The Omni Group

[1] - https://github.com/omnigroup/OmniGroup/tree/master/Frameworks/OmniAppKit/Appearance
[2] - http://curtclifton.net/video-of-oaappearance-at-xcoders


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160117/407a3e35/attachment.html>


More information about the swift-evolution mailing list