<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">+1 on the idea.<div class=""><br class=""></div><div class="">I'm less convinced by the suggested syntax, to me it feels a bit weird.</div><div class=""><br class=""></div><div class="">I'm thinking an attribute on the closure's first parameter, for exemple (feel free to suggest other names):</div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #35568a" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #35568a" class="">func</span> with&lt;T&gt;(value: <span style="font-variant-ligatures: no-common-ligatures; color: #c35900" class="">T</span>, body: (<span style="font-variant-ligatures: no-common-ligatures; color: #35568a" class="">bound</span>&nbsp;<span style="font-variant-ligatures: no-common-ligatures; color: #c35900" class="">T</span>) -&gt; ()) -&gt; <span style="font-variant-ligatures: no-common-ligatures; color: #c35900" class="">T</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; body(value)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; <span style="font-variant-ligatures: no-common-ligatures; color: #35568a" class="">return</span> value</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">Le 26 févr. 2016 à 08:22, Eugene Gubin via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; a écrit :</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">+1 very interesting idea</div><div class="gmail_extra"><br class=""><div class="gmail_quote">2016-02-26 9:09 GMT+03:00 Russ Bishop via swift-evolution <span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span>:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">+1 to this or something like it.<br class="">
<br class="">
Right now I’m relying on crap^H^H^H^Hstuff like dispatch_get_specific to provide that kind of context without introducing something like Quick’s global “World”.<br class="">
<br class="">
Russ<br class="">
<div class="HOEnZb"><div class="h5"><br class="">
&gt; On Feb 25, 2016, at 2:47 PM, Stephen Celis via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class="">
&gt;<br class="">
&gt; I'm reopening a topic that has already been discussed here at length[1]: setup closures and `self`-binding closures.<br class="">
&gt;<br class="">
&gt; I've been wondering if Swift could adopt what Kotlin calls "extension function expressions"[2]. These would allow us to encode a closure's receiver type (`self`) into the closure type itself, providing a powerful, type-safe way to define DSLs.<br class="">
&gt;<br class="">
&gt; Erica's earlier draft proposed this builder pattern:<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; with let task = NSTask() {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; launchPath = "/usr/bin/mdfind"<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; arguments = ["kMDItemDisplayName == *.playground"]<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; standardOutput = pipe<br class="">
&gt;&nbsp; &nbsp; }<br class="">
&gt;<br class="">
&gt; With extension functions, we could approach something similar:<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; func with&lt;T&gt;(value: T, body: T.() -&gt; ()) -&gt; T {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; value.body()<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; return value<br class="">
&gt;&nbsp; &nbsp; }<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; let task = with(NSTask()) {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; launchPath = "/usr/bin/mdfind"<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; arguments = ["kMDItemDisplayName == *.playground"]<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; standardOutput = pipe<br class="">
&gt;&nbsp; &nbsp; }<br class="">
&gt;<br class="">
&gt; Or, using the `then`[3] pattern:<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; protocol Builder {}<br class="">
&gt;&nbsp; &nbsp; extension Builder {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; func then(body: Self.() -&gt; ()) -&gt; Self {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; body()<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return self<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; }<br class="">
&gt;&nbsp; &nbsp; }<br class="">
&gt;&nbsp; &nbsp; extension NSTask: Builder {}<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; let task = NSTask().then {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; launchPath = "/usr/bin/mdfind"<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; arguments = ["kMDItemDisplayName == *.playground"]<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; standardOutput = pipe<br class="">
&gt;&nbsp; &nbsp; }<br class="">
&gt;<br class="">
&gt; How about BDD-style frameworks (like Quick/Nimble[4] and Spectre[5])?<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; describe("a person") {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; let person = Person(name: "Kyle")<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; it("has a name") {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try expect(<a href="http://person.name/" rel="noreferrer" target="_blank" class="">person.name</a>) == "Kyle"<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; }<br class="">
&gt;&nbsp; &nbsp; }<br class="">
&gt;<br class="">
&gt; And HTML builders?<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; html {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; head { title("Hello, World!") }<br class="">
&gt;&nbsp; &nbsp; }<br class="">
&gt;<br class="">
&gt; And block-based, transactional APIs?<br class="">
&gt;<br class="">
&gt;&nbsp; &nbsp; db.inTransaction {<br class="">
&gt;&nbsp; &nbsp; &nbsp; &nbsp; delete("users", "first_name = ?", ["Jake"])<br class="">
&gt;&nbsp; &nbsp; }<br class="">
&gt;<br class="">
&gt; The main benefits have been previously discussed:<br class="">
&gt;<br class="">
&gt; 1. The ability to remove noise ("$0" everywhere)<br class="">
&gt; 2. The ability to avoid defining globals (in favor of a safer, scoped interface)<br class="">
&gt;<br class="">
&gt; Would such an enhancement be feasible?<br class="">
&gt;<br class="">
&gt; ---<br class="">
&gt; Stephen<br class="">
&gt;<br class="">
&gt; Footnotes:<br class="">
&gt;<br class="">
&gt; [1] A probably-incomplete list:<br class="">
&gt; - "Idea for enabling DSLs: bind to self in closures": <a href="https://lists.swift.org/pipermail/swift-evolution/2015-December/000114.html" rel="noreferrer" target="_blank" class="">https://lists.swift.org/pipermail/swift-evolution/2015-December/000114.html</a><br class="">
&gt; - "Request for Discussion: Setup closures": <a href="https://lists.swift.org/pipermail/swift-evolution/2015-December/000211.html" rel="noreferrer" target="_blank" class="">https://lists.swift.org/pipermail/swift-evolution/2015-December/000211.html</a><br class="">
&gt; - "Method cascading (was Re: Request for Discussion: Setup closures)": <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151130/000729.html" rel="noreferrer" target="_blank" class="">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151130/000729.html</a><br class="">
&gt; - "Fluent syntax (replacing void with a useful default return value)": <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/374" rel="noreferrer" target="_blank" class="">http://thread.gmane.org/gmane.comp.lang.swift.evolution/374</a><br class="">
&gt; - "Lexical scope statement (with .. do)": <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/1408" rel="noreferrer" target="_blank" class="">http://thread.gmane.org/gmane.comp.lang.swift.evolution/1408</a><br class="">
&gt; - "Scoped resources (like C# using statement)": <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/1641" rel="noreferrer" target="_blank" class="">http://thread.gmane.org/gmane.comp.lang.swift.evolution/1641</a><br class="">
&gt; - "Customized Inline Init Closure": <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/1946" rel="noreferrer" target="_blank" class="">http://thread.gmane.org/gmane.comp.lang.swift.evolution/1946</a><br class="">
&gt; - "Then Support": <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/2054" rel="noreferrer" target="_blank" class="">http://thread.gmane.org/gmane.comp.lang.swift.evolution/2054</a><br class="">
&gt; - "Draft proposal: multi-property assignment .= operator": <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/2960" rel="noreferrer" target="_blank" class="">http://thread.gmane.org/gmane.comp.lang.swift.evolution/2960</a><br class="">
&gt; - "Custom default names for arguments of closures": <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/6969" rel="noreferrer" target="_blank" class="">http://thread.gmane.org/gmane.comp.lang.swift.evolution/6969</a><br class="">
&gt; - <a href="https://bugs.swift.org/browse/SR-160" rel="noreferrer" target="_blank" class="">https://bugs.swift.org/browse/SR-160</a><br class="">
&gt;<br class="">
&gt; [2] <a href="https://kotlinlang.org/docs/reference/lambdas.html#function-literals-with-receiver" rel="noreferrer" target="_blank" class="">https://kotlinlang.org/docs/reference/lambdas.html#function-literals-with-receiver</a><br class="">
&gt; [3] <a href="https://github.com/devxoul/Then" rel="noreferrer" target="_blank" class="">https://github.com/devxoul/Then</a><br class="">
&gt; [4] <a href="https://github.com/Quick/Quick" rel="noreferrer" target="_blank" class="">https://github.com/Quick/Quick</a><br class="">
&gt; [5] <a href="https://github.com/kylef/Spectre" rel="noreferrer" target="_blank" class="">https://github.com/kylef/Spectre</a><br class="">
&gt;<br class="">
&gt; _______________________________________________<br class="">
&gt; swift-evolution mailing list<br class="">
&gt; <a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
<br class="">
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
</div></div></blockquote></div><br class=""></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=""></div></body></html>