<div dir="ltr">+1 very interesting idea</div><div class="gmail_extra"><br><div class="gmail_quote">2016-02-26 9:09 GMT+03:00 Russ Bishop via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span>:<br><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>
<br>
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>
<br>
Russ<br>
<div class="HOEnZb"><div class="h5"><br>
&gt; On Feb 25, 2016, at 2:47 PM, Stephen Celis via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt; I&#39;m reopening a topic that has already been discussed here at length[1]: setup closures and `self`-binding closures.<br>
&gt;<br>
&gt; I&#39;ve been wondering if Swift could adopt what Kotlin calls &quot;extension function expressions&quot;[2]. These would allow us to encode a closure&#39;s receiver type (`self`) into the closure type itself, providing a powerful, type-safe way to define DSLs.<br>
&gt;<br>
&gt; Erica&#39;s earlier draft proposed this builder pattern:<br>
&gt;<br>
&gt;    with let task = NSTask() {<br>
&gt;        launchPath = &quot;/usr/bin/mdfind&quot;<br>
&gt;        arguments = [&quot;kMDItemDisplayName == *.playground&quot;]<br>
&gt;        standardOutput = pipe<br>
&gt;    }<br>
&gt;<br>
&gt; With extension functions, we could approach something similar:<br>
&gt;<br>
&gt;    func with&lt;T&gt;(value: T, body: T.() -&gt; ()) -&gt; T {<br>
&gt;        value.body()<br>
&gt;        return value<br>
&gt;    }<br>
&gt;<br>
&gt;    let task = with(NSTask()) {<br>
&gt;        launchPath = &quot;/usr/bin/mdfind&quot;<br>
&gt;        arguments = [&quot;kMDItemDisplayName == *.playground&quot;]<br>
&gt;        standardOutput = pipe<br>
&gt;    }<br>
&gt;<br>
&gt; Or, using the `then`[3] pattern:<br>
&gt;<br>
&gt;    protocol Builder {}<br>
&gt;    extension Builder {<br>
&gt;        func then(body: Self.() -&gt; ()) -&gt; Self {<br>
&gt;            body()<br>
&gt;            return self<br>
&gt;        }<br>
&gt;    }<br>
&gt;    extension NSTask: Builder {}<br>
&gt;<br>
&gt;    let task = NSTask().then {<br>
&gt;        launchPath = &quot;/usr/bin/mdfind&quot;<br>
&gt;        arguments = [&quot;kMDItemDisplayName == *.playground&quot;]<br>
&gt;        standardOutput = pipe<br>
&gt;    }<br>
&gt;<br>
&gt; How about BDD-style frameworks (like Quick/Nimble[4] and Spectre[5])?<br>
&gt;<br>
&gt;    describe(&quot;a person&quot;) {<br>
&gt;        let person = Person(name: &quot;Kyle&quot;)<br>
&gt;<br>
&gt;        it(&quot;has a name&quot;) {<br>
&gt;            try expect(<a href="http://person.name" rel="noreferrer" target="_blank">person.name</a>) == &quot;Kyle&quot;<br>
&gt;        }<br>
&gt;    }<br>
&gt;<br>
&gt; And HTML builders?<br>
&gt;<br>
&gt;    html {<br>
&gt;        head { title(&quot;Hello, World!&quot;) }<br>
&gt;    }<br>
&gt;<br>
&gt; And block-based, transactional APIs?<br>
&gt;<br>
&gt;    db.inTransaction {<br>
&gt;        delete(&quot;users&quot;, &quot;first_name = ?&quot;, [&quot;Jake&quot;])<br>
&gt;    }<br>
&gt;<br>
&gt; The main benefits have been previously discussed:<br>
&gt;<br>
&gt; 1. The ability to remove noise (&quot;$0&quot; everywhere)<br>
&gt; 2. The ability to avoid defining globals (in favor of a safer, scoped interface)<br>
&gt;<br>
&gt; Would such an enhancement be feasible?<br>
&gt;<br>
&gt; ---<br>
&gt; Stephen<br>
&gt;<br>
&gt; Footnotes:<br>
&gt;<br>
&gt; [1] A probably-incomplete list:<br>
&gt; - &quot;Idea for enabling DSLs: bind to self in closures&quot;: <a href="https://lists.swift.org/pipermail/swift-evolution/2015-December/000114.html" rel="noreferrer" target="_blank">https://lists.swift.org/pipermail/swift-evolution/2015-December/000114.html</a><br>
&gt; - &quot;Request for Discussion: Setup closures&quot;: <a href="https://lists.swift.org/pipermail/swift-evolution/2015-December/000211.html" rel="noreferrer" target="_blank">https://lists.swift.org/pipermail/swift-evolution/2015-December/000211.html</a><br>
&gt; - &quot;Method cascading (was Re: Request for Discussion: Setup closures)&quot;: <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151130/000729.html" rel="noreferrer" target="_blank">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151130/000729.html</a><br>
&gt; - &quot;Fluent syntax (replacing void with a useful default return value)&quot;: <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/374" rel="noreferrer" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/374</a><br>
&gt; - &quot;Lexical scope statement (with .. do)&quot;: <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/1408" rel="noreferrer" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/1408</a><br>
&gt; - &quot;Scoped resources (like C# using statement)&quot;: <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/1641" rel="noreferrer" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/1641</a><br>
&gt; - &quot;Customized Inline Init Closure&quot;: <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/1946" rel="noreferrer" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/1946</a><br>
&gt; - &quot;Then Support&quot;: <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/2054" rel="noreferrer" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/2054</a><br>
&gt; - &quot;Draft proposal: multi-property assignment .= operator&quot;: <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/2960" rel="noreferrer" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/2960</a><br>
&gt; - &quot;Custom default names for arguments of closures&quot;: <a href="http://thread.gmane.org/gmane.comp.lang.swift.evolution/6969" rel="noreferrer" target="_blank">http://thread.gmane.org/gmane.comp.lang.swift.evolution/6969</a><br>
&gt; - <a href="https://bugs.swift.org/browse/SR-160" rel="noreferrer" target="_blank">https://bugs.swift.org/browse/SR-160</a><br>
&gt;<br>
&gt; [2] <a href="https://kotlinlang.org/docs/reference/lambdas.html#function-literals-with-receiver" rel="noreferrer" target="_blank">https://kotlinlang.org/docs/reference/lambdas.html#function-literals-with-receiver</a><br>
&gt; [3] <a href="https://github.com/devxoul/Then" rel="noreferrer" target="_blank">https://github.com/devxoul/Then</a><br>
&gt; [4] <a href="https://github.com/Quick/Quick" rel="noreferrer" target="_blank">https://github.com/Quick/Quick</a><br>
&gt; [5] <a href="https://github.com/kylef/Spectre" rel="noreferrer" target="_blank">https://github.com/kylef/Spectre</a><br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; swift-evolution mailing list<br>
&gt; <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
&gt; <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br>
_______________________________________________<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/mailman/listinfo/swift-evolution</a><br>
</div></div></blockquote></div><br></div>