<div dir="ltr"><div class="gmail_default" style="font-family:comic sans ms,sans-serif;color:#274e13">+1 Lenses would be awesome!</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 15, 2017 at 1:59 AM, Robert Widmann via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><a href="https://github.com/typelift/Focus" target="_blank">Lenses</a>!  My only concern is that arbitrary effects can be attached to setters and getters, which can lead to surprising results when using the property reference.  As a language feature, I’d be interested to see where discussion around this will lead.<div><br></div><div>~Robert Widmann</div><div><div class="h5"><div><br></div><div><div><blockquote type="cite"><div>On Mar 14, 2017, at 4:02 AM, Andrew Thompson via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-3110926282754345011Apple-interchange-newline"><div><div>Hello Swift Evolution Community,<br><br>I’ve been thinking about a new language feature that would allow properties to be first class citizens. The basic idea is as follows:<br><br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>let x: PropertySelector&lt;UIView, CGFloat&gt; = #property(UIView.frame.origin.<wbr>x)<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>let view: UIView = …<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>view.frame.origin.x = 20<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>x.read(view) // returns 20<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>x.write(view, value: 9091)<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>view.frame.origin.x // now 9091<br><br>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):<br><br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>func animate(view: UIView, property: PropertySelector&lt;UIView, CGFloat&gt;, amount: Int) {<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>let originalValue = property.read(view)<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>func generateKeyFrames() {<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>let step = 1.0 / Double(amount)<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>for i in 0..&lt;amount {<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>let newValue = originalValue + CGFloat(i)<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>let time = Double(i) / Double(amount)<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>UIView.addKeyframe(<wbr>withRelativeStartTime: time,<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>  relativeDuration: step,<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>  animations: { property.write(view, value: newValue) }<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>)<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>UIView.animateKeyframes(<wbr>withDuration: 1.0,<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>   delay: 0,<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>   options: [],<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>   animations: generateKeyFrames,<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>   completion: nil)<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>}<br><br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>let myView: UIView = …<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>myView.frame = CGRect(x: 20, y: 100, width: 99, height: 120)<br><br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>// once this completes, myView.frame.origin.x == 120<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>animate(view: myView, property: #property(UIView.frame.origin.<wbr>x), amount: 100)<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span><br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>// once this completes, myView.frame.size.width == 198<br><span class="m_-3110926282754345011Apple-tab-span" style="white-space:pre-wrap">        </span>animate(view: myView, property: #property(UIView.frame.size.<wbr>width), amount: 99)<br><br>I think this would be a pretty neat feature to have, what do you think?<br><br>Cheers,<br>- Andrew<br>______________________________<wbr>_________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br></div></div></blockquote></div><br></div></div></div></div><br>______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
<br></blockquote></div><br></div>