<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">At a glance it sounds great!</div><div class=""><br class=""></div><div class="">The current behaviour should clearly be changed and I'm very much in favor keeping the ability to get unapplied instance methods for mutating methods.</div><div class=""><br class=""></div><div class="">I particularly liked the last example. I've tried similar things before only to be disappointed when it didn't work.</div><div class=""><br class=""></div><div class="">
<div class="">- Janosch</div>

</div>
<br class=""><div><blockquote type="cite" class=""><div class="">On 22 Feb 2016, at 23:52, Joe Groff via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Today, you can reference an instance property as a member of its type to access it as a fully unbound function, which is currently curried:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">struct Foo {</div><div class="">&nbsp; var x: Int</div><div class="">&nbsp; func foo(y y: Int) { return x + y }</div><div class="">}</div><div class=""><br class=""></div><div class="">let foo = Foo.foo</div><div class="">foo(Foo(x: 1))(y: 2) // returns 3</div><div class=""><br class=""></div></blockquote>However, this is problematic for `mutating` methods. Since the first argument is `inout`, the mutation window for the parameter formally ends before the second argument can be applied to complete the call. Currently we miscompile this, and form a closure over a dangling pointer, leading to undefined behavior:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">struct Bar {</div><div class="">&nbsp; var x = 0</div><div class="">&nbsp; mutating func bar() { x += 1 }</div><div class="">}</div><div class=""><br class=""></div><div class="">let bar = Bar.bar</div><div class="">var a = Bar()</div><div class="">bar(&amp;a)() // This might appear to work, if we don't optimize too hard</div><div class=""><br class=""></div><div class="">let closure: () -&gt; ()</div><div class="">do {</div><div class="">&nbsp; var b = Bar()</div><div class="">&nbsp; closure = bar(&amp;b)</div><div class="">}</div><div class="">closure() // This scribbles dead stack space</div><div class=""><br class=""></div><div class="">var c = Bar() {</div><div class="">&nbsp; didSet { print("c was set") }</div><div class="">}</div><div class=""><br class=""></div><div class="">bar(&amp;c)() // This will scribble over c after didSet is called, if not worse</div><div class=""><br class=""></div></blockquote>We can close this hole by disallowing a reference to Bar.bar, like we already disallow partial applications. However, I think it would be in line with our other simplifications of the function type system to change the type of `Bar.bar` and other unapplied instance method references to no longer be curried. In addition to providing a model for unapplied instance methods that works with mutating methods, this would also eliminate a type difference between free functions and methods of the same arity, allowing for easier code reuse. For instance, `reduce` takes a closure of type (State, Element) -&gt; State. Flattening the formal type of instance methods would allow binary methods to be used as-is with `reduce`, like binary free functions can:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class="">func sumOfInts(ints: [Int]) -&gt; Int {&nbsp;</blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class="">&nbsp; return ints.reduce(0, combine: +)</blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class="">}</blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class="">func unionOfSets&lt;T&gt;(sets: [Set&lt;T&gt;]) -&gt; Set&lt;T&gt; {&nbsp;<br class="">&nbsp; return ints.reduce([], combine: Set.union)<br class="">}</blockquote><div class=""><br class=""></div><div class="">What do you all think?</div><br class=""><div class="">-Joe</div></div></div></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>