Lambda function syntax


(Alexander Regueiro) #1

Does anyone not like the current syntax for this?

I would propose changing it from:

{ (param_list) -> return_type in … }

to something cleaner like:

(param_list) -> return_type => { … }

where I’m not so bothered about the `=>` separator (could be `:`, `,`, or indeed `in`).

The braces being around the type specifier as well as function body rather bothers me. Surely it would be more consistent just to have the braces around the function body, and then the type specifier preceding this?

Alternate syntaxes welcome, but I think the suggestion above already represents a significant improvement.


(Chris Lattner) #2

Hi Alexander,

We’re open in principle to replacing closure syntax with something better, but A) it needs to be actually better, and B) it needs to fit with the swift grammar. If you’re interested in pushing forward in this area, please familiarize yourself with the structure of the grammar and propose what you’re thinking in terms of a diff to it. Thanks,

-Chris

···

On Dec 21, 2015, at 11:20 AM, Alexander Regueiro via swift-evolution <swift-evolution@swift.org> wrote:

Does anyone not like the current syntax for this?

I would propose changing it from:

{ (param_list) -> return_type in … }

to something cleaner like:

(param_list) -> return_type => { … }

where I’m not so bothered about the `=>` separator (could be `:`, `,`, or indeed `in`).

The braces being around the type specifier as well as function body rather bothers me. Surely it would be more consistent just to have the braces around the function body, and then the type specifier preceding this?


(Alexander Regueiro) #3

Hi Chris,

Don’t you think the suggestion is better? I’m happy to formula it in terms of an E(BNF) grammar if you like. Is this published/available anywhere, for the current version of Swift?

Thanks.

···

On 21 Dec 2015, at 19:22, Chris Lattner <clattner@apple.com> wrote:

On Dec 21, 2015, at 11:20 AM, Alexander Regueiro via swift-evolution <swift-evolution@swift.org> wrote:

Does anyone not like the current syntax for this?

I would propose changing it from:

{ (param_list) -> return_type in … }

to something cleaner like:

(param_list) -> return_type => { … }

where I’m not so bothered about the `=>` separator (could be `:`, `,`, or indeed `in`).

The braces being around the type specifier as well as function body rather bothers me. Surely it would be more consistent just to have the braces around the function body, and then the type specifier preceding this?

Hi Alexander,

We’re open in principle to replacing closure syntax with something better, but A) it needs to be actually better, and B) it needs to fit with the swift grammar. If you’re interested in pushing forward in this area, please familiarize yourself with the structure of the grammar and propose what you’re thinking in terms of a diff to it. Thanks,

-Chris


(Rob Mayoff) #4

The braces being around the type specifier as well as function body rather
bothers me. Surely it would be more consistent just to have the braces
around the function body, and then the type specifier preceding this?

If you mean consistency between closures and function declarations,
wouldn't it be simpler to go the other way?

    func tableView { (tableView: UITableView, cellForRowAtIndexPath
indexPath: NSIndexPath) -> UITableViewCell in
        ...
    }


(Chris Lattner) #5

Hi Chris,

Don’t you think the suggestion is better? I’m happy to formula it in terms of an E(BNF) grammar if you like. Is this published/available anywhere, for the current version of Swift?

My personal opinion is “no”, because it will look very weird in trailing closure, in the argument lists for function calls, etc.

Further, it would not permit dropping ()’s on closure arguments, you wouldn’t be able to write this:

foo({ lhs, rhs in … })

because the comma would be exposed out to the function call.

The grammar is described in the reference section of TSPL:

In addition to proposing EBNF, please consider the existing grammar so that the new proposal isn’t completely ambiguous. What you are proposing would be an extremely tricky thing to do.

-Chris

···

On Dec 21, 2015, at 1:33 PM, Alexander Regueiro <alexreg@gmail.com> wrote:

Thanks.

On 21 Dec 2015, at 19:22, Chris Lattner <clattner@apple.com> wrote:

On Dec 21, 2015, at 11:20 AM, Alexander Regueiro via swift-evolution <swift-evolution@swift.org> wrote:

Does anyone not like the current syntax for this?

I would propose changing it from:

{ (param_list) -> return_type in … }

to something cleaner like:

(param_list) -> return_type => { … }

where I’m not so bothered about the `=>` separator (could be `:`, `,`, or indeed `in`).

The braces being around the type specifier as well as function body rather bothers me. Surely it would be more consistent just to have the braces around the function body, and then the type specifier preceding this?

Hi Alexander,

We’re open in principle to replacing closure syntax with something better, but A) it needs to be actually better, and B) it needs to fit with the swift grammar. If you’re interested in pushing forward in this area, please familiarize yourself with the structure of the grammar and propose what you’re thinking in terms of a diff to it. Thanks,

-Chris


(Alexander Regueiro) #6

Thanks for clarifying.

In that case, I would propose grammar for capture expressions, which should drop in without modifications elsewhere (I say tentatively):

closure-expression → “func" closure-signature_opt { statements }
‌ closure-signature → parameter-clause function-result_opt
‌ closure-signature → identifier-list function-result_opt
‌ closure-signature → capture-list parameter-clause function-result_opt
‌ closure-signature → capture-list identifier-list function-result_opt
‌ closure-signature → capture-list
‌ capture-list → [ capture-list-items ]
‌ capture-list-items → capture-list-item | capture-list-item , capture-list-items
‌ capture-list-item → capture-specifier_opt expression
‌ capture-specifier → weak | unowned | unowned(safe) | unowned(unsafe)

I am open to whether the introducing keyword is “func” (overloading the existing keyword but in an evidently separate context, and unambiguously I believe) – or “lambda” (like Python), or “\” (like Haskell) – or even something like “cl” (for Closure). Note that the aforementioned adds an additional keyword, but also removes the the “in” keyword. For reasons mentioned in my previous message, I believe this syntax is both clearer and more consistent. It’s also more in line with other widespread languages (in my experience).

For reference, the current grammar is:

closure-expression → { closure-signature_opt statements }
‌ closure-signature → parameter-clause function-result_opt “in"
‌ closure-signature → identifier-list function-result_opt “in"
‌ closure-signature → capture-list parameter-clause function-result_opt “in"
‌ closure-signature → capture-list identifier-list function-result_opt "in"
‌ closure-signature → capture-list “in"
‌ capture-list → [ capture-list-items ]
‌ capture-list-items → capture-list-item | capture-list-item , capture-list-items
‌ capture-list-item → capture-specifier_opt expression
‌ capture-specifier → weak | unowned | unowned(safe) | unowned(unsafe)

Also, I didn’t bother making braces optional, since I hear that the original language designers wanted to avoid the problems that optional braces have the potential to introduce (e.g. in C-style languages). There are no round brackets used in my above syntax either, which is consistent with their absence in expressions in conditional and loop statements.

Thoughts?

···

On 21 Dec 2015, at 21:47, Chris Lattner <clattner@apple.com> wrote:

On Dec 21, 2015, at 1:33 PM, Alexander Regueiro <alexreg@gmail.com> wrote:

Hi Chris,

Don’t you think the suggestion is better? I’m happy to formula it in terms of an E(BNF) grammar if you like. Is this published/available anywhere, for the current version of Swift?

My personal opinion is “no”, because it will look very weird in trailing closure, in the argument lists for function calls, etc.

Further, it would not permit dropping ()’s on closure arguments, you wouldn’t be able to write this:

foo({ lhs, rhs in … })

because the comma would be exposed out to the function call.

The grammar is described in the reference section of TSPL:
https://swift.org/documentation/

In addition to proposing EBNF, please consider the existing grammar so that the new proposal isn’t completely ambiguous. What you are proposing would be an extremely tricky thing to do.

-Chris

Thanks.

On 21 Dec 2015, at 19:22, Chris Lattner <clattner@apple.com> wrote:

On Dec 21, 2015, at 11:20 AM, Alexander Regueiro via swift-evolution <swift-evolution@swift.org> wrote:

Does anyone not like the current syntax for this?

I would propose changing it from:

{ (param_list) -> return_type in … }

to something cleaner like:

(param_list) -> return_type => { … }

where I’m not so bothered about the `=>` separator (could be `:`, `,`, or indeed `in`).

The braces being around the type specifier as well as function body rather bothers me. Surely it would be more consistent just to have the braces around the function body, and then the type specifier preceding this?

Hi Alexander,

We’re open in principle to replacing closure syntax with something better, but A) it needs to be actually better, and B) it needs to fit with the swift grammar. If you’re interested in pushing forward in this area, please familiarize yourself with the structure of the grammar and propose what you’re thinking in terms of a diff to it. Thanks,

-Chris


(Alexander Regueiro) #7

N.B. My previous observation would also rely on return being optional (at least for single-line nested functions / closures). I believe that making return statements optional at the end of a function is already being considered under another proposal.

···

On 21 Dec 2015, at 21:47, Chris Lattner <clattner@apple.com> wrote:

On Dec 21, 2015, at 1:33 PM, Alexander Regueiro <alexreg@gmail.com> wrote:

Hi Chris,

Don’t you think the suggestion is better? I’m happy to formula it in terms of an E(BNF) grammar if you like. Is this published/available anywhere, for the current version of Swift?

My personal opinion is “no”, because it will look very weird in trailing closure, in the argument lists for function calls, etc.

Further, it would not permit dropping ()’s on closure arguments, you wouldn’t be able to write this:

foo({ lhs, rhs in … })

because the comma would be exposed out to the function call.

The grammar is described in the reference section of TSPL:
https://swift.org/documentation/

In addition to proposing EBNF, please consider the existing grammar so that the new proposal isn’t completely ambiguous. What you are proposing would be an extremely tricky thing to do.

-Chris

Thanks.

On 21 Dec 2015, at 19:22, Chris Lattner <clattner@apple.com> wrote:

On Dec 21, 2015, at 11:20 AM, Alexander Regueiro via swift-evolution <swift-evolution@swift.org> wrote:

Does anyone not like the current syntax for this?

I would propose changing it from:

{ (param_list) -> return_type in … }

to something cleaner like:

(param_list) -> return_type => { … }

where I’m not so bothered about the `=>` separator (could be `:`, `,`, or indeed `in`).

The braces being around the type specifier as well as function body rather bothers me. Surely it would be more consistent just to have the braces around the function body, and then the type specifier preceding this?

Hi Alexander,

We’re open in principle to replacing closure syntax with something better, but A) it needs to be actually better, and B) it needs to fit with the swift grammar. If you’re interested in pushing forward in this area, please familiarize yourself with the structure of the grammar and propose what you’re thinking in terms of a diff to it. Thanks,

-Chris


(Chris Lattner) #8

Thanks for clarifying.

In that case, I would propose grammar for capture expressions, which should drop in without modifications elsewhere (I say tentatively):

closure-expression → “func" closure-signature_opt { statements }

If you dig through (very early) history you’ll see that we had this. There are a couple of problems with it:

1) It punishes simple cases like “X.sort { $1 < $0 }”, along with lots of simple map and filter closures.
2) It reads really weird in trailing closure cases.

Lets step back: What problems are you trying to solve with the current closure syntax?

-Chris

···

On Dec 21, 2015, at 2:26 PM, Alexander Regueiro <alexreg@gmail.com> wrote:

‌ closure-signature → parameter-clause function-result_opt
‌ closure-signature → identifier-list function-result_opt
‌ closure-signature → capture-list parameter-clause function-result_opt
‌ closure-signature → capture-list identifier-list function-result_opt
‌ closure-signature → capture-list
‌ capture-list → [ capture-list-items ]
‌ capture-list-items → capture-list-item | capture-list-item , capture-list-items
‌ capture-list-item → capture-specifier_opt expression
‌ capture-specifier → weak | unowned | unowned(safe) | unowned(unsafe)

I am open to whether the introducing keyword is “func” (overloading the existing keyword but in an evidently separate context, and unambiguously I believe) – or “lambda” (like Python), or “\” (like Haskell) – or even something like “cl” (for Closure). Note that the aforementioned adds an additional keyword, but also removes the the “in” keyword. For reasons mentioned in my previous message, I believe this syntax is both clearer and more consistent. It’s also more in line with other widespread languages (in my experience).

For reference, the current grammar is:

closure-expression → { closure-signature_opt statements }
‌ closure-signature → parameter-clause function-result_opt “in"
‌ closure-signature → identifier-list function-result_opt “in"
‌ closure-signature → capture-list parameter-clause function-result_opt “in"
‌ closure-signature → capture-list identifier-list function-result_opt "in"
‌ closure-signature → capture-list “in"
‌ capture-list → [ capture-list-items ]
‌ capture-list-items → capture-list-item | capture-list-item , capture-list-items
‌ capture-list-item → capture-specifier_opt expression
‌ capture-specifier → weak | unowned | unowned(safe) | unowned(unsafe)

Also, I didn’t bother making braces optional, since I hear that the original language designers wanted to avoid the problems that optional braces have the potential to introduce (e.g. in C-style languages). There are no round brackets used in my above syntax either, which is consistent with their absence in expressions in conditional and loop statements.

Thoughts?

On 21 Dec 2015, at 21:47, Chris Lattner <clattner@apple.com> wrote:

On Dec 21, 2015, at 1:33 PM, Alexander Regueiro <alexreg@gmail.com> wrote:

Hi Chris,

Don’t you think the suggestion is better? I’m happy to formula it in terms of an E(BNF) grammar if you like. Is this published/available anywhere, for the current version of Swift?

My personal opinion is “no”, because it will look very weird in trailing closure, in the argument lists for function calls, etc.

Further, it would not permit dropping ()’s on closure arguments, you wouldn’t be able to write this:

foo({ lhs, rhs in … })

because the comma would be exposed out to the function call.

The grammar is described in the reference section of TSPL:
https://swift.org/documentation/

In addition to proposing EBNF, please consider the existing grammar so that the new proposal isn’t completely ambiguous. What you are proposing would be an extremely tricky thing to do.

-Chris

Thanks.

On 21 Dec 2015, at 19:22, Chris Lattner <clattner@apple.com> wrote:

On Dec 21, 2015, at 11:20 AM, Alexander Regueiro via swift-evolution <swift-evolution@swift.org> wrote:

Does anyone not like the current syntax for this?

I would propose changing it from:

{ (param_list) -> return_type in … }

to something cleaner like:

(param_list) -> return_type => { … }

where I’m not so bothered about the `=>` separator (could be `:`, `,`, or indeed `in`).

The braces being around the type specifier as well as function body rather bothers me. Surely it would be more consistent just to have the braces around the function body, and then the type specifier preceding this?

Hi Alexander,

We’re open in principle to replacing closure syntax with something better, but A) it needs to be actually better, and B) it needs to fit with the swift grammar. If you’re interested in pushing forward in this area, please familiarize yourself with the structure of the grammar and propose what you’re thinking in terms of a diff to it. Thanks,

-Chris


(Alexander Regueiro) #9

Okay, I assume you are aware this essentially the same syntax as used in languages like C# and Python, yes? I’m not sure there are any problems in those languages with it.

If you dig through (very early) history you’ll see that we had this. There are a couple of problems with it:

1) It punishes simple cases like “X.sort { $1 < $0 }”, along with lots of simple map and filter closures.

Not really. The above example would just be `X.sort func { $1 < $0 }” or "X.sort \ { $1 < $0 }` in my proposed syntax. Also, it would be nice to have all operators implicitly convertible to functions, or at the very least have corresponding function definitions for all built-in & standard library operators. Haskell does this really nicely (functions and operators are basically interchangeable, and either can be used in prefix or infix mode). Anyway, your above example might look something like `X.sort (>)` (since `(<)` would take arguments in the opposite order).

2) It reads really weird in trailing closure cases.

Honestly, I strongly dislike trailing closures. I don’t think they add much, and moreover they use a confusing syntax that make the whole function call look superficially like a function declaration (or indeed the whole thing being a closure).

Lets step back: What problems are you trying to solve with the current closure syntax?

Readability, mainly. I think this is a big improvement. Also, consistency of semantics. Everything else between curly braces represents a list of statements and is conceptually the “body” of something (a function, a conditional, a loop). The current closure syntax rather embeds the head into the body! Then there’s similarity with other languages, which is minor, but nice. I don’t know any language that uses a syntax like the current one of Swift.


(Tino) #10

am open to whether the introducing keyword is “func” (overloading the existing keyword but in an evidently separate context, and unambiguously I believe) – or “lambda” (like Python), or “\” (like Haskell) – or even something like “cl” (for Closure).

The cool thing with Swift compared to other languages:
Apple could leave out surrogates and just change the key bindings for λ :wink:

Me to had some instinctive repulsion against putting arguments inside the curly braces, but it has benefits, and I bet it would be tough to change such a fundamental part of the language now


(Alexander Regueiro) #11

I just thought, another way of looking at this proposal is by merging the nested function and closure expression features. Or rather, simply removing current closure syntax and allowing nested functions to be specified inline (and adding capture support to nested functions). This would not only simplify the language, but improve style, in quite an elegant way.

···

On 21 Dec 2015, at 22:26, Alexander Regueiro <alexreg@gmail.com> wrote:

Thanks for clarifying.

In that case, I would propose grammar for capture expressions, which should drop in without modifications elsewhere (I say tentatively):

closure-expression → “func" closure-signature_opt { statements }
‌ closure-signature → parameter-clause function-result_opt
‌ closure-signature → identifier-list function-result_opt
‌ closure-signature → capture-list parameter-clause function-result_opt
‌ closure-signature → capture-list identifier-list function-result_opt
‌ closure-signature → capture-list
‌ capture-list → [ capture-list-items ]
‌ capture-list-items → capture-list-item | capture-list-item , capture-list-items
‌ capture-list-item → capture-specifier_opt expression
‌ capture-specifier → weak | unowned | unowned(safe) | unowned(unsafe)

I am open to whether the introducing keyword is “func” (overloading the existing keyword but in an evidently separate context, and unambiguously I believe) – or “lambda” (like Python), or “\” (like Haskell) – or even something like “cl” (for Closure). Note that the aforementioned adds an additional keyword, but also removes the the “in” keyword. For reasons mentioned in my previous message, I believe this syntax is both clearer and more consistent. It’s also more in line with other widespread languages (in my experience).

For reference, the current grammar is:

closure-expression → { closure-signature_opt statements }
‌ closure-signature → parameter-clause function-result_opt “in"
‌ closure-signature → identifier-list function-result_opt “in"
‌ closure-signature → capture-list parameter-clause function-result_opt “in"
‌ closure-signature → capture-list identifier-list function-result_opt "in"
‌ closure-signature → capture-list “in"
‌ capture-list → [ capture-list-items ]
‌ capture-list-items → capture-list-item | capture-list-item , capture-list-items
‌ capture-list-item → capture-specifier_opt expression
‌ capture-specifier → weak | unowned | unowned(safe) | unowned(unsafe)

Also, I didn’t bother making braces optional, since I hear that the original language designers wanted to avoid the problems that optional braces have the potential to introduce (e.g. in C-style languages). There are no round brackets used in my above syntax either, which is consistent with their absence in expressions in conditional and loop statements.

Thoughts?

On 21 Dec 2015, at 21:47, Chris Lattner <clattner@apple.com> wrote:

On Dec 21, 2015, at 1:33 PM, Alexander Regueiro <alexreg@gmail.com> wrote:

Hi Chris,

Don’t you think the suggestion is better? I’m happy to formula it in terms of an E(BNF) grammar if you like. Is this published/available anywhere, for the current version of Swift?

My personal opinion is “no”, because it will look very weird in trailing closure, in the argument lists for function calls, etc.

Further, it would not permit dropping ()’s on closure arguments, you wouldn’t be able to write this:

foo({ lhs, rhs in … })

because the comma would be exposed out to the function call.

The grammar is described in the reference section of TSPL:
https://swift.org/documentation/

In addition to proposing EBNF, please consider the existing grammar so that the new proposal isn’t completely ambiguous. What you are proposing would be an extremely tricky thing to do.

-Chris

Thanks.

On 21 Dec 2015, at 19:22, Chris Lattner <clattner@apple.com> wrote:

On Dec 21, 2015, at 11:20 AM, Alexander Regueiro via swift-evolution <swift-evolution@swift.org> wrote:

Does anyone not like the current syntax for this?

I would propose changing it from:

{ (param_list) -> return_type in … }

to something cleaner like:

(param_list) -> return_type => { … }

where I’m not so bothered about the `=>` separator (could be `:`, `,`, or indeed `in`).

The braces being around the type specifier as well as function body rather bothers me. Surely it would be more consistent just to have the braces around the function body, and then the type specifier preceding this?

Hi Alexander,

We’re open in principle to replacing closure syntax with something better, but A) it needs to be actually better, and B) it needs to fit with the swift grammar. If you’re interested in pushing forward in this area, please familiarize yourself with the structure of the grammar and propose what you’re thinking in terms of a diff to it. Thanks,

-Chris


(Chris Lattner) #12

Okay, I assume you are aware this essentially the same syntax as used in languages like C# and Python, yes? I’m not sure there are any problems in those languages with it.

If you dig through (very early) history you’ll see that we had this. There are a couple of problems with it:

1) It punishes simple cases like “X.sort { $1 < $0 }”, along with lots of simple map and filter closures.

Not really. The above example would just be `X.sort func { $1 < $0 }” or "X.sort \ { $1 < $0 }` in my proposed syntax. Also, it would be nice to have all operators implicitly convertible to functions, or at the very least have corresponding function definitions for all built-in & standard library operators. Haskell does this really nicely (functions and operators are basically interchangeable, and either can be used in prefix or infix mode). Anyway, your above example might look something like `X.sort (>)` (since `(<)` would take arguments in the opposite order).

Swift already supports this. X.sort(>) works fine today. I don’t think that that detracts from the point, since there are lots of other simple closures :-)

2) It reads really weird in trailing closure cases.

Honestly, I strongly dislike trailing closures. I don’t think they add much, and moreover they use a confusing syntax that make the whole function call look superficially like a function declaration (or indeed the whole thing being a closure).

Ok, but you’re going to have to grapple with the fact that they are an important aspect of swift design. If you want your proposal to be seriously considered, it needs to consider them.

Lets step back: What problems are you trying to solve with the current closure syntax?

Readability, mainly. I think this is a big improvement. Also, consistency of semantics. Everything else between curly braces represents a list of statements and is conceptually the “body” of something (a function, a conditional, a loop). The current closure syntax rather embeds the head into the body! Then there’s similarity with other languages, which is minor, but nice. I don’t know any language that uses a syntax like the current one of Swift.

Since your recent proposal has serious tradeoffs, you should explain how each of the changes it forces measures on this.

Further, keep in mind that swift supports nested functions, which yield a very similar experience to what you’re proposing.

-Chris

···

On Dec 21, 2015, at 2:44 PM, Alexander Regueiro <alexreg@gmail.com> wrote:


(Thorsten Seitz) #13

Well, I'm actually happy with the current closure syntax as it allows very succinct simple cases and trailing closures as Chris has already pointed out.

Okay, I assume you are aware this essentially the same syntax as used in languages like C# and Python, yes? I’m not sure there are any problems in those languages with it.

If you dig through (very early) history you’ll see that we had this. There are a couple of problems with it:

1) It punishes simple cases like “X.sort { $1 < $0 }”, along with lots of simple map and filter closures.

Not really. The above example would just be `X.sort func { $1 < $0 }” or "X.sort \ { $1 < $0 }` in my proposed syntax. Also, it would be nice to have all operators implicitly

Having "func" or the backslash crammed in there is really ugly and unreadable IMHO.

And in Haskell you don't have braces for the body to begin with and you would have to enclose the closure in parenthesis if it is part of an expression like your examples so in effect it would look quite similar, i.e. having the parameters within the parenthesis (sure, the semantics are different, but I made argument just to demonstrate that what looks good in one syntactic environment might not look good in another).

2) It reads really weird in trailing closure cases.

Honestly, I strongly dislike trailing closures. I don’t think they add much, and moreover they use a confusing syntax that make the whole function call look superficially like a function declaration (or indeed the whole thing being a closure).

Trailing closures are a great feature IMHO because they make the code much more readable by allowing constructs to look similar to control flow statements.
This allows creating very readable DSLs.

Lets step back: What problems are you trying to solve with the current closure syntax?

Readability, mainly. I think this is a big improvement.

Well, I think it's the opposite for the simple cases and for trailing closures.

Then there’s similarity with other languages, which is minor, but nice. I don’t know any language that uses a syntax like the current one of Swift.

Smalltalk and Ruby immediately come to mind and I'm sure there are others.

Scala has a trailing closure syntax which is similar to Swift's syntax as well.

-Thorsten

···

Am 21.12.2015 um 23:44 schrieb Alexander Regueiro via swift-evolution <swift-evolution@swift.org>:


(Daniel Valls Estella) #14

Just to add my point of view as language user. I don’t know so much about compilers and neither have many familiarity with language grammars. I like to learn, and this list helps.

I think clousures are strangely written and break some coherence. I agree with Alexander on that.
But I don’t like the proposed solution.

In the other side, I think trailing closures are a really a great feature, I like a lot.
But I feel it’s a bit confusing in some way, as Alexander pointed. As if it was the body definition of the called function.

To throw an idea, the with keyword:

with ( parameters ) -> return_type {
    statements
}

sorted = names.sort( with(s1: String, s2: String) -> Bool {
    return s1 > s2
})

sorted = names.sort( with(s1, s2){ return s1 > s2 } )

reversed = names.sort( with(s1, s2){ s1 > s2 } )

reversed = names.sort( { $0 > $1 } )
OR? reversed = names.sort( with{ $0 > $1 } )

reversed = names.sort(>)
OR? reversed = names.sort(with >)

reversed = names.sort() with { $0 > $1 } // I think clarifies it is an input to exeute not a definition

reversed = names.sort with { $0 > $1 } // I think clarifies it is an input to exeute not a definition

Thanks!

Daniel

Daniel Valls Estella · tel. 659.910.830 · daniel@upzzle.com

···

El 22 des 2015, a les 7:57, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> va escriure:

Well, I'm actually happy with the current closure syntax as it allows very succinct simple cases and trailing closures as Chris has already pointed out.

Am 21.12.2015 um 23:44 schrieb Alexander Regueiro via swift-evolution <swift-evolution@swift.org>:

Okay, I assume you are aware this essentially the same syntax as used in languages like C# and Python, yes? I’m not sure there are any problems in those languages with it.

If you dig through (very early) history you’ll see that we had this. There are a couple of problems with it:

1) It punishes simple cases like “X.sort { $1 < $0 }”, along with lots of simple map and filter closures.

Not really. The above example would just be `X.sort func { $1 < $0 }” or "X.sort \ { $1 < $0 }` in my proposed syntax. Also, it would be nice to have all operators implicitly

Having "func" or the backslash crammed in there is really ugly and unreadable IMHO.

And in Haskell you don't have braces for the body to begin with and you would have to enclose the closure in parenthesis if it is part of an expression like your examples so in effect it would look quite similar, i.e. having the parameters within the parenthesis (sure, the semantics are different, but I made argument just to demonstrate that what looks good in one syntactic environment might not look good in another).

2) It reads really weird in trailing closure cases.

Honestly, I strongly dislike trailing closures. I don’t think they add much, and moreover they use a confusing syntax that make the whole function call look superficially like a function declaration (or indeed the whole thing being a closure).

Trailing closures are a great feature IMHO because they make the code much more readable by allowing constructs to look similar to control flow statements.
This allows creating very readable DSLs.

Lets step back: What problems are you trying to solve with the current closure syntax?

Readability, mainly. I think this is a big improvement.

Well, I think it's the opposite for the simple cases and for trailing closures.

Then there’s similarity with other languages, which is minor, but nice. I don’t know any language that uses a syntax like the current one of Swift.

Smalltalk and Ruby immediately come to mind and I'm sure there are others.

Scala has a trailing closure syntax which is similar to Swift's syntax as well.

-Thorsten
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Alexander Regueiro) #15

Sorry, but I don’t think you could be more wrong on every point. I’ve clearly detailed why my solution is superior (both factually and in my opinion), and I can only see subjective “dislike this”.

Using “func” or “lambda” outside is uglier than “in” inside the braes? Really? That just boggles my mind. Sure, maybe Ruby does, but the vast majority of languages shun this approach. C# for example has a lovely, crystal clear syntax for lambda expressions. So does Haskell, like I’ve mentioned.

I’ve also explained the big problem with trailing closures already. And closures are really *not* control flow statements, so treating like them is just a fallacy and source of confusion. There are other arguments against it too, like it doesn’t generalise well (at all) to multiple closure arguments.

Ultimately, the key points when judging how worthwhile a feature are 1) how big a feature is it? 2) how much does it add?. I’d say that for trailing closures, the answer to 1) is “moderate”, and 2) is “next to nothing”.

···

On 22 Dec 2015, at 06:57, Thorsten Seitz <tseitz42@icloud.com> wrote:

Well, I'm actually happy with the current closure syntax as it allows very succinct simple cases and trailing closures as Chris has already pointed out.

Am 21.12.2015 um 23:44 schrieb Alexander Regueiro via swift-evolution <swift-evolution@swift.org>:

Okay, I assume you are aware this essentially the same syntax as used in languages like C# and Python, yes? I’m not sure there are any problems in those languages with it.

If you dig through (very early) history you’ll see that we had this. There are a couple of problems with it:

1) It punishes simple cases like “X.sort { $1 < $0 }”, along with lots of simple map and filter closures.

Not really. The above example would just be `X.sort func { $1 < $0 }” or "X.sort \ { $1 < $0 }` in my proposed syntax. Also, it would be nice to have all operators implicitly

Having "func" or the backslash crammed in there is really ugly and unreadable IMHO.

And in Haskell you don't have braces for the body to begin with and you would have to enclose the closure in parenthesis if it is part of an expression like your examples so in effect it would look quite similar, i.e. having the parameters within the parenthesis (sure, the semantics are different, but I made argument just to demonstrate that what looks good in one syntactic environment might not look good in another).

2) It reads really weird in trailing closure cases.

Honestly, I strongly dislike trailing closures. I don’t think they add much, and moreover they use a confusing syntax that make the whole function call look superficially like a function declaration (or indeed the whole thing being a closure).

Trailing closures are a great feature IMHO because they make the code much more readable by allowing constructs to look similar to control flow statements.
This allows creating very readable DSLs.

Lets step back: What problems are you trying to solve with the current closure syntax?

Readability, mainly. I think this is a big improvement.

Well, I think it's the opposite for the simple cases and for trailing closures.

Then there’s similarity with other languages, which is minor, but nice. I don’t know any language that uses a syntax like the current one of Swift.

Smalltalk and Ruby immediately come to mind and I'm sure there are others.

Scala has a trailing closure syntax which is similar to Swift's syntax as well.

-Thorsten


(Charles Constant) #16

When I started using Swift, and wanted to learn the syntax for closures, I
found the "in" token very confusing. I probably would have figured it out
at least a half hour sooner, if it had been a different word, or an
operator. I kept thinking "that can't be right, I must be misinterpreting
the documentation"

Once you learn the syntax once, it's not a practical issue ever again.
Still, it's kinder to new learners, and reads better, if the syntax uses
something other than "in"

···

On Tue, Dec 22, 2015 at 1:54 AM, Daniel Valls Estella via swift-evolution < swift-evolution@swift.org> wrote:

Just to add my point of view as language user. I don’t know so much about
compilers and neither have many familiarity with language grammars. I like
to learn, and this list helps.

I think clousures are strangely written and break some coherence. I agree
with Alexander on that.
But I don’t like the proposed solution.

In the other side, I think trailing closures are a really a great feature,
I like a lot.
But I feel it’s a bit confusing in some way, as Alexander pointed. As if
it was the body definition of the called function.

To throw an idea, the *with* keyword:

with ( *parameters* ) -> *return_type* {
    *statements*
}

sorted = names.sort( *with*(s1: String, s2: String) -> Bool {
    return s1 > s2
})

sorted = names.sort( *with*(s1, s2){ return s1 > s2 } )

reversed = names.sort( *with*(s1, s2){ s1 > s2 } )

reversed = names.sort( { $0 > $1 } )
OR? reversed = names.sort( *with*{ $0 > $1 } )

reversed = names.sort(>)
OR? reversed = names.sort(*with* >)

reversed = names.sort() *with* { $0 > $1 } // I think clarifies it is
an input to exeute not a definition

reversed = names.sort *with* { $0 > $1 } // I think clarifies it is an
input to exeute not a definition

Thanks!

Daniel

Daniel Valls Estella · tel. 659.910.830 · daniel@upzzle.com

El 22 des 2015, a les 7:57, Thorsten Seitz via swift-evolution <
swift-evolution@swift.org> va escriure:

Well, I'm actually happy with the current closure syntax as it allows very
succinct simple cases and trailing closures as Chris has already pointed
out.

Am 21.12.2015 um 23:44 schrieb Alexander Regueiro via swift-evolution < > swift-evolution@swift.org>:

Okay, I assume you are aware this essentially the same syntax as used in
languages like C# and Python, yes? I’m not sure there are any problems in
those languages with it.

If you dig through (very early) history you’ll see that we had this.
There are a couple of problems with it:

1) It punishes simple cases like “X.sort { $1 < $0 }”, along with lots of
simple map and filter closures.

Not really. The above example would just be `X.sort func { $1 < $0 }” or
"X.sort \ { $1 < $0 }` in my proposed syntax. Also, it would be nice to
have all operators implicitly

Having "func" or the backslash crammed in there is really ugly and
unreadable IMHO.

And in Haskell you don't have braces for the body to begin with and you
would have to enclose the closure in parenthesis if it is part of an
expression like your examples so in effect it would look quite similar,
i.e. having the parameters within the parenthesis (sure, the semantics are
different, but I made argument just to demonstrate that what looks good in
one syntactic environment might not look good in another).

2) It reads really weird in trailing closure cases.

Honestly, I strongly dislike trailing closures. I don’t think they add
much, and moreover they use a confusing syntax that make the whole function
call look superficially like a function declaration (or indeed the whole
thing being a closure).

Trailing closures are a great feature IMHO because they make the code much
more readable by allowing constructs to look similar to control flow
statements.
This allows creating very readable DSLs.

Lets step back: What problems are you trying to solve with the current
closure syntax?

Readability, mainly. I think this is a big improvement.

Well, I think it's the opposite for the simple cases and for trailing
closures.

Then there’s similarity with other languages, which is minor, but nice. I
don’t know any language that uses a syntax like the current one of Swift.

Smalltalk and Ruby immediately come to mind and I'm sure there are others.

Scala has a trailing closure syntax which is similar to Swift's syntax as
well.

-Thorsten
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Greg Parker) #17

I’ve also explained the big problem with trailing closures already. And closures are really *not* control flow statements, so treating like them is just a fallacy and source of confusion.

Trailing closures allow you to write constructs that look and act as if they were control flow statements, which in practice is quite useful.

Closures do have control flow ramifications when reading code: the meaning of `return` inside a closure is different from its meaning in nearby code.

I personally favored `func` as the introducer for closures for precisely that reason. The presence of `func` would make it easier to recognize that there is something additional going on here, such as variable captures and `return` hijacking. Be warned that I lost that argument internally long ago.

There are other arguments against it too, like it doesn’t generalise well (at all) to multiple closure arguments.

The argument that a feature does not generalize becomes much weaker when the special case is important enough. Single-closure argument lists like map and dispatch… and with… are common enough that special treatment is warranted.

···

On Dec 22, 2015, at 3:45 PM, Alexander Regueiro via swift-evolution <swift-evolution@swift.org> wrote:

--
Greg Parker gparker@apple.com Runtime Wrangler


(Alexander Regueiro) #18

I’ve also explained the big problem with trailing closures already. And closures are really *not* control flow statements, so treating like them is just a fallacy and source of confusion.

Trailing closures allow you to write constructs that look and act as if they were control flow statements, which in practice is quite useful.

It really just means you put the close bracket for a function call (parameter list) before the actual parameters end. Which not only doesn’t save any real space (2 characters if you’re lucky, but quite often 0), but it belies the semantics of passing arguments to function, at such trifling benefit.

Closures do have control flow ramifications when reading code: the meaning of `return` inside a closure is different from its meaning in nearby code.

Sure, but that doesn’t mean closures are control-flow elements or statements. Also, I think my above point makes this rather irrelevant anyway.

I personally favored `func` as the introducer for closures for precisely that reason. The presence of `func` would make it easier to recognize that there is something additional going on here, such as variable captures and `return` hijacking. Be warned that I lost that argument internally long ago.

Did you have anyone else on that side? :slight_smile: I think if another public support can be drummed up, it should be on the cards again.

There are other arguments against it too, like it doesn’t generalise well (at all) to multiple closure arguments.

The argument that a feature does not generalize becomes much weaker when the special case is important enough. Single-closure argument lists like map and dispatch… and with… are common enough that special treatment is warranted.

Sure, but then what's the benefit for single-closure argument lists in the first place? I still don’t say any. Honestly, it just looks like a confusing way to put the brackets in another place, at the cost of confusing people and making your function call look like a function definition. (Great!)


(Andrey Tarantsov) #19

Can't help commenting...

I can only see subjective “dislike this”.

The feel of the language is very important. We're talking about improving the syntax to look better here, so of course the subjective look of it matters most.

Using “func” or “lambda” outside is uglier than “in” inside the braes? Really?

A thousand times yes. "in" is unfortunate, but adding a keyword would be... backwards doesn't quite capture it. It would destroy a big portion of the fun of the entire language.

And closures are really *not* control flow statements, so treating like them is just a fallacy and source of confusion.

...but it looks and reads very good. :wink:

The only thing that I find wrong is "in". It just doesn't look delimited enough. foo.map { bar in bar.boz} is heavy on the eyes, while foo.map { |bar| bar.boz } would be ideal.

A man can dream, right?

Honestly, I think I understand the tradeoffs involved, so I'm fine with letting that "in" be.

A.


(Alexander Regueiro) #20

Disagree, disagree, disagree. Don’t see any logic to that.

···

On 23 Dec 2015, at 02:10, Andrey Tarantsov <andrey@tarantsov.com> wrote:

Can't help commenting...

I can only see subjective “dislike this”.

The feel of the language is very important. We're talking about improving the syntax to look better here, so of course the subjective look of it matters most.

Using “func” or “lambda” outside is uglier than “in” inside the braes? Really?

A thousand times yes. "in" is unfortunate, but adding a keyword would be... backwards doesn't quite capture it. It would destroy a big portion of the fun of the entire language.

And closures are really *not* control flow statements, so treating like them is just a fallacy and source of confusion.

...but it looks and reads very good. :wink:

The only thing that I find wrong is "in". It just doesn't look delimited enough. foo.map { bar in bar.boz} is heavy on the eyes, while foo.map { |bar| bar.boz } would be ideal.

A man can dream, right?

Honestly, I think I understand the tradeoffs involved, so I'm fine with letting that "in" be.

A.