> On Mar 19, 2017, at 6:25 PM, Andrew Thompson <[email protected]> wrote:
>
> Opps, should have sent this to the mailing list….
>
> That sounds pretty good. 😊 I find the response from the community to this
> proposal to be pretty cool.
>
> While reading some of the discussion around your proposal, I’ve seen requests
> where people are wanting to retrieve the list of an object’s properties. I
> think this is an interesting idea to explore, particularly if it was possible
> to generalise about all of the properties stored on an object.
I agree, I think that's a natural extension of the core key path functionality.
We're trying to keep the initial work small in scope to begin with, but I think
it's a good foundation to start building out a better reflection model.
-Joe
> For example, consider the following:
>
> We have a protocol, JSONEncodable, and a bunch of types that conform to it,
> namely `Int`, `String`, and `Data`.
>
> protocol JSONEncodable {
> func encode() -> String
> }
>
> extension Int {
> func encode() -> String { … }
> }
>
> // similarly for String and Data.
>
> A very common scenario that occurs is composing a type where all properties
> conform to a particular protocol, for example:
>
> struct Person {
> var age: Int
> var name: String
> var identifier: Data
> }
>
> Now, we want to have `Person` conform to `JSONEncodable`, so we could just
> implement the encode method ourselves:
>
> extension Person: JSONEncodable {
> func encode() -> String {
> return age.encode() + name.encode() +
> identifier.encode()
> }
> }
>
> But this seems a little bit repetitive, what we really want is for the
> library author to declare the following:
>
> For every type T whose properties conform to protocol P, we can derive
> a free conformance to protocol P for type T.
>
> Applying this, we get the following code:
>
> extension JSONEncodable where Self.InstanceProperties: JSONEncodable {
> func encode() -> String {
> let properties = Metatype<Self>.properties
> var output = “”
> for p in properties {
> output += p.read(self).encode()
> }
> return output
> }
> }
>
> Now all a user needs to do is say that want to conform to the protocol:
>
> struct Person: JSONEncodable {
> var age: Int
> var name: String
> var identifier: Data
> }
>
> Cheers,
> - Andrew
>
>> On 18 Mar 2017, at 6:08 am, Joe Groff <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>>>
>>> On Mar 14, 2017, at 1:02 AM, Andrew Thompson via swift-evolution
>>> <[email protected] <mailto:[email protected]>> wrote:
>>>
>>> Hello Swift Evolution Community,
>>>
>>> I’ve been thinking about a new language feature that would allow properties
>>> to be first class citizens. The basic idea is as follows:
>>>
>>> let x: PropertySelector<UIView, CGFloat> =
>>> #property(UIView.frame.origin.x)
>>> let view: UIView = …
>>> view.frame.origin.x = 20
>>> x.read(view) // returns 20
>>> x.write(view, value: 9091)
>>> view.frame.origin.x // now 9091
>>>
>>> This is a trivial example, but now we can do more interesting things in our
>>> code. For example, we can animate any property on a view (that is
>>> documented to be animatable of course):
>>>
>>> func animate(view: UIView, property: PropertySelector<UIView, CGFloat>,
>>> amount: Int) {
>>> let originalValue = property.read(view)
>>> func generateKeyFrames() {
>>> let step = 1.0 / Double(amount)
>>> for i in 0..<amount {
>>> let newValue = originalValue + CGFloat(i)
>>> let time = Double(i) / Double(amount)
>>> UIView.addKeyframe(withRelativeStartTime: time,
>>>
>>> relativeDuration: step,
>>> animations: {
>>> property.write(view, value: newValue) }
>>> )
>>> }
>>> }
>>>
>>> UIView.animateKeyframes(withDuration: 1.0,
>>> delay: 0,
>>> options: [],
>>> animations:
>>> generateKeyFrames,
>>> completion: nil)
>>> }
>>>
>>> let myView: UIView = …
>>> myView.frame = CGRect(x: 20, y: 100, width: 99, height: 120)
>>>
>>> // once this completes, myView.frame.origin.x == 120
>>> animate(view: myView, property: #property(UIView.frame.origin.x),
>>> amount: 100)
>>>
>>> // once this completes, myView.frame.size.width == 198
>>> animate(view: myView, property: #property(UIView.frame.size.width),
>>> amount: 99)
>>>
>>> I think this would be a pretty neat feature to have, what do you think?
>>
>> We agree! How does this sound:
>>
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170313/033998.html
>>
>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170313/033998.html>
>>
>> -Joe
>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution