<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"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></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>
> On Feb 25, 2016, at 2:47 PM, Stephen Celis via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br>
><br>
> I'm reopening a topic that has already been discussed here at length[1]: setup closures and `self`-binding closures.<br>
><br>
> 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>
><br>
> Erica's earlier draft proposed this builder pattern:<br>
><br>
> with let task = NSTask() {<br>
> launchPath = "/usr/bin/mdfind"<br>
> arguments = ["kMDItemDisplayName == *.playground"]<br>
> standardOutput = pipe<br>
> }<br>
><br>
> With extension functions, we could approach something similar:<br>
><br>
> func with<T>(value: T, body: T.() -> ()) -> T {<br>
> value.body()<br>
> return value<br>
> }<br>
><br>
> let task = with(NSTask()) {<br>
> launchPath = "/usr/bin/mdfind"<br>
> arguments = ["kMDItemDisplayName == *.playground"]<br>
> standardOutput = pipe<br>
> }<br>
><br>
> Or, using the `then`[3] pattern:<br>
><br>
> protocol Builder {}<br>
> extension Builder {<br>
> func then(body: Self.() -> ()) -> Self {<br>
> body()<br>
> return self<br>
> }<br>
> }<br>
> extension NSTask: Builder {}<br>
><br>
> let task = NSTask().then {<br>
> launchPath = "/usr/bin/mdfind"<br>
> arguments = ["kMDItemDisplayName == *.playground"]<br>
> standardOutput = pipe<br>
> }<br>
><br>
> How about BDD-style frameworks (like Quick/Nimble[4] and Spectre[5])?<br>
><br>
> describe("a person") {<br>
> let person = Person(name: "Kyle")<br>
><br>
> it("has a name") {<br>
> try expect(<a href="http://person.name" rel="noreferrer" target="_blank">person.name</a>) == "Kyle"<br>
> }<br>
> }<br>
><br>
> And HTML builders?<br>
><br>
> html {<br>
> head { title("Hello, World!") }<br>
> }<br>
><br>
> And block-based, transactional APIs?<br>
><br>
> db.inTransaction {<br>
> delete("users", "first_name = ?", ["Jake"])<br>
> }<br>
><br>
> The main benefits have been previously discussed:<br>
><br>
> 1. The ability to remove noise ("$0" everywhere)<br>
> 2. The ability to avoid defining globals (in favor of a safer, scoped interface)<br>
><br>
> Would such an enhancement be feasible?<br>
><br>
> ---<br>
> Stephen<br>
><br>
> Footnotes:<br>
><br>
> [1] A probably-incomplete list:<br>
> - "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">https://lists.swift.org/pipermail/swift-evolution/2015-December/000114.html</a><br>
> - "Request for Discussion: Setup closures": <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>
> - "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">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151130/000729.html</a><br>
> - "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">http://thread.gmane.org/gmane.comp.lang.swift.evolution/374</a><br>
> - "Lexical scope statement (with .. do)": <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>
> - "Scoped resources (like C# using statement)": <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>
> - "Customized Inline Init Closure": <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>
> - "Then Support": <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>
> - "Draft proposal: multi-property assignment .= operator": <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>
> - "Custom default names for arguments of closures": <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>
> - <a href="https://bugs.swift.org/browse/SR-160" rel="noreferrer" target="_blank">https://bugs.swift.org/browse/SR-160</a><br>
><br>
> [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>
> [3] <a href="https://github.com/devxoul/Then" rel="noreferrer" target="_blank">https://github.com/devxoul/Then</a><br>
> [4] <a href="https://github.com/Quick/Quick" rel="noreferrer" target="_blank">https://github.com/Quick/Quick</a><br>
> [5] <a href="https://github.com/kylef/Spectre" rel="noreferrer" target="_blank">https://github.com/kylef/Spectre</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>
<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>