<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div></div><div>+1</div><div><br></div><div>-Thorsten </div><div><br>Am 22.02.2016 um 23:52 schrieb Joe Groff via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>>:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=us-ascii"><div><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=""> var x: Int</div><div class=""> 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=""> var x = 0</div><div class=""> 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(&a)() // This might appear to work, if we don't optimize too hard</div><div class=""><br class=""></div><div class="">let closure: () -> ()</div><div class="">do {</div><div class=""> var b = Bar()</div><div class=""> closure = bar(&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=""> didSet { print("c was set") }</div><div class="">}</div><div class=""><br class=""></div><div class="">bar(&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) -> 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]) -> Int { </blockquote><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""> 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<T>(sets: [Set<T>]) -> Set<T> { <br class=""> 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></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>