<div dir="ltr"><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;word-break:normal;color:rgb(51,51,51);background-color:rgb(247,247,247)"><br></pre><div><br></div><div><div>And if we only make the actual type inference more powerful?</div><div><br></div><div>Using the examples on proposal:</div></div><div><br></div><div><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;word-break:normal;color:rgb(51,51,51);background-color:rgb(247,247,247)"><span style="color:rgb(167,29,93)">extension</span> UIView {
<span style="color:rgb(167,29,93)">func</span> <span style="color:rgb(121,93,163)">insertSubview</span>(view: UIView, at index: <span style="color:rgb(0,134,179)">Int</span>)
<span style="color:rgb(167,29,93)">func</span> <span style="color:rgb(121,93,163)">insertSubview</span>(view: UIView, aboveSubview siblingSubview: UIView)
<span style="color:rgb(167,29,93)">func</span> <span style="color:rgb(121,93,163)">insertSubview</span>(view: UIView, belowSubview siblingSubview: UIView)
}</pre><div><br></div><div><br></div><div><pre style="overflow:auto;margin-top:0px;margin-bottom:0px;font-stretch:normal;padding:16px;border-radius:3px;word-wrap:normal;word-break:normal;line-height:1.45;font-size:13.6px;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;color:rgb(51,51,51);background-color:rgb(247,247,247)"><span class="pl-k" style="color:rgb(167,29,93)">let</span> fn1: (UIView, <span class="pl-c1" style="color:rgb(0,134,179)">Int</span>) <span class="pl-k" style="color:rgb(167,29,93)">=</span> someView<span class="pl-k" style="color:rgb(167,29,93)">.</span>insertSubview <span class="pl-c" style="color:rgb(150,152,150)">// ok: uses insertSubview(_:at:)</span>
<span class="pl-k" style="color:rgb(167,29,93)">let</span> fn2: (UIView, aboveSubview: UIView) <span class="pl-k" style="color:rgb(167,29,93)">=</span> someView<span class="pl-k" style="color:rgb(167,29,93)">.</span>insertSubview <span class="pl-c" style="color:rgb(150,152,150)">// Ok: no more ambiguous!
<span style="color:rgb(167,29,93);font-size:13.6px;line-height:1.45">let</span> <span style="color:rgb(51,51,51);font-size:13.6px;line-height:1.45">fn3: (UIView, </span></span><span style="line-height:20px;font-size:small;color:rgb(33,33,33);font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;background-color:white">belowSubview: </span><span style="font-size:13.6px;line-height:1.45">UIView) </span><span class="pl-k" style="font-size:13.6px;line-height:1.45;color:rgb(167,29,93)">=</span><span style="font-size:13.6px;line-height:1.45"> someView</span><span class="pl-k" style="font-size:13.6px;line-height:1.45;color:rgb(167,29,93)">.</span><span style="font-size:13.6px;line-height:1.45">insertSubview </span><span class="pl-c" style="color:rgb(150,152,150);font-size:13.6px;line-height:1.45">// Ok: no more ambiguous!</span></pre></div></div><div><br></div><div><div>And for properties:</div></div><div><br></div><div><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;font-stretch:normal;line-height:1.45;padding:16px;border-radius:3px;word-wrap:normal;word-break:normal;color:rgb(51,51,51);background-color:rgb(247,247,247)"><span class="pl-k" style="color:rgb(167,29,93)">let</span> specificTitle:() -> String? <span class="pl-k" style="color:rgb(167,29,93)">=</span> button<span class="pl-k" style="color:rgb(167,29,93)">.</span>currentTitle <span class="pl-c" style="color:rgb(150,152,150)">// will pick the getter</span>
<span class="pl-k" style="color:rgb(167,29,93)">let</span> otherTitle: (UIButton) -> () -> String? <span class="pl-k" style="color:rgb(167,29,93)">=</span> UIButton<span class="pl-k" style="color:rgb(167,29,93)">.</span>currentTitle <span class="pl-c" style="color:rgb(150,152,150)">// will pick the getter</span>
<span class="pl-k" style="color:rgb(167,29,93)">let</span> setTintColor: (UIColor!) -> () <span class="pl-k" style="color:rgb(167,29,93)">=</span> button<span class="pl-k" style="color:rgb(167,29,93)">.</span>tintColor <span class="pl-c" style="color:rgb(150,152,150)">// </span><span style="color:rgb(150,152,150);font-size:13.6px;line-height:1.45">will pick the setter</span></pre></div><div><br></div><div>This can be an opportunity to do something like that:<br></div><div><br></div><div><pre style="overflow:auto;margin-top:0px;margin-bottom:0px;font-stretch:normal;padding:16px;border-radius:3px;word-wrap:normal;word-break:normal;line-height:1.45;font-size:13.6px;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;background-color:rgb(247,247,247)"><span style="color:rgb(51,51,51)"><span style="color:rgb(167,29,93)">func</span> </span><font color="#795da3">processColor</font><font color="#333333">(data: Any, delegate : </font><span style="color:rgb(51,51,51);font-size:13.6px;line-height:1.45">(UIColor!) -> ()</span><span style="color:rgb(51,51,51);font-size:13.6px;line-height:1.45">)</span></pre><pre style="overflow:auto;margin-top:0px;margin-bottom:0px;font-stretch:normal;padding:16px;border-radius:3px;word-wrap:normal;word-break:normal;line-height:1.45;font-size:13.6px;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;background-color:rgb(247,247,247)"><span style="color:rgb(121,93,163);font-size:13.6px;line-height:1.45">processColor</span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace" style="font-size:13.6px;line-height:20px"><span style="font-size:13.6px;line-height:19.72px">(someData, </span></font><span style="font-size:13.6px;line-height:1.45;color:rgb(51,51,51)">button</span><span class="pl-k" style="font-size:13.6px;line-height:1.45;color:rgb(167,29,93)">.</span><span style="font-size:13.6px;line-height:1.45;color:rgb(51,51,51)">tintColor) </span><span class="pl-c" style="font-size:13.6px;line-height:1.45;color:rgb(150,152,150)">// </span><span style="font-size:13.6px;line-height:1.45;color:rgb(150,152,150)">will pass tintColor setter</span></pre></div><div><br></div><div>And for subscript:</div><div><br></div><div><pre style="overflow:auto;margin-top:0px;margin-bottom:0px;font-stretch:normal;padding:16px;border-radius:3px;word-wrap:normal;word-break:normal;background-color:rgb(247,247,247)"><span class="pl-k" style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">extension</span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45"> Matrix {
</span></font><span class="pl-k" style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">subscript</span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45"> (row row: </span></font><span class="pl-c1" style="color:rgb(0,134,179);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">Int</span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45">) </span></font><span class="pl-k" style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">-></span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45"> [</span></font><span class="pl-c1" style="color:rgb(0,134,179);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">Double</span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45">] {
</span></font><span class="pl-k" style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">get</span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45"> { </span></font><span class="pl-k" style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">...</span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45"> }
</span></font><span class="pl-k" style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">set</span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45"> { </span></font><span class="pl-k" style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">...</span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45"> }
}
}
</span></font><span class="pl-k" style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">let</span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45"> getRow: (Int) -> () -> [Double] </span></font><span class="pl-k" style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">=</span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45"> someMatrix </span></font><span class="pl-c" style="color:rgb(150,152,150);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">// will pick the </span><font color="#969896" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:19.72px">subscript getter</span></font><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45">
</span></font><span class="pl-k" style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">let</span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45"> setRow: (Int) -> ([Double]) -> () </span></font><span class="pl-k" style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">=</span><font color="#333333" face="Consolas, Liberation Mono, Menlo, Courier, monospace"><span style="font-size:13.6px;line-height:1.45"> someMatrix </span></font><span class="pl-c" style="color:rgb(150,152,150);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:13.6px;line-height:1.45">// will pick the subscript setter</span></pre></div><br><div dir="ltr"><div class="gmail_quote"><div dir="ltr"><br></div><div>Of course is more hard, but there's no new notation, just a expansion of the current type inference.</div><div><br></div><div>Maybe some syntax sugar can be provided in another proposal, but this one can be the kickoff.<br></div><div dir="ltr"><br></div><div dir="ltr"><br></div><div dir="ltr">Em seg, 28 de dez de 2015 às 16:10, Joe Groff via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> escreveu:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>On Dec 27, 2015, at 2:47 PM, John McCall <<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>> wrote:</div><br><div><div style="word-wrap:break-word"><div><blockquote type="cite"><div>On Dec 27, 2015, at 10:37 AM, Joe Groff via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><blockquote type="cite"><div><div style="word-wrap:break-word"><div><ul style="padding:0px 0px 0px 2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;background-color:rgb(255,255,255)"><li><p style="margin-top:16px;margin-bottom:16px">Getters and setters can be written using dotted syntax within the back-ticks:</p><div style="margin-bottom:16px"><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;padding:16px;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;word-break:normal"><span style="color:rgb(167,29,93)">let</span> specificTitle <span style="color:rgb(167,29,93)">=</span> button<span style="color:rgb(167,29,93)">.</span>`currentTitle<span style="color:rgb(167,29,93)">.</span><span style="color:rgb(167,29,93)">get</span>` <span style="color:rgb(150,152,150)">// has type () -> String?</span>
<span style="color:rgb(167,29,93)">let</span> otherTitle <span style="color:rgb(167,29,93)">=</span> UIButton<span style="color:rgb(167,29,93)">.</span>`currentTitle<span style="color:rgb(167,29,93)">.</span><span style="color:rgb(167,29,93)">get</span>` <span style="color:rgb(150,152,150)">// has type (UIButton) -> () -> String?</span>
<span style="color:rgb(167,29,93)">let</span> setTintColor <span style="color:rgb(167,29,93)">=</span> button<span style="color:rgb(167,29,93)">.</span>`tintColor<span style="color:rgb(167,29,93)">.</span><span style="color:rgb(167,29,93)">set</span>` <span style="color:rgb(150,152,150)">// has type (UIColor!) -> ()</span></pre></div><p style="margin-top:16px;margin-bottom:16px">The same syntax works with subscript getters and setters as well, using the full name of the subscript:</p><div style="margin-bottom:16px"><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;padding:16px;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal;word-break:normal"><span style="color:rgb(167,29,93)">extension</span> Matrix {
<span style="color:rgb(167,29,93)">subscript</span> (row row: <span style="color:rgb(0,134,179)">Int</span>) <span style="color:rgb(167,29,93)">-></span> [<span style="color:rgb(0,134,179)">Double</span>] {
<span style="color:rgb(167,29,93)">get</span> { <span style="color:rgb(167,29,93)">...</span> }
<span style="color:rgb(167,29,93)">set</span> { <span style="color:rgb(167,29,93)">...</span> }
}
}
<span style="color:rgb(167,29,93)">let</span> getRow <span style="color:rgb(167,29,93)">=</span> someMatrix<span style="color:rgb(167,29,93)">.</span>`<span style="color:rgb(167,29,93)">subscript</span>(row:)<span style="color:rgb(167,29,93)">.</span><span style="color:rgb(167,29,93)">get</span>` <span style="color:rgb(150,152,150)">// has type (Int) -> () -> [Double]</span>
<span style="color:rgb(167,29,93)">let</span> setRow <span style="color:rgb(167,29,93)">=</span> someMatrix<span style="color:rgb(167,29,93)">.</span>`<span style="color:rgb(167,29,93)">subscript</span>(row:)<span style="color:rgb(167,29,93)">.</span><span style="color:rgb(167,29,93)">set</span>` <span style="color:rgb(150,152,150)">// has type (Int) -> ([Double]) -> ()</span></pre></div></li></ul></div></div></div></blockquote><div>At least as far as pure Swift is concerned, for unapplied access, like `UIButton.currentTitle`, I think it would be more consistent with the way method references works for that to give you the getter (or lens) without decoration. instance.instanceMethod has type Args -> Ret, and Type.instanceMethod has type Self -> Args -> Ret; by analogy, since instance.instanceProperty has type Ret or inout Ret, it's reasonable to expect Type.instanceProperty to have type Self -> [inout] Ret. Forming a getter or setter partially applied to an instance feels unmotivated to me—{ button.currentTitle } or { button.currentTitle = $0 } already work, and are arguably clearer than this syntax.</div><div><br></div><div>I acknowledge that this leaves forming selectors from setters out to dry, but I feel like that's something that could be incorporated into a "lens" design along with typed selectors. As a rough sketch, we could say that the representation of @convention(selector) T -> inout U is a pair of getter/setter selectors, and provide API on Selector to grab the individual selectors from that, maybe Selector(getterFor: UIView.currentTitle)/(setterFor: UIView.currentTitle). I don't think get/set is a good interface for working with Swift properties, so I don't like the idea of building in language support to codify it beyond what's needed for ObjC interaction.</div></div></div></blockquote><div><br></div>I know this might be too early, but: what syntax are we thinking of for lenses? We might want to design this with future consistency in mind.</div></div></div></blockquote><br></div></div><div style="word-wrap:break-word"><div>Vaguely, I think it could look something like this. You could define a lens function by having it return `inout`. Calling the function produces an lvalue whose access nests within the accesses of its input `inout` parameters, if any, allowing for things like:</div><div><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div>var localVar = 1</div><div>let localRef: () -> inout Int = { &localVar }</div><div><br></div><div>func second(inout array: [Int]) -> inout Int {</div><div> return &array[1]</div><div>}</div><div><br></div><div>// Maybe you can define an inout function with accessors too</div><div>func fahrenheit(inout celsius: Double) -> inout Double {</div><div> get {</div><div> return celsius * 9/5 + 32</div><div> }</div><div> set {</div><div> celsius = (newValue - 32) * 5/9</div><div> }</div><div>}</div></blockquote><br><div>and you could access the unapplied lens for an instance property using `Type.property` syntax, analogous to how `Type.method` works. I feel like if we did that, then it would obviate the need for explicit `property.get` or `property.set` for most native Swift uses, though maybe not ObjC interop uses.</div><div><br></div><div>-Joe</div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=fuWmDRE6-2FDdvdUHeLHruUfdigJaxz7nh99l6HfkulY8L9VbyV0LnZ3wowg-2BqG6jleshEHmSShiAp-2FS8KCKPnSsmJ2NozdKJrod4LdxXS-2FltqbU7pi4cAIGeX7DErhN0wwgq-2BUD-2FFXe3IcBagPjHeFFddZmehpOHTnREvRDhLXOsNc56-2B-2BLsHZrFFlZ3RbYQslUnvqMm-2BMooAzsIebHmqRi6qEbirBNIbKVK2Mvt5Soo-3D" alt="" width="1" height="1" border="0" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important">
</div>
_______________________________________________<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" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div></div></div>