<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="">Problem is that without the `in` you could conflict with custom defined operators.<div class=""><br class=""></div><div class="">Right now, you can go with</div><div class=""><br class=""></div><div class="">[1, 2, 3, 4, 5].map {</div><div class=""> $0 + 1</div><div class="">}</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Now assume a world where a user defined a custom postfix . or | operator.</div><div class=""><br class=""></div><div class="">var error = ""</div><div class="">someAsyncFunction() { error .</div><div class=""> // body</div><div class="">}</div><div class=""><br class=""></div><div class="">Is the "error" a named variable inside the closure, or the one used in the outer scope?</div><div class=""><br class=""></div><div class="">Is the . our custom postfix operator, or is it the delimiter between the argument list and the body?</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">With `in`, this problem cannot occur, as `in` cannot be used as an identifier.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Also don't forget about the whole mess when it starts with capture lists and explicit return type.</div><div class=""><br class=""></div><div class=""><div class=""><div class=""><div class=""><div class="">someAsyncFunction() { [capture list] (arg1: Arg1Type, arg2: Arg2Type, arg3: Arg3Type) -> ReturnType in</div><div class=""> // ...</div><div class="">}</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Etan</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""> </div><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 13 Dec 2015, at 15:36, Taras Zakharko via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><blockquote type="cite" class=""><div dir="ltr" class=""><div class="">On 13 Dec 2015, at 15:26, Marc Knaup <<a href="mailto:marc@knaup.koeln" class="">marc@knaup.koeln</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">How would you write this with the new syntax?</div></div></div></blockquote></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div dir="ltr" class=""><div class=""><div dir="ltr" class=""><br class=""></div></div><div dir="ltr" class=""><div class=""><blockquote type="cite" class=""><div class="">On 13 Dec 2015, at 09:42, Thorsten Seitz <<a href="mailto:tseitz42@icloud.com" class="">tseitz42@icloud.com</a>> wrote:</div><div class=""><div dir="auto" class=""><div class=""><br class=""></div><div class="">I don't think the syntax { x in ... } is a hindrance for your proposal of turning all code blocks into closures, as all code blocks currently have no arguments and in that case both variants look the same. All code blocks with the exception of function bodies but I think having these looking different is ok.</div></div></div></blockquote><div class=""><div class=""><div dir="auto" class=""><div class=""><br class=""></div><div class=""><br class=""></div></div></div></div></div></div></div></div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Point well taken :)</span><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">Other suggestions (out of top of my head) would be</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="">// lambda-calculus inspired, but potentially confusing</div><div class="">someAsyncFunction() { error .<br class=""> // …<br class="">}</div></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">// like above, kind of constructor notation, my personal favourite so far</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">someAsyncFunction() { error |<br class=""> // …<br class="">}</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">// lest idiosyncratic but also verbose and ugly</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">someAsyncFunction() func(error) { <br class=""> // …<br class="">}</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">But you are right of course that the syntax I proposed in the original mail does not work with these examples. Again, its more of a cosmetic thing anyway. I think the other point (streamlining the concept of closures in the language) is more important. </div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><blockquote type="cite" class=""><div class="">On 13 Dec 2015, at 09:42, Thorsten Seitz <<a href="mailto:tseitz42@icloud.com" class="">tseitz42@icloud.com</a>> wrote:</div></blockquote></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class="">Actually I was very surprised to see that your example with "local" returning a tuple did not work. The type inferencer should be able to infer the result type T to be a tuple without problems.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Yep, I was also quite surprised. But it does not work for me as of Xcode 7C68</div></div></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">Cheers, </div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"> Taras</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">P.S. Thorsten, sorry for wrong reply, I am not using mailing lists often and the behaviour of the mail client is a bit confusing. </div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 13 Dec 2015, at 15:26, Marc Knaup <<a href="mailto:marc@knaup.koeln" class="">marc@knaup.koeln</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">How would you write this with the new syntax?<div class=""><br class=""></div><div class=""><font face="monospace, monospace" class="">someAsyncFunction() { error in</font></div><div class=""><font face="monospace, monospace" class=""> // …</font></div><div class=""><font face="monospace, monospace" class="">}</font></div><div class=""><br class=""></div><div class="">This doesn't make sense (like Thorsten explained earlier):</div><div class=""><br class=""></div><div class=""><div class=""><font face="monospace, monospace" class="">someAsyncFunction() error {</font></div><div class=""><font face="monospace, monospace" class=""> // …</font></div><div class=""><font face="monospace, monospace" class="">}</font></div></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class="">I agree though that "in" is confusing and I never understood what "in" means here.</div><div class="">Since "do" is no longer used for loops but code blocks it would make sense to replace "in" with "do". </div><div class=""><br class=""></div><div class=""><div class=""><font face="monospace, monospace" class="">someAsyncFunction() { error do</font></div><div class=""><font face="monospace, monospace" class=""> // …</font></div><div class=""><font face="monospace, monospace" class="">}</font></div></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Sun, Dec 13, 2015 at 9:42 AM, Thorsten Seitz via swift-evolution <span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div dir="auto" class=""><div class=""></div><div class="">Hi Taras,</div><div class=""><br class=""></div><div class="">I don't think the syntax { x in ... } is a hindrance for your proposal of turning all code blocks into closures, as all code blocks currently have no arguments and in that case both variants look the same. All code blocks with the exception of function bodies but I think having these looking different is ok.</div><div class=""><br class=""></div><div class="">An advantage of the current syntax is that you can leave off the parentheses when calling a closure if it is the last argument which already enables the syntax you would like for "local":</div><div class=""><br class=""></div><div class="">let x = local {</div><div class=""> ...</div><div class="">}</div><div class=""><br class=""></div><div class="">This requires having the arguments inside the braces to allow for things like these:</div><div class=""><br class=""></div><div class="">someCollection.forEach { x in ... }</div><div class="">File.open("some/path") { file in ... } // having the file closed automatically</div><div class=""><br class=""></div><div class="">Such usage patterns would look awkward with arguments outside of the braces and they are very common and very useful.</div><div class=""><br class=""></div><div class="">Actually I was very surprised to see that your example with "local" returning a tuple did not work. The type inferencer should be able to infer the result type T to be a tuple without problems.</div><div class=""><br class=""></div><div class="">-Thorsten </div><div class=""><div class="h5"><div class=""><br class=""></div><div class="">Am 13.12.2015 um 05:14 schrieb Taras Zakharko via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>>:<br class=""><br class=""></div><blockquote type="cite" class=""><div class="">Dear all, <br class=""><br class="">first of all, thank you for giving the community the opportunity to influence the future of Swift. This is a strong move, which shows how passionate the Swift team is about their language and how you guys want to make it the best. <br class=""><br class="">Personally, I am a huge fan of streamlined, logically concise concepts as well as syntax in programming languages. This is an area where Swift both excels at (love what you do with types in the compiler) but also sometimes lacking, as there seems to be a lot of idiosyncrasy, as evident from the huge number of language keywords and compiler attributes. Here, I would like to discuss some of the idiosyncrasy with closures. As I am trying to throw some random ideas out there, my post might be a bit chaotic, so please bear with me. Besides, I literally started playing around with Swift only few hours ago (I know, I know, I’m late), so my practical knowledge of the language is very limited. <br class=""><br class="">1. I always wondered about the specific closure syntax { A -> B in … }. The type annotation is within the block for some reason and the there is the keyword ‘in’, which is usually associated with the for loop. My proposal would be to change this to simply:<br class=""><br class=""> A -> B { … }<br class=""><br class="">That is, the closure declaration closely mirrors the function declaration, but without the 'func name’ part. This is far from being just a cosmetic change though. Rather, it has some far-reaching consequences to how the concept of closure is applied to the language, but I believe that this would make Swift much more streamlined and concise (and also solve some other issues in the process). <br class=""><br class="">The crucial point is that the type annotation is (and should be) optional. Which means that every code block { … } is a closure. I think this fundamentally makes a lot of sense. So, a function declaration is just a closure associated with a name identifier (aka. injected into the namespace). Similarly, code blocks used in statements such as for and do have local lexical scope, which makes them essentially compatible closures as far as I can see. <br class=""><br class="">Essentially, this approach radically simplifies the language both from the syntax standpoint — closures and funcs are using the same syntax, the notion of code blocks is removed from the language; but also from the semantics standpoint. For instance, one can give more formal definitions for statements, which opens the path of treating statements as expressions (see <a href="https://lists.swift.org/pipermail/swift-evolution/2015-December/000133.html" target="_blank" class="">https://lists.swift.org/pipermail/swift-evolution/2015-December/000133.html</a>). For instance, current if is of type (Bool, ()->())->(), but it can easily be redeclared as (Bool, ()->T)->T, which opens way to nice things like <br class=""><br class=""> let x = if(…) { .. some complex setup code..; value1} else { … other code..; value2}<br class=""><br class="">Similarly, do can be used to incapsulate auxiliary computations in the local scope (see below).<br class=""><br class="">2. Another closure limitation is that return type inference does not work with longer closures (but they should). Here a particular use case. Due to my work, I program a lot with R (which is sometimes a neat language in its own right). A particular paradigm I find very useful is to use anonymous code blocks in local scope to prevent namespace pollution, e.g. (in R code)<br class=""><br class=""> dataset <- local({<br class=""> a <- some_computation<br class=""> b <- some_computation<br class=""><br class=""> a combined with b<br class="">})<br class=""><br class="">// a and b are not visible in the outer scope anymore<br class=""><br class="">In JavaScript, people often use anonymous functions for the same effect. The nice thing about this paradigm is that it allows one to properly isolate data dependency from each other, give the compiler a better sense of variable lifespan and overall make your code much nicer to read. Of course, in Swift this can be done with nested functions or closures, but its the question of aesthetics. At any rate, the R function is very easy to emulate in Swift:<br class=""><br class=""> func local<T>(closure: () -> T) -> T {<br class=""> return closure()<br class=""> }<br class=""><br class="">which works beautifully, e.g.<br class=""><br class=""> let (a1,a2) = local({return(1, 2)}<br class=""><br class="">However, if I want to use more complex code, I need to explicitly declare the closure type:<br class=""><br class=""> let (a1, a2) = local({ () -> (Int, Int) in<br class=""> let x2 = x*2<br class=""><br class=""> return (x2, x2+1)<br class=""> })<br class=""><br class=""><br class="">This is bulky, and frankly, unnecessary, as the compiler can easily infer the return type of the closure. <br class=""><br class="">BTW, combined with proposal in 1., this style of programming just becomes the beautiful<br class=""><br class="">let (a1, a2) = do {<br class=""> .. do something ..<br class=""> return(…, …) // or simply (…, …)<br class="">}<br class=""><br class=""><br class="">Summary TL;DR version of the proposal: <br class=""><br class="">replace the {A->B in …} closure syntax by A->B {…} — where type declaration is optional, remove the concept of code block (replace it by closure) and statements that take blocks/closures typed expressions. Improve type inference for return values. Current syntactic sugar for closures such as anonymous arguments and last line as return values should be preserved. <br class=""><br class="">Advantages: streamlines the language, solves a number of issues at the same time (idiosyncrasy, operators as expressions). In the end, makes the language easier to use and also to understand conceptually. <br class=""><br class="">Disadvantages: I honestly can’t see a single one<br class=""><br class="">Implementation challenge: would requires a parser change that might be non-trivial. I can also imagine that a lot of refactoring in the compiler code is necessary in regards to how statements work — but this might pay off as in the end, the compiler only needs to deal with closures and calls, which simplifies optimisation. And Swift is already great at aggressive inlining of closures. <br class=""><br class="">Impact on existing code: the syntax of closure declarations can be automatically ported as the rewrite rule is trivial. As far as I can see, changing code blocks to closures won’t have any impact on the semantics of the control structures, because the blocks are already using lexical scope. <br class=""><br class="">Eager to hear your thoughts on this!<br class=""><br class="">Cheers, <br class=""><br class="">Taras <span id="cid:3136A03D-D918-4EA6-82D3-9099CFADAA57"><open.gif></span></div></blockquote></div></div><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote><span id="cid:4971B40F-7237-4D67-A961-62AE9A8D8C15"><open.gif></span></div><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=""><br class=""></blockquote></div><br class=""></div></div></blockquote></div></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class="">On 13 Dec 2015, at 15:26, Marc Knaup <<a href="mailto:marc@knaup.koeln" class="">marc@knaup.koeln</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">How would you write this with the new syntax?<div class=""><br class=""></div><div class=""><font face="monospace, monospace" class="">someAsyncFunction() { error in</font></div><div class=""><font face="monospace, monospace" class=""> // …</font></div><div class=""><font face="monospace, monospace" class="">}</font></div><div class=""><br class=""></div><div class="">This doesn't make sense (like Thorsten explained earlier):</div><div class=""><br class=""></div><div class=""><div class=""><font face="monospace, monospace" class="">someAsyncFunction() error {</font></div><div class=""><font face="monospace, monospace" class=""> // …</font></div><div class=""><font face="monospace, monospace" class="">}</font></div></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div><div class="">I agree though that "in" is confusing and I never understood what "in" means here.</div><div class="">Since "do" is no longer used for loops but code blocks it would make sense to replace "in" with "do". </div><div class=""><br class=""></div><div class=""><div class=""><font face="monospace, monospace" class="">someAsyncFunction() { error do</font></div><div class=""><font face="monospace, monospace" class=""> // …</font></div><div class=""><font face="monospace, monospace" class="">}</font></div></div><div class=""><font face="monospace, monospace" class=""><br class=""></font></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Sun, Dec 13, 2015 at 9:42 AM, Thorsten Seitz via swift-evolution<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><div dir="auto" class=""><div class=""></div><div class="">Hi Taras,</div><div class=""><br class=""></div><div class="">I don't think the syntax { x in ... } is a hindrance for your proposal of turning all code blocks into closures, as all code blocks currently have no arguments and in that case both variants look the same. All code blocks with the exception of function bodies but I think having these looking different is ok.</div><div class=""><br class=""></div><div class="">An advantage of the current syntax is that you can leave off the parentheses when calling a closure if it is the last argument which already enables the syntax you would like for "local":</div><div class=""><br class=""></div><div class="">let x = local {</div><div class=""> ...</div><div class="">}</div><div class=""><br class=""></div><div class="">This requires having the arguments inside the braces to allow for things like these:</div><div class=""><br class=""></div><div class="">someCollection.forEach { x in ... }</div><div class="">File.open("some/path") { file in ... } // having the file closed automatically</div><div class=""><br class=""></div><div class="">Such usage patterns would look awkward with arguments outside of the braces and they are very common and very useful.</div><div class=""><br class=""></div><div class="">Actually I was very surprised to see that your example with "local" returning a tuple did not work. The type inferencer should be able to infer the result type T to be a tuple without problems.</div><div class=""><br class=""></div><div class="">-Thorsten </div><div class=""><div class="h5"><div class=""><br class=""></div><div class="">Am 13.12.2015 um 05:14 schrieb Taras Zakharko via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>>:<br class=""><br class=""></div><blockquote type="cite" class=""><div class="">Dear all, <br class=""><br class="">first of all, thank you for giving the community the opportunity to influence the future of Swift. This is a strong move, which shows how passionate the Swift team is about their language and how you guys want to make it the best. <br class=""><br class="">Personally, I am a huge fan of streamlined, logically concise concepts as well as syntax in programming languages. This is an area where Swift both excels at (love what you do with types in the compiler) but also sometimes lacking, as there seems to be a lot of idiosyncrasy, as evident from the huge number of language keywords and compiler attributes. Here, I would like to discuss some of the idiosyncrasy with closures. As I am trying to throw some random ideas out there, my post might be a bit chaotic, so please bear with me. Besides, I literally started playing around with Swift only few hours ago (I know, I know, I’m late), so my practical knowledge of the language is very limited. <br class=""><br class="">1. I always wondered about the specific closure syntax { A -> B in … }. The type annotation is within the block for some reason and the there is the keyword ‘in’, which is usually associated with the for loop. My proposal would be to change this to simply:<br class=""><br class=""> A -> B { … }<br class=""><br class="">That is, the closure declaration closely mirrors the function declaration, but without the 'func name’ part. This is far from being just a cosmetic change though. Rather, it has some far-reaching consequences to how the concept of closure is applied to the language, but I believe that this would make Swift much more streamlined and concise (and also solve some other issues in the process). <br class=""><br class="">The crucial point is that the type annotation is (and should be) optional. Which means that every code block { … } is a closure. I think this fundamentally makes a lot of sense. So, a function declaration is just a closure associated with a name identifier (aka. injected into the namespace). Similarly, code blocks used in statements such as for and do have local lexical scope, which makes them essentially compatible closures as far as I can see. <br class=""><br class="">Essentially, this approach radically simplifies the language both from the syntax standpoint — closures and funcs are using the same syntax, the notion of code blocks is removed from the language; but also from the semantics standpoint. For instance, one can give more formal definitions for statements, which opens the path of treating statements as expressions (see <a href="https://lists.swift.org/pipermail/swift-evolution/2015-December/000133.html" target="_blank" class="">https://lists.swift.org/pipermail/swift-evolution/2015-December/000133.html</a>). For instance, current if is of type (Bool, ()->())->(), but it can easily be redeclared as (Bool, ()->T)->T, which opens way to nice things like <br class=""><br class=""> let x = if(…) { .. some complex setup code..; value1} else { … other code..; value2}<br class=""><br class="">Similarly, do can be used to incapsulate auxiliary computations in the local scope (see below).<br class=""><br class="">2. Another closure limitation is that return type inference does not work with longer closures (but they should). Here a particular use case. Due to my work, I program a lot with R (which is sometimes a neat language in its own right). A particular paradigm I find very useful is to use anonymous code blocks in local scope to prevent namespace pollution, e.g. (in R code)<br class=""><br class=""> dataset <- local({<br class=""> a <- some_computation<br class=""> b <- some_computation<br class=""><br class=""> a combined with b<br class="">})<br class=""><br class="">// a and b are not visible in the outer scope anymore<br class=""><br class="">In JavaScript, people often use anonymous functions for the same effect. The nice thing about this paradigm is that it allows one to properly isolate data dependency from each other, give the compiler a better sense of variable lifespan and overall make your code much nicer to read. Of course, in Swift this can be done with nested functions or closures, but its the question of aesthetics. At any rate, the R function is very easy to emulate in Swift:<br class=""><br class=""> func local<T>(closure: () -> T) -> T {<br class=""> return closure()<br class=""> }<br class=""><br class="">which works beautifully, e.g.<br class=""><br class=""> let (a1,a2) = local({return(1, 2)}<br class=""><br class="">However, if I want to use more complex code, I need to explicitly declare the closure type:<br class=""><br class=""> let (a1, a2) = local({ () -> (Int, Int) in<br class=""> let x2 = x*2<br class=""><br class=""> return (x2, x2+1)<br class=""> })<br class=""><br class=""><br class="">This is bulky, and frankly, unnecessary, as the compiler can easily infer the return type of the closure. <br class=""><br class="">BTW, combined with proposal in 1., this style of programming just becomes the beautiful<br class=""><br class="">let (a1, a2) = do {<br class=""> .. do something ..<br class=""> return(…, …) // or simply (…, …)<br class="">}<br class=""><br class=""><br class="">Summary TL;DR version of the proposal: <br class=""><br class="">replace the {A->B in …} closure syntax by A->B {…} — where type declaration is optional, remove the concept of code block (replace it by closure) and statements that take blocks/closures typed expressions. Improve type inference for return values. Current syntactic sugar for closures such as anonymous arguments and last line as return values should be preserved. <br class=""><br class="">Advantages: streamlines the language, solves a number of issues at the same time (idiosyncrasy, operators as expressions). In the end, makes the language easier to use and also to understand conceptually. <br class=""><br class="">Disadvantages: I honestly can’t see a single one<br class=""><br class="">Implementation challenge: would requires a parser change that might be non-trivial. I can also imagine that a lot of refactoring in the compiler code is necessary in regards to how statements work — but this might pay off as in the end, the compiler only needs to deal with closures and calls, which simplifies optimisation. And Swift is already great at aggressive inlining of closures. <br class=""><br class="">Impact on existing code: the syntax of closure declarations can be automatically ported as the rewrite rule is trivial. As far as I can see, changing code blocks to closures won’t have any impact on the semantics of the control structures, because the blocks are already using lexical scope. <br class=""><br class="">Eager to hear your thoughts on this!<br class=""><br class="">Cheers, <br class=""><br class="">Taras<span class="Apple-converted-space"> </span><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=1MXK54sosN3xru3iYcLt0oBZ2w20i49gyogXctgrspd6a6Hj7ZQ6DWm2MZfIp6hnlGxPNZECuHLcwpV8vAhmdADPgafzH4LXjUYJQ-2BcXuF39-2B-2FAxpV-2BbM3TJdjFqM5mE-2BysFi-2BOste-2BAFK9m3P7h8YV4AvO-2BFWUp8SCb72QovA8sYXr-2FpeBY9S-2B6GJ88QGSGbx-2BoYj56tzKSzK1uwmRppcoPLANoMK1LWFO-2FBa0KKzY-3D" alt="" width="1" height="1" border="0" class="" style="min-height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;"></div></blockquote></div></div><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=6ZGE61OxINd5lLe2xYh9Ku-2BXbixWNr2nvfzp2IB1sZhJ2e6gJiKjAo2cdTmI-2B7zmqozymj-2BPNLj5OlRXsyZgHyPV15SLLd-2Fux-2Fjxtf-2FXIqLdffxtx9RmXg72gMxEXd-2B1mOYMwCJeS1zN6aRiydy7b1WRFngeqZiEwUTVfEzRIgC-2Fk22XKcSCYyTaYQ1TDh73cFL21yow5AuFTs-2FknPoo9wTtsw-2FZB09t-2FQ3IuaEd-2BFQ-3D" alt="" width="1" height="1" border="0" class="" style="min-height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;"></div><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=""><br class=""></blockquote></div><br class=""></div></div></blockquote></div><br class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=tTTJ5sn5y0uc3ODSZa-2BndLNwXCDS7T2cq5OlDDhG0RtI27iIcXse3SqHAyRx96y0VJanc5PicE-2FnJtx-2FZUQ5KdcwkzwnBwlWRE60UxkCXrzaoENoPsk0R79MBR9EudfksD3WDpqJYk58Imkn1-2FWDGtDjjI2PR4gmWHwi59xHmOURFFEQTqpk-2F3lNIt-2B1lxkz3K9rLURMnNGD6v12YBKCHKC6rrtVoP5Oa9Z3NnxOGDQ-3D" alt="" width="1" height="1" border="0" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class=""><span class="Apple-converted-space"> </span></span><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">swift-evolution mailing list</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="mailto:swift-evolution@swift.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">swift-evolution@swift.org</a><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br class=""></div></div></div></div></div></body></html>