[RFC] Arrow functions / short closures

php.internals

Nikita Popov

7 years ago
Hi internals, Motivated by the recent list comprehensions RFC, I think it's time we took another look at short closures: https://wiki.php.net/rfc/arrow_functions_v2 This is based on a previous (withdrawn) proposal by Levi & Bob. It uses the syntax fn($x) => $x * $multiplier and implicit by-value variable binding. This example is roughly equivalent to: function($x) use($multiplier) { return $x * $multiplier; } The RFC contains a detailed discussion of syntax choices and binding modes. Regards, Nikita

Ben Ramsey

7 years ago
> On Mar 13, 2019, at 10:56, Nikita Popov <nikita.ppv@gmail.com> wrote: > > Hi internals, > > Motivated by the recent list comprehensions RFC, I think it's time we took > another look at short closures: > > https://wiki.php.net/rfc/arrow_functions_v2 > > This is based on a previous (withdrawn) proposal by Levi & Bob. It uses the > syntax > > fn($x) => $x * $multiplier > > and implicit by-value variable binding. This example is roughly equivalent > to: > > function($x) use($multiplier) { return $x * $multiplier; } > > The RFC contains a detailed discussion of syntax choices and binding modes.
Has the use of `f` as a leading symbol been considered and discussed? For example: f($x) => $x * $multiplier Cheers, Ben

Travis van der Font

7 years ago
Arrow functions are ternary operators to functions. While they are nice and shorten, they can be hard to read at times; considerably to people who aren't used to them which is surprisedly a majority of PHP programmers. Having them optional sure, but not necessary. Feel free to decide between fn() or f() as both are equivalently comprehensible to the same level of minimalism. Anyone considered? ($x) => $x * $multiplier #mytwocents Kind regards / Léif Gréiss, Travis van Font Le mer. 13 mars 2019 à 16:57, Nikita Popov <nikita.ppv@gmail.com> a écrit :

Chase Peeler

7 years ago
On Wed, Mar 13, 2019 at 4:26 PM Travis van der Font <travis.font@gmail.com> wrote:
> Arrow functions are ternary operators to functions. > While they are nice and shorten, they can be hard to read at times; > considerably to people who aren't used to them which is surprisedly a > majority of PHP programmers. > > Having them optional sure, but not necessary. > > Feel free to decide between fn() or f() as both are equivalently > comprehensible to the same level of minimalism. > Anyone considered? ($x) => $x * $multiplier > > I use this format a lot in javascript, so I like not having any indicator.
I can't remember which language it was, but they didn't even require the parentheses if there was only a single input: $x => $x * $multiplier;
> #mytwocents > > Kind regards / Léif Gréiss, > Travis van Font > > > Le mer. 13 mars 2019 à 16:57, Nikita Popov <nikita.ppv@gmail.com> a écrit > : > > > Hi internals, > > > > Motivated by the recent list comprehensions RFC, I think it's time we > took > > another look at short closures: > > > > https://wiki.php.net/rfc/arrow_functions_v2 > > > > This is based on a previous (withdrawn) proposal by Levi & Bob. It uses > the > > syntax > > > > fn($x) => $x * $multiplier > > > > and implicit by-value variable binding. This example is roughly > equivalent > > to: > > > > function($x) use($multiplier) { return $x * $multiplier; } > > > > The RFC contains a detailed discussion of syntax choices and binding > modes. > > > > Regards, > > Nikita > > >
-- -- Chase chasepeeler@gmail.com

Rowan Collins

7 years ago
On 13/03/2019 20:37, Chase Peeler wrote:
>> Anyone considered? ($x) => $x * $multiplier >> >> I use this format a lot in javascript, so I like not having any indicator. > I can't remember which language it was, but they didn't even require the > parentheses if there was only a single input: > $x => $x * $multiplier;
I suggest you both read the RFC; about half the page is dedicated to summarising the syntaxes which have been considered, and the pros and cons of each. The summary of that syntax begins:
> This is both the most popular and the most technically infeasible syntax.
Regards,
-- Rowan Collins [IMSoP]

Ben Ramsey

7 years ago
> On Mar 13, 2019, at 15:56, Rowan Collins <rowan.collins@gmail.com> wrote: > > I suggest you both read the RFC; about half the page is dedicated to summarising the syntaxes which have been considered, and the pros and cons of each. > > The summary of that syntax begins: > > > This is both the most popular and the most technically infeasible syntax.
I did read the RFC, and I could find no mention of f(), so I’ll rephrase my question. :-) I would like to consider `f` as a potential leading symbol instead of `fn`. Cheers, Ben

Björn Larsson

7 years ago
Den 2019-03-13 kl. 16:56, skrev Nikita Popov:
> Hi internals, > > Motivated by the recent list comprehensions RFC, I think it's time we took > another look at short closures: > > https://wiki.php.net/rfc/arrow_functions_v2 > > This is based on a previous (withdrawn) proposal by Levi & Bob. It uses the > syntax > > fn($x) => $x * $multiplier > > and implicit by-value variable binding. This example is roughly equivalent > to: > > function($x) use($multiplier) { return $x * $multiplier; } > > The RFC contains a detailed discussion of syntax choices and binding modes. > > Regards, > Nikita
Thanks for bringing this forward Nikita! I recall from the earlier discussions 2017 that also the lambda as a keyword was considered. I would like to bring that forward as one option, maybe less impact on existing code as a reserved keyword. An advantage of not having a keyword /prefix could be that for simple arrow functions no parenthesis is needed and readability is improved: $someDict->map(fn($v) => $v * 2)->filter(fn($v) => $v % 3); $someDict->map(\($v) => $v * 2)->filter(\($v) => $v % 3); $someDict->map(^($v) => $v * 2)->filter(^($v) => $v % 3); vs $someDict->map($v ==> $v * 2)->filter($v ==> $v % 3); $someDict->map($v ~> $v * 2)->filter($v ~> $v % 3); r//Björn L

Larry Garfield

7 years ago
On Wed, Mar 13, 2019, at 11:57 AM, Nikita Popov wrote:
> Hi internals, > > Motivated by the recent list comprehensions RFC, I think it's time we took > another look at short closures: > > https://wiki.php.net/rfc/arrow_functions_v2 > > This is based on a previous (withdrawn) proposal by Levi & Bob. It uses the > syntax > > fn($x) => $x * $multiplier > > and implicit by-value variable binding. This example is roughly equivalent > to: > > function($x) use($multiplier) { return $x * $multiplier; } > > The RFC contains a detailed discussion of syntax choices and binding modes. > > Regards, > Nikita
A very thorough writeup, thanks, Nikita! +1 from me. Two questions: The section on static arrow functions implies, but doesn't say outright, that $this will auto-bind just like any other variable if used inside an arrow function. Is that the case? If so, that should be made explicit for clarity. With regards to comprehensions, this RFC says that arrow functions have a single, implicitly returned statement. How would that play with a function body that includes a yield? Would that work "as expected" (the arrow function becomes a generator function that can be iterated, making it functionally a comprehension) or would it fail in some mysterious way? --Larry Garfield

David Rodrigues

7 years ago
I have two doubts about the RFC: 1. Your example with "($x) => $x" consider the use of "$x => $x", but not specifically "($x) => $x". I mean: maybe it can accept "($x) => $x" but not "$x => $x" because of the array conflict (as mentioned), and with that we avoid to create a new keyword "fn". So parentheses is required. 2. I don't remember. haha Em qua, 13 de mar de 2019 às 12:57, Nikita Popov <nikita.ppv@gmail.com> escreveu:
> Hi internals, > > Motivated by the recent list comprehensions RFC, I think it's time we took > another look at short closures: > > https://wiki.php.net/rfc/arrow_functions_v2 > > This is based on a previous (withdrawn) proposal by Levi & Bob. It uses the > syntax > > fn($x) => $x * $multiplier > > and implicit by-value variable binding. This example is roughly equivalent > to: > > function($x) use($multiplier) { return $x * $multiplier; } > > The RFC contains a detailed discussion of syntax choices and binding modes. > > Regards, > Nikita >
-- David Rodrigues

Rowan Collins

7 years ago
On 14 March 2019 04:01:54 GMT+00:00, David Rodrigues <david.proweb@gmail.com> wrote:
>1. Your example with "($x) => $x" consider the use of "$x => $x", but >not >specifically "($x) => $x". I mean: maybe it can accept "($x) => $x" but >not >"$x => $x" because of the array conflict (as mentioned), and with that >we >avoid to create a new keyword "fn". So parentheses is required.
I don't think this helps, because you can put brackets around any expression, for precedence, and any expression can appear on the left of an array literal: $foo = [ ($bar + 1) * 2 => $baz ]; So the following, while redundant, is currently valid: $foo = [ ($bar) => $baz ]; Regards,
-- Rowan Collins [IMSoP]

David Rodrigues

7 years ago
Em qui, 14 de mar de 2019 às 03:17, Rowan Collins <rowan.collins@gmail.com> escreveu:
> I don't think this helps, because you can put brackets around any > expression, for precedence, and any expression can appear on the left of an > array literal: > > $foo = [ ($bar + 1) * 2 => $baz ]; > > So the following, while redundant, is currently valid: > > $foo = [ ($bar) => $baz ]; >
Yeah, I don't think in that case. And maybe using [] instead of ()? For instance: "[$x] => $x + 1". PHP don't supports and array as key, so maybe it will not causes any conflict.
-- David Rodrigues

Nikita Popov

7 years ago
On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> wrote:
> Hi internals, > > Motivated by the recent list comprehensions RFC, I think it's time we took > another look at short closures: > > https://wiki.php.net/rfc/arrow_functions_v2 > > This is based on a previous (withdrawn) proposal by Levi & Bob. It uses > the syntax > > fn($x) => $x * $multiplier > > and implicit by-value variable binding. This example is roughly equivalent > to: > > function($x) use($multiplier) { return $x * $multiplier; } > > The RFC contains a detailed discussion of syntax choices and binding modes. >
Trying to reply to everyone in one mail... 1. Using f() =>. This is possible. However, f would become a reserved keyword, and I'm very leery of making a single-character reserved keyword. Additionally I think that the fn() => syntax is more intuitive, but maybe that's my Rust influences speaking ;) 2. $this binding. Yes, $this is indeed bound exactly as with normal closures. I've explicitly mentioned this in the RFC now. 3. yield. Using yield is per-se not a problem. You can write `() => yield 42`, which is basically `function() { return yield 42; }`, which is okay, because yield is an expression and generators can return values since PHP 7. It also doesn't seem particularly useful though, as you're limited to yielding a single value. However, in the current form short closures are a replacement for list comprehensions only insofar they make the use of map() and filter() non-torturous. You couldn't actually use them to get a comprehension-like syntax as suggested in the other thread: $gen = (fn() => foreach ($list as $elem) yield $elem * 2))(); // would be, hypothetically: $gen = (function() use($list) { return foreach ($list as $elem) yield $elem * 2; }))(); The yield part here isn't the problem, "return foreach" is. Unlike yield, foreach is a statement, not an expression. To make this work we'd need a block form of short closures: $gen = (fn() { foreach ($list as $elem) yield $elem * 2; })(); // or maybe $gen = (fn() => { foreach ($list as $elem) yield $elem * 2; })(); Either way, I wouldn't want to read that code ;) The right way to write this is $list->map(fn($elem) => $elem * 2). 4. ($x) => $x instead of $x => $x. As Rowan mentioned, this doesn't really change things. Where $x is valid, ($x) is in most cases also valid. Regards, Nikita

Rowan Collins

7 years ago
On 13 March 2019 15:56:40 GMT+00:00, Nikita Popov <nikita.ppv@gmail.com> wrote:
>Motivated by the recent list comprehensions RFC, I think it's time we >took >another look at short closures: > >https://wiki.php.net/rfc/arrow_functions_v2
Hi Nikita, Thanks for reviving this. I think the RFC does a great job of justifying both the syntax and the behaviour, and focusing on the most used features without ruling out further additions in future. In particular, I think whether and how we support auto-capture in full function bodies has its own pros and cons to debate, separate from auto-capture as a convenience in short "lambda" expressions. I was initially quite drawn to a block-style syntax. As someone not particularly familiar with functional programming (which I suspect puts me in the majority of PHP users), I actually find it easier to spot this as "a closure returning a closure": { ($x) => { ($y) => $x * $y } } rather than having to work out the associativity of chained operators: fn($x) => fn($y) => $x * $y However, I imagine the only people who will heavily use such a construct will be those who *are* familiar with functional programming in other languages, and will find the simpler syntax more familiar and convenient. It would also be ugly to add full block bodies in a similar style like { ($x) => { ... } }, and while I'm not convinced we need that, we probably don't want to rule it out completely. As such, I support the RFC in its current form. Regards,
-- Rowan Collins [IMSoP]

Benjamin Morel

7 years ago
This makes me thinking, has this syntax been considered? ($x) => { $x * $y } Nested: ($x) => { ($y) => { $x * $y } } AFAICS, we don't need the brackets around the whole expression, as this should be parsable without any ambiguity; and the syntax would be closer to that of JavaScript. On Thu, 14 Mar 2019 at 14:44, Rowan Collins <rowan.collins@gmail.com> wrote:

Rowan Collins

7 years ago
On Thu, 14 Mar 2019 at 14:12, Benjamin Morel <benjamin.morel@gmail.com> wrote:
> This makes me thinking, has this syntax been considered? > > ($x) => { $x * $y } > > Nested: > > ($x) => { ($y) => { $x * $y } } >
Wouldn't this have all the same parser problems as the RFC discusses? The problem, as I understand it, is not avoiding ambiguity, it's avoiding lookahead. If you write: $foo = [ ($x) => { $x } ]; $bar = [ ($x) => $x ]; The parser has already consumed " [ ($x) =>" before it can decide if each ($x) is an array key or a closure signature. It's parseable, but only using one of the workarounds described in the RFC. If I'm understanding the RFC correctly, the only way to avoid that is to have closures *start* differently from other valid constructs, because then the parser doesn't need to recurse / backtrack / etc. Regards,
-- Rowan Collins [IMSoP]

Benjamin Morel

7 years ago
> > The problem, as I understand it, is not avoiding ambiguity, it's avoiding > lookahead.
You're right, I was only thinking about resolving the ambiguity with array keys. It's too bad if the parser implementation considerations take precedence over the purity of the language, but I can understand the maintenance nightmare that people are trying to avoid here. Something else that crosses my mind, is: what prevents us from using the same syntax as ES6: ($x) => $x * $y But to prevent any ambiguity, forbid array keys from being enclosed with parenthese? For example, the following would be considered an array containing a closure: [ ($foo) => "bar" ] And the following would just become a syntax error: [ ("foo") => "bar" ] Would that solve the parser problem? BC-wise, I don't think this would be much of a problem: I have yet to see array keys enclosed with parentheses in PHP codebases. On Thu, 14 Mar 2019 at 15:54, Rowan Collins <rowan.collins@gmail.com> wrote:

Rowan Collins

7 years ago
On Thu, 14 Mar 2019 at 15:10, Benjamin Morel <benjamin.morel@gmail.com> wrote:
> The problem, as I understand it, is not avoiding ambiguity, it's avoiding >> lookahead. > > > You're right, I was only thinking about resolving the ambiguity with array > keys. It's too bad if the parser implementation considerations take > precedence over the purity of the language >
I don't agree that this has anything to do with "purity". If JS didn't have => syntax, why would "fn is a shorter keyword than function" not be a good enough reason to go with this syntax? I think it's equally valid to say that it would be a shame for one syntax shortcut to take precedence over the consistency and maintainability of everything else in the language. Is it really that important to save two key strokes per closure?
> Would that solve the parser problem? BC-wise, I don't think this would be > much of a problem: I have yet to see array keys enclosed with parentheses > in PHP codebases. >
A quick regex search in a code base I had to hand found a few instances of casts, like [(string)$foo => $bar], but indeed no instances of bracketed variables. However, it would feel rather bizarre to be able to write this: [ $x+1 => $foo ] But not this: [ ($x+1) => $foo ] Which I think would have to be the implication for this to make the parsing any easier. On Thu, 14 Mar 2019 at 15:38, David Rodrigues <david.proweb@gmail.com> wrote:
> maybe using [] instead of ()? For instance: "[$x] => $x + 1". PHP don't
supports and array as key, so maybe it will not causes any conflict. Again, I think this solves the ambiguity but not the parsing, although I could be wrong. Consider parsing these three expressions: [ [ $foo ] ] # Nested arrays [ [ $foo => $bar ] ] # Nested arrays with an explicit key [ [ $foo ] => $bar ] # An array containing a closure Regards,
-- Rowan Collins [IMSoP]

Josh Di Fabio

7 years ago
On Thu, Mar 14, 2019 at 3:49 PM Rowan Collins <rowan.collins@gmail.com> wrote:
> > Is it really that important to save two key strokes per closure? >
I'd say that the (probably overwhelming) majority of arrow functions have a single parameter and, in those cases, the JS syntax saves four characters, ignoring whitespace. Another way of looking at it is that you have six characters of boilerplate with the fn() syntax versus two in JS (ignoring whitespace) for single param arrow functions.

Girgias

7 years ago
On Thu, 14 Mar 2019 at 18:20, Josh Di Fabio <joshdifabio@gmail.com> wrote:
> On Thu, Mar 14, 2019 at 3:49 PM Rowan Collins <rowan.collins@gmail.com> > wrote: > > > > Is it really that important to save two key strokes per closure? > > > > I'd say that the (probably overwhelming) majority of arrow functions > have a single parameter and, in those cases, the JS syntax saves four > characters, ignoring whitespace. Another way of looking at it is that > you have six characters of boilerplate with the fn() syntax versus two > in JS (ignoring whitespace) for single param arrow functions. >
No offense but at the end of the day having readable code is better than shorter code IMHO, so I don't really see the problem with having a couple of extra character/keystrokes as this is more readable then the massive boilerplate we currently have. However, I can see people beeing fond of the concise syntax of JS Best regards George P. Banyard

Mathieu Rochette

7 years ago
Hi, it's nice to see this going on again :) while reading the rfc I was wondering, why do we need the "static" keyword, couldn't static function be detected automatically ? I guess this apply to the existing closure syntax as well so to get more on this topic I'll share my preferences on the syntax: I like the ==> or ~> version because it also allow to drop the parenthesis when there is only one argument and it's closer to what I'm used to in javascript I wouldn't mind having the rust syntax too but yeah, it would feel a bit odd in PHP thank you for your work on this ! Nikita Popov – Wed, 13. March 2019 16:57

Nikita Popov

7 years ago
On Thu, Mar 14, 2019 at 3:04 PM Mathieu Rochette <mathieu@rochette.cc> wrote:
> > Hi, > > it's nice to see this going on again :) > > while reading the rfc I was wondering, why do we need the "static" > keyword, couldn't static function be detected automatically ? >
I've added a note regarding this in https://wiki.php.net/rfc/arrow_functions_v2#this_binding_and_static_arrow_functions. The problem is that in PHP we cannot actually reliably detect whether or not a closure uses $this. Sure -- we can see literal $this uses, but some of them are implicit: fn() => Foo::bar() can make use of $this if $this is scope-compatible with Foo. fn() => call_user_func('Foo::bar') can as well. fn() => $a($b) can as well, if it so happens that $a = 'call_user_func' and $b = 'Foo::bar'. The result is that we cannot reliably detect whether $this is used or not -- we can only make a conservative analysis that may sometimes bind $this even though it's not needed. In which case I would prefer going with the more predictable behavior of always binding $this, and using "static" in the rare cases where someone really cares about this.

Nikita Popov

7 years ago
On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> wrote:
> Hi internals, > > Motivated by the recent list comprehensions RFC, I think it's time we took > another look at short closures: > > https://wiki.php.net/rfc/arrow_functions_v2 > > This is based on a previous (withdrawn) proposal by Levi & Bob. It uses > the syntax > > fn($x) => $x * $multiplier > > and implicit by-value variable binding. This example is roughly equivalent > to: > > function($x) use($multiplier) { return $x * $multiplier; } > > The RFC contains a detailed discussion of syntax choices and binding modes. > > Regards, > Nikita >
As a small update, I've implemented a proof of concept that uses the ($x) ==> $x * $multiplier syntax (or $x ==> $x * $multiplier for short) in https://github.com/php/php-src/pull/3945. As mentioned in the RFC, this requires scanahead in the lexer. This syntax is in principle still on the table, though personally I prefer fn($x, $y) => $x * $y over ($x, $y) ==> $x * $y. The main redeeming quality of ==> is that it supports the paren-less variant $x ==> $x. Taking into account the lexer hackery it requires (and which will also be required in any 3rd party tooling), this would not be my preferred choice. Regards, Nikita

Theodore Brown

7 years ago
On Thu, March 14, 2019 10:41 AM Nikita Popov <nikita.ppv@gmail.com> wrote: > On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> wrote: > > > Hi internals, > > > > Motivated by the recent list comprehensions RFC, I think it's time we took > > another look at short closures: > > > > https://wiki.php.net/rfc/arrow_functions_v2 > > As a small update, I've implemented a proof of concept that uses the ($x) > ==> $x * $multiplier syntax (or $x ==> $x * $multiplier for short) in > https://github.com/php/php-src/pull/3945. As mentioned in the RFC, this > requires scanahead in the lexer. > > This syntax is in principle still on the table, though personally I prefer > fn($x, $y) => $x * $y over ($x, $y) ==> $x * $y. The main redeeming quality > of ==> is that it supports the paren-less variant $x ==> $x. Taking into > account the lexer hackery it requires (and which will also be required in > any 3rd party tooling), this would not be my preferred choice. > I agree that the nicest thing about this syntax is the ability to save an additional 3 characters of boilerplate for the common use case of single-parameter arrow functions. However, I'm also not a fan of adding complex code hacks to make the syntax work. One alternative that doesn't seem to have had much discussion on list is the `\($x) => $x * $y` lambda syntax. This would also allow parentheses to be omitted for single parameters, making it just as terse as the ==> syntax without the need for any lexer hackery. Here's how the examples from the RFC would look: ```php function array_values_from_keys($arr, $keys) { return array_map(\$x => $arr[$x], $keys); } $extended = \$c => $callable($factory($c), $c); $this->existingSchemaPaths = array_filter($paths, \$v => in_array($v, $names)); function complement(callable $f) { return \(...$args) => !$f(...$args); } $result = Collection::from([1, 2]) ->map(\$v => $v * 2) ->reduce(\($tmp, $v) => $tmp + $v, 0); ``` One argument against this shorter syntax is that it wouldn't be as easy to google as `fn`. However, long term I think everyone would still get used to it, and I'm personally willing to add an answer to the top Stack Overflow search result for "php backslash keyword". The backslash syntax has precedent from Haskell, and also wouldn't introduce any BC break (who knows how many private codebases might already have functions named `fn`).

Larry Garfield

7 years ago
On Thu, Mar 14, 2019, at 3:41 PM, Theodore Brown wrote:
> > As a small update, I've implemented a proof of concept that uses the ($x) > > ==> $x * $multiplier syntax (or $x ==> $x * $multiplier for short) in > > https://github.com/php/php-src/pull/3945. As mentioned in the RFC, this > > requires scanahead in the lexer. > > > > This syntax is in principle still on the table, though personally I prefer > > fn($x, $y) => $x * $y over ($x, $y) ==> $x * $y. The main redeeming quality > > of ==> is that it supports the paren-less variant $x ==> $x. Taking into > > account the lexer hackery it requires (and which will also be required in > > any 3rd party tooling), this would not be my preferred choice. > > > > I agree that the nicest thing about this syntax is the ability to save > an additional 3 characters of boilerplate for the common use case of > single-parameter arrow functions. However, I'm also not a fan of adding > complex code hacks to make the syntax work. > > One alternative that doesn't seem to have had much discussion on list > is the `\($x) => $x * $y` lambda syntax. This would also allow parentheses > to be omitted for single parameters, making it just as terse as the ==> > syntax without the need for any lexer hackery. > > Here's how the examples from the RFC would look: > > ```php > function array_values_from_keys($arr, $keys) { > return array_map(\$x => $arr[$x], $keys); > } > > > $extended = \$c => $callable($factory($c), $c); > > > $this->existingSchemaPaths = array_filter($paths, \$v => in_array($v, $names)); > > > function complement(callable $f) { > return \(...$args) => !$f(...$args); > } > > > $result = Collection::from([1, 2]) > ->map(\$v => $v * 2) > ->reduce(\($tmp, $v) => $tmp + $v, 0); > ``` > > One argument against this shorter syntax is that it wouldn't be as > easy to google as `fn`. However, long term I think everyone would > still get used to it, and I'm personally willing to add an answer > to the top Stack Overflow search result for "php backslash keyword". > > The backslash syntax has precedent from Haskell, and also wouldn't > introduce any BC break (who knows how many private codebases might > already have functions named `fn`).
To clarify a point (not aimed at Theodore in particular, just a general statement), I don't think "saving keystrokes" is really a relevant or compelling argument here for fn() vs. other options. Rather, the intent of making a short-lambda as terse as possible is that it ceases to feel like a function. It's just a logical operation definition that you work into whatever code you're writing. That it is nominally a function ceases to be something you really think about. That's a worthwhile goal that I support. That said, Nikita has laid out a detailed analysis of why various options are or are not feasible in the RFC. I would encourage anyone tempted to bikeshed or suggest alternate syntaxes read that entire section twice before doing so. fn() isn't my preferred choice either, but it keeps the lexer happy, and we really want to keep the lexer happy. So any alternatives need to consider "keep the lexer happy" as a primary design goal. --Larry Garfield

Josh Di Fabio

7 years ago
On Thu, Mar 14, 2019 at 7:42 PM Theodore Brown <theodorejb@outlook.com> wrote:
> > On Thu, March 14, 2019 10:41 AM Nikita Popov <nikita.ppv@gmail.com> wrote: > > > On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> wrote: > > > > > Hi internals, > > > > > > Motivated by the recent list comprehensions RFC, I think it's time we took > > > another look at short closures: > > > > > > https://wiki.php.net/rfc/arrow_functions_v2 > > > > As a small update, I've implemented a proof of concept that uses the ($x) > > ==> $x * $multiplier syntax (or $x ==> $x * $multiplier for short) in > > https://github.com/php/php-src/pull/3945. As mentioned in the RFC, this > > requires scanahead in the lexer. > > > > This syntax is in principle still on the table, though personally I prefer > > fn($x, $y) => $x * $y over ($x, $y) ==> $x * $y. The main redeeming quality > > of ==> is that it supports the paren-less variant $x ==> $x. Taking into > > account the lexer hackery it requires (and which will also be required in > > any 3rd party tooling), this would not be my preferred choice. > > > > I agree that the nicest thing about this syntax is the ability to save > an additional 3 characters of boilerplate for the common use case of > single-parameter arrow functions. However, I'm also not a fan of adding > complex code hacks to make the syntax work. > > One alternative that doesn't seem to have had much discussion on list > is the `\($x) => $x * $y` lambda syntax. This would also allow parentheses > to be omitted for single parameters, making it just as terse as the ==> > syntax without the need for any lexer hackery. > > Here's how the examples from the RFC would look: > > ```php > function array_values_from_keys($arr, $keys) { > return array_map(\$x => $arr[$x], $keys); > } > > > $extended = \$c => $callable($factory($c), $c); > > > $this->existingSchemaPaths = array_filter($paths, \$v => in_array($v, $names)); > > > function complement(callable $f) { > return \(...$args) => !$f(...$args); > } > > > $result = Collection::from([1, 2]) > ->map(\$v => $v * 2) > ->reduce(\($tmp, $v) => $tmp + $v, 0); > ``` > > One argument against this shorter syntax is that it wouldn't be as > easy to google as `fn`. However, long term I think everyone would > still get used to it, and I'm personally willing to add an answer > to the top Stack Overflow search result for "php backslash keyword". > > The backslash syntax has precedent from Haskell, and also wouldn't > introduce any BC break (who knows how many private codebases might > already have functions named `fn`). > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >
I'd certainly be on board with the fn() syntax, but the backslash syntax has definitely grown on me. To me, all of the examples in Theodore's email are very readable and I find that the backslash makes it very easy to identify arrow functions when grokking. array_filter($numbers, \$n => $n % 2); vs. array_filter($numbers, fn($n) => $n % 2); When grokking these two pieces of code, I immediately see "\$n => $n % 2" as a single unit, whereas in the latter example I instinctively (and incorrectly) interpret "fn($n)" as an expression. When parens are required, the difference is obviously reduced, but I think I still prefer the backslash syntax since the LHS doesn't grok as a function call. reduce($numbers, \($x, $y) => $x + $y); vs. reduce($numbers, fn($x, $y) => $x + $y); That said, I'd personally take either syntax gladly.

Theodore Brown

7 years ago
On Fri, March 15, 2019 at 4:45 AM Josh Di Fabio <joshdifabio@gmail.com> wrote: > I'd certainly be on board with the fn() syntax, but the backslash > syntax has definitely grown on me. To me, all of the examples in > Theodore's email are very readable and I find that the backslash makes > it very easy to identify arrow functions when grokking. > > `array_filter($numbers, \$n => $n % 2);` > vs. > `array_filter($numbers, fn($n) => $n % 2);` > > When grokking these two pieces of code, I immediately see `\$n => $n % > 2` > as a single unit, whereas in the latter example I instinctively > (and incorrectly) interpret "fn($n)" as an expression. > > When parens are required, the difference is obviously reduced, but I > think I still prefer the backslash syntax since the LHS doesn't grok > as a function call. > > `reduce($numbers, \($x, $y) => $x + $y);` > vs. > `reduce($numbers, fn($x, $y) => $x + $y);` > > That said, I'd personally take either syntax gladly. You have a good point about `fn()` looking like an expression. That said, since it would be a keyword IDEs will highlight it differently which should help avoid confusion. Regarding the backslash syntax, I forgot to check how it looks with by-reference passing and returning before I sent my email. Here are those examples: ```php fn(&$x) => $x; fn&($x) => $x; // vs. \(&$x) => $x; \&($x) => $x; // unclear if passing or returning by reference \&$x => $x; // and worst of all... fn&(&$x) => $x; // vs. \&(&$x) => $x; ``` I have to admit that the `fn` prefix is a little more readable for these use cases (though I've never actually seen a real function using by-reference passing and returning at the same time). -Theodore Brown

Alexandru Pătrănescu

7 years ago
Hi, To start with, I personally understand why a prefix character is needed before parenthesis to make the parser simpler. I would like another simpler option but will have to investigate more on this. My question would be: whatever syntax we are going to use that has arrow syntax, let's say *$f = \($x) => $x * 2;* are we going to also support the arrow block version?: *$f = \($x) => {* * // more operations that will have better visible on multi-line* * return $x * 2;* *}* This is present in other languages and was thinking that we could have it in PHP also. Regards, Alex On Wed, Mar 13, 2019 at 5:57 PM Nikita Popov <nikita.ppv@gmail.com> wrote:

Rowan Collins

7 years ago
On Fri, 15 Mar 2019 at 09:01, Alexandru Pătrănescu <drealecs@gmail.com> wrote:
> My question would be: whatever syntax we are going to use that has arrow > syntax, let's say *$f = \($x) => $x * 2;* are we going to also support the > arrow block version?: > *$f = \($x) => {* > * // more operations that will have better visible on multi-line* > > * return $x * 2;* > *}* >
See "Future Scope" in the RFC:
> This feature is omitted in this RFC, because the value-proposition of
this syntax is much smaller: Once you have multiple statements, the relative overhead of the conventional closure syntax becomes small. We shouldn't pick a syntax that rules it out, but it can be added later, with a separate RFC to discuss the benefits and details. Regards,
-- Rowan Collins [IMSoP]

Nikita Popov

7 years ago
On Fri, Mar 15, 2019 at 10:31 AM Rowan Collins <rowan.collins@gmail.com> wrote:
> On Fri, 15 Mar 2019 at 09:01, Alexandru Pătrănescu <drealecs@gmail.com> > wrote: > > > My question would be: whatever syntax we are going to use that has arrow > > syntax, let's say *$f = \($x) => $x * 2;* are we going to also support > the > > arrow block version?: > > *$f = \($x) => {* > > * // more operations that will have better visible on multi-line* > > > > * return $x * 2;* > > *}* > > > > > See "Future Scope" in the RFC: > > > This feature is omitted in this RFC, because the value-proposition of > this syntax is much smaller: Once you have multiple statements, the > relative overhead of the conventional closure syntax becomes small. > > We shouldn't pick a syntax that rules it out, but it can be added later, > with a separate RFC to discuss the benefits and details. >
It might be worth giving some consideration to the possibility of introducing this syntax already in this RFC. The main problem with punting this off for later is that it may be necessary to refactor closures between the short and the long form regularly: You need an extra statement in the closure? You have to switch closure types, and also not forget to write our the use() list this time. On the other hand, allowing a block body for the closure does add a number of complications to this proposal: 1. Syntax choice. Given the fn() syntax, we could go for either fn() {} or fn() => {}. 2. By-ref binding: While by-reference binding is not useful for single-expression closures, there will be cases where it's needed for block closures. We will also need to choose a syntax to opt-in to by-reference binding. The RFC suggests use(&), which is somewhat non-great. 3. Determining bound variables. For single-expression closures we can get away with binding all variables that are used inside the closure. Writing something like fn() $a = $b might cause an unnecessary binding of $a, but it's also a very contrived situation. For block closures performing assignments inside the closure will be much more common and will need some more consideration to avoid unnecessary bindings. Regards, Nikita

Rowan Collins

7 years ago
On Fri, 15 Mar 2019 at 10:10, Nikita Popov <nikita.ppv@gmail.com> wrote:
> It might be worth giving some consideration to the possibility of > introducing this syntax already in this RFC. The main problem with punting > this off for later is that it may be necessary to refactor closures between > the short and the long form regularly: You need an extra statement in the > closure? You have to switch closure types, and also not forget to write our > the use() list this time. >
I know I'm not necessarily in the majority, here, but to me, that's a feature not a bug: short closures should not be a replacement for every anonymous function, they should be for those cases where you have a really simple expression. At some point, you should be saying "this is now too long for a short closure, it needs a clearer definition", and "more than one expression or statement" is as good a heuristic for that as you're likely to get. I also have strong reservations about generalising automatic binding to full function bodies, because it fundamentally changes the way variable scope works in the language: right now, $foo is always local to a function, unless *explicitly* listed as a parameter, imported with "global", or captured with "use". That's a lot simpler than the scoping rules of a lot of other languages, and it's a guarantee we shouldn't break lightly. I'm willing to be convinced - or simply "out-voted" - on these points, but I think they deserve their own discussion. I was shot down on chat the other day for a naive remark that capturing a large number of variables in a closure would be "doing it wrong"; I'd love to see examples of where this is useful / necessary, and a new RFC would be the perfect place for someone to put those. That could mean another RFC proposed immediately after this one passes, and the feature arriving in the same PHP version, but I don't think we need to merge the two discussions - as long as we keep the possibility in mind when choosing a base syntax. Regards,
-- Rowan Collins [IMSoP]

Nikita Popov

7 years ago
On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> wrote:
> Hi internals, > > Motivated by the recent list comprehensions RFC, I think it's time we took > another look at short closures: > > https://wiki.php.net/rfc/arrow_functions_v2 > > This is based on a previous (withdrawn) proposal by Levi & Bob. It uses > the syntax > > fn($x) => $x * $multiplier > > and implicit by-value variable binding. This example is roughly equivalent > to: > > function($x) use($multiplier) { return $x * $multiplier; } > > The RFC contains a detailed discussion of syntax choices and binding modes. > > Regards, > Nikita >
Heads up: I plan to start voting on this RFC tomorrow if nothing new comes up. Most of the discussion was (as expected) about the choice of syntax. Ultimately I think there are many reasonable choices we can make here, but we should stick to a specific proposal for the purposes of the RFC vote. None of the given arguments convinced me that some other syntax is *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a matter of some choices being slightly better in one case and slightly worse in another. My personal runner-up would be \($x, $y) => $x*$y, but I suspect that there are some people who are more strongly biased against "sigil salad" than I am... Nikita

Björn Larsson

7 years ago
Den 2019-04-08 kl. 16:06, skrev Nikita Popov:
> On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> wrote: > >> Hi internals, >> >> Motivated by the recent list comprehensions RFC, I think it's time we took >> another look at short closures: >> >> https://wiki.php.net/rfc/arrow_functions_v2 >> >> This is based on a previous (withdrawn) proposal by Levi & Bob. It uses >> the syntax >> >> fn($x) => $x * $multiplier >> >> and implicit by-value variable binding. This example is roughly equivalent >> to: >> >> function($x) use($multiplier) { return $x * $multiplier; } >> >> The RFC contains a detailed discussion of syntax choices and binding modes. >> >> Regards, >> Nikita >> > Heads up: I plan to start voting on this RFC tomorrow if nothing new comes > up. > > Most of the discussion was (as expected) about the choice of syntax. > Ultimately I think there are many reasonable choices we can make here, but > we should stick to a specific proposal for the purposes of the RFC vote. > None of the given arguments convinced me that some other syntax is > *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a > matter of some choices being slightly better in one case and slightly worse > in another. My personal runner-up would be \($x, $y) => $x*$y, but I > suspect that there are some people who are more strongly biased against > "sigil salad" than I am... > > Nikita
Hi, I recall that the perception of the ==> syntax in the Hacklang user community was quite positive. Of course it was implementation difficulties. Are they still to cumbersome in PHP? Personally I prefer that one being more readable or the \ one. Anyway, glad to see that short closures finally is on the road again! r//Björn L

Nikita Popov

7 years ago
On Tue, Apr 9, 2019 at 8:56 AM Björn Larsson <bjorn.x.larsson@telia.com> wrote:
> Den 2019-04-08 kl. 16:06, skrev Nikita Popov: > > > On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> > wrote: > > > >> Hi internals, > >> > >> Motivated by the recent list comprehensions RFC, I think it's time we > took > >> another look at short closures: > >> > >> https://wiki.php.net/rfc/arrow_functions_v2 > >> > >> This is based on a previous (withdrawn) proposal by Levi & Bob. It uses > >> the syntax > >> > >> fn($x) => $x * $multiplier > >> > >> and implicit by-value variable binding. This example is roughly > equivalent > >> to: > >> > >> function($x) use($multiplier) { return $x * $multiplier; } > >> > >> The RFC contains a detailed discussion of syntax choices and binding > modes. > >> > >> Regards, > >> Nikita > >> > > Heads up: I plan to start voting on this RFC tomorrow if nothing new > comes > > up. > > > > Most of the discussion was (as expected) about the choice of syntax. > > Ultimately I think there are many reasonable choices we can make here, > but > > we should stick to a specific proposal for the purposes of the RFC vote. > > None of the given arguments convinced me that some other syntax is > > *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a > > matter of some choices being slightly better in one case and slightly > worse > > in another. My personal runner-up would be \($x, $y) => $x*$y, but I > > suspect that there are some people who are more strongly biased against > > "sigil salad" than I am... > > > > Nikita > Hi, > > I recall that the perception of the ==> syntax in the Hacklang user > community was quite positive. Of course it was implementation > difficulties. Are they still to cumbersome in PHP? > > Personally I prefer that one being more readable or the \ one. > Anyway, glad to see that short closures finally is on the road > again! >
The ==> syntax is the other one I implemented ( https://github.com/php/php-src/pull/3945). The implementation is based on lexer lookahead, which is ugly but still manageable. I haven't seen much support for this variant in this discussion though. And of course, if there's no strong preference for ==>, I'd rather go with the variant that is easier for us (and all 3rd party tooling) to support from a technical perspective. Nikita

Björn Larsson

7 years ago
Den 2019-04-09 kl. 12:19, skrev Nikita Popov:
> On Tue, Apr 9, 2019 at 8:56 AM Björn Larsson <bjorn.x.larsson@telia.com> > wrote: > >> Den 2019-04-08 kl. 16:06, skrev Nikita Popov: >> >>> On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> >> wrote: >>>> Hi internals, >>>> >>>> Motivated by the recent list comprehensions RFC, I think it's time we >> took >>>> another look at short closures: >>>> >>>> https://wiki.php.net/rfc/arrow_functions_v2 >>>> >>>> This is based on a previous (withdrawn) proposal by Levi & Bob. It uses >>>> the syntax >>>> >>>> fn($x) => $x * $multiplier >>>> >>>> and implicit by-value variable binding. This example is roughly >> equivalent >>>> to: >>>> >>>> function($x) use($multiplier) { return $x * $multiplier; } >>>> >>>> The RFC contains a detailed discussion of syntax choices and binding >> modes. >>>> Regards, >>>> Nikita >>>> >>> Heads up: I plan to start voting on this RFC tomorrow if nothing new >> comes >>> up. >>> >>> Most of the discussion was (as expected) about the choice of syntax. >>> Ultimately I think there are many reasonable choices we can make here, >> but >>> we should stick to a specific proposal for the purposes of the RFC vote. >>> None of the given arguments convinced me that some other syntax is >>> *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a >>> matter of some choices being slightly better in one case and slightly >> worse >>> in another. My personal runner-up would be \($x, $y) => $x*$y, but I >>> suspect that there are some people who are more strongly biased against >>> "sigil salad" than I am... >>> >>> Nikita >> Hi, >> >> I recall that the perception of the ==> syntax in the Hacklang user >> community was quite positive. Of course it was implementation >> difficulties. Are they still to cumbersome in PHP? >> >> Personally I prefer that one being more readable or the \ one. >> Anyway, glad to see that short closures finally is on the road >> again! >> > The ==> syntax is the other one I implemented ( > https://github.com/php/php-src/pull/3945). The implementation is based on > lexer lookahead, which is ugly but still manageable. I haven't seen much > support for this variant in this discussion though. And of course, if > there's no strong preference for ==>, I'd rather go with the variant that > is easier for us (and all 3rd party tooling) to support from a technical > perspective. > > Nikita
Maybe part of the reason it didn't attract to much support is that people are quite aware and respect the implementation difficulties. I recall a comment in this thread pointing in that direction. Well it's probably me being a long-time PHP user and now trying to learn RUST that finds the fn() syntax a bit confusing ;-) From that perspective I would prefer the \$x => $x **2 vs fn($x) => $x **2 or the ==> one. r//Björn L

Björn Larsson

7 years ago
Den 2019-04-09 kl. 17:23, skrev Björn Larsson:
> Den 2019-04-09 kl. 12:19, skrev Nikita Popov: >> On Tue, Apr 9, 2019 at 8:56 AM Björn Larsson <bjorn.x.larsson@telia.com> >> wrote: >> >>> Den 2019-04-08 kl. 16:06, skrev Nikita Popov: >>> >>>> On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> >>> wrote: >>>>> Hi internals, >>>>> >>>>> Motivated by the recent list comprehensions RFC, I think it's time we >>> took >>>>> another look at short closures: >>>>> >>>>> https://wiki.php.net/rfc/arrow_functions_v2 >>>>> >>>>> This is based on a previous (withdrawn) proposal by Levi & Bob. It >>>>> uses >>>>> the syntax >>>>> >>>>>       fn($x) => $x * $multiplier >>>>> >>>>> and implicit by-value variable binding. This example is roughly >>> equivalent >>>>> to: >>>>> >>>>>       function($x) use($multiplier) { return $x * $multiplier; } >>>>> >>>>> The RFC contains a detailed discussion of syntax choices and binding >>> modes. >>>>> Regards, >>>>> Nikita >>>>> >>>> Heads up: I plan to start voting on this RFC tomorrow if nothing new >>> comes >>>> up. >>>> >>>> Most of the discussion was (as expected) about the choice of syntax. >>>> Ultimately I think there are many reasonable choices we can make here, >>> but >>>> we should stick to a specific proposal for the purposes of the RFC >>>> vote. >>>> None of the given arguments convinced me that some other syntax is >>>> *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a >>>> matter of some choices being slightly better in one case and slightly >>> worse >>>> in another. My personal runner-up would be \($x, $y) => $x*$y, but I >>>> suspect that there are some people who are more strongly biased >>>> against >>>> "sigil salad" than I am... >>>> >>>> Nikita >>> Hi, >>> >>> I recall that the perception of the ==> syntax in the Hacklang user >>> community was quite positive. Of course it was implementation >>> difficulties. Are they still to cumbersome in PHP? >>> >>> Personally I prefer that one being more readable or the \ one. >>> Anyway, glad to see that short closures finally is on the road >>> again! >>> >> The ==> syntax is the other one I implemented ( >> https://github.com/php/php-src/pull/3945). The implementation is >> based on >> lexer lookahead, which is ugly but still manageable. I haven't seen much >> support for this variant in this discussion though. And of course, if >> there's no strong preference for ==>, I'd rather go with the variant >> that >> is easier for us (and all 3rd party tooling) to support from a technical >> perspective. >> >> Nikita > Maybe part of the reason it didn't attract to much support is that people > are quite aware and respect the implementation difficulties. I recall a > comment in this thread pointing in that direction. > > Well it's probably me being a long-time PHP user and now trying to learn > RUST that finds the fn() syntax a bit confusing ;-) From that > perspective I > would prefer the \$x => $x **2 vs fn($x) => $x **2 or the ==> one. > > r//Björn L > >
Hi again, Just read the RFC a bit closer and saw that \$x is'nt possible, pity. Taking an example from chregu gist with arrow function inside a function call: - $waithandles = $this->urls->map(fn($url) => $this->fetcher->fetch($url)); - $waithandles = $this->urls->map(\($url) => $this->fetcher->fetch($url)); - $waithandles = $this->urls->map($url ==> $this->fetcher->fetch($url)); I would say that when lambda functions occurs in function calls I find the \ or ==> syntax more readable. Over & out //Björn L

Robert Hickman

7 years ago
> - $waithandles = $this->urls->map(fn($url) => $this->fetcher->fetch($url)); > - $waithandles = $this->urls->map(\($url) => $this->fetcher->fetch($url)); > - $waithandles = $this->urls->map($url ==> $this->fetcher->fetch($url)); > > I would say that when lambda functions occurs in function calls I find the > \ or ==> syntax more readable. >
To me, in that context, '==>' is the most readable as it does not have parentheses on the argument. It's a bit visually noisy with them.

Markus Fischer

7 years ago
On 10.04.19 00:10, Robert Hickman wrote:
>> - $waithandles = $this->urls->map(fn($url) => $this->fetcher->fetch($url)); >> - $waithandles = $this->urls->map(\($url) => $this->fetcher->fetch($url)); >> - $waithandles = $this->urls->map($url ==> $this->fetcher->fetch($url)); >> >> I would say that when lambda functions occurs in function calls I find the >> \ or ==> syntax more readable. >> > > To me, in that context, '==>' is the most readable as it does not have > parentheses on the argument. It's a bit visually noisy with them.
I concur, `==>` to me also stands out the most easiest to read without too much parenthesis noise. - Markus

Gabriel Ostrolucky

7 years ago
Those parentheses are important when having multiple argument On 10 April 2019 10:02:46 AM Markus Fischer <markus@fischer.name> wrote:

Markus Fischer

7 years ago
Hi, Gabriel, On 10.04.19 10:33, Gabriel O wrote:
> Those parentheses are important when having multiple argument
Please don't top post, thanks! Thanks for pointing it out, I'm aware. Still `===>` would better stand out to _me_ personally. thanks, - Markus

Rowan Collins

7 years ago
On Tue, 9 Apr 2019 at 11:20, Nikita Popov <nikita.ppv@gmail.com> wrote:
> The ==> syntax is the other one I implemented ( > https://github.com/php/php-src/pull/3945). The implementation is based on > lexer lookahead, which is ugly but still manageable. I haven't seen much > support for this variant in this discussion though. And of course, if > there's no strong preference for ==>, I'd rather go with the variant that > is easier for us (and all 3rd party tooling) to support from a technical > perspective. >
I'd just like to amplify this mention of 3rd party tooling: if we go with something which requires complex lexer/parser rules, then every editor, IDE, and static analysis tool will need to also work with that syntax. For those saying they "slightly prefer" ==> please ask yourself, do you prefer it enough to add complexity to every tool that wants to process PHP source code? Regards,
-- Rowan Collins [IMSoP]

Robert Hickman

7 years ago
> I'd just like to amplify this mention of 3rd party tooling: if we go with > something which requires complex lexer/parser rules, then every editor, > IDE, and static analysis tool will need to also work with that syntax. >
Is this actually a problem? Don't these tools make use of existing parsers like 'php parser', thus the cost is lower than initially apparent?

Rowan Collins

7 years ago
On Wed, 10 Apr 2019 at 09:59, Robert Hickman <robehickman@gmail.com> wrote:
> > I'd just like to amplify this mention of 3rd party tooling: if we go with > > something which requires complex lexer/parser rules, then every editor, > > IDE, and static analysis tool will need to also work with that syntax. > > > > Is this actually a problem? Don't these tools make use of existing > parsers like 'php parser', thus the cost is lower than initially > apparent? >
I don't think you can generalise about "these tools" at all - for instance, PHPStorm is written in Java, and VSCode is written in JS; I doubt they share any parser components with each other, or with anything written in C or PHP itself. We're not just talking about existing tools, either, but every tool created until the language dies. Regards,
-- Rowan Collins [IMSoP]

Stephen Reay

7 years ago
> On 10 Apr 2019, at 15:59, Robert Hickman <robehickman@gmail.com> wrote: > >> I'd just like to amplify this mention of 3rd party tooling: if we go with >> something which requires complex lexer/parser rules, then every editor, >> IDE, and static analysis tool will need to also work with that syntax. >> > > Is this actually a problem? Don't these tools make use of existing > parsers like 'php parser', thus the cost is lower than initially > apparent? > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >
This seems like a risky thing to assume “it’ll be fine” about. I’d like to add my (non-voting) voice in favour of the `fn(…)` syntax. I don’t know that I’d get a lot of use out of short closures anyway, but I’d at least like it to remain readable on the occasion I might use them, or (more likely) work on something where someone else uses them. I question (loudly) any view that less characters is automatically improves readability. I’ve yet to see a project anywhere that suffered overrun or saw low productivity because developers were busy typing/reading parenthesis around argument lists or keywords.

M. W. Moe

7 years ago
Hello, this is not much the syntax which is problematic here but the implicit lambda capture ruleset proposed; for that, it would require (fully justified in this case) a preprocessing step hence a language contextual analysis step or what people call `static`. On Wed, Apr 10, 2019 at 2:35 AM Stephen Reay <php-lists@koalephant.com> wrote:

M. W. Moe

7 years ago
@Stephen Reay, I have never seen ML programmers being improductive; that's because maybe you witness people unfit for it; math is less character and contextual i.e meanings change according to environment; it's fully readable to people fitted for it. On Wed, Apr 10, 2019 at 10:18 AM M. W. Moe <mo.mu.wss@gmail.com> wrote:

Stephen Reay

7 years ago
> On 11 Apr 2019, at 00:32, M. W. Moe <mo.mu.wss@gmail.com> wrote: > > I have never seen ML programmers being improductive;
Great. I’ve never seen a pig crash a plane, therefore all pilots should be pigs? Given your previous comments regarding removing “java impurities” it’s hard to take anything you suggest seriously.

Björn Larsson

7 years ago
Den 2019-04-10 kl. 10:39, skrev Rowan Collins:
> On Tue, 9 Apr 2019 at 11:20, Nikita Popov <nikita.ppv@gmail.com> wrote: > >> The ==> syntax is the other one I implemented ( >> https://github.com/php/php-src/pull/3945). The implementation is based on >> lexer lookahead, which is ugly but still manageable. I haven't seen much >> support for this variant in this discussion though. And of course, if >> there's no strong preference for ==>, I'd rather go with the variant that >> is easier for us (and all 3rd party tooling) to support from a technical >> perspective. >> > > I'd just like to amplify this mention of 3rd party tooling: if we go with > something which requires complex lexer/parser rules, then every editor, > IDE, and static analysis tool will need to also work with that syntax. > > For those saying they "slightly prefer" ==> please ask yourself, do you > prefer it enough to add complexity to every tool that wants to process PHP > source code? > > Regards,
Hi, Could then the \($x) syntax be a good compromise between readability & implementation? It also has the advantage of having less BC impact, since the fn keyword must be a full keyword according to RFC. As a side note I'm thinking on if the Hacklang implementation could shed some light on tooling issues that they got, due to their implementation of the ==> syntax. r//Björn L

Rowan Collins

7 years ago
On 10 April 2019 21:56:41 BST, "Björn Larsson" <bjorn.x.larsson@telia.com> wrote:
>Could then the \($x) syntax be a good compromise between >readability & implementation?
Personally, I don't find it "more readable"; on the one hand, it's one character shorter; on the other, it stands out less from everything else. My personal bias against it is that I'm too used to reading \ as "escape", so every time I see examples my first reaction is "what does an escaped parenthesis mean?" I'm sure I'd get used to it, but I prefer "fn" because it more immediately makes me think "function". Regards,
-- Rowan Collins [IMSoP]

Robert Hickman

7 years ago
On Thu, 11 Apr 2019 at 00:43, Rowan Collins <rowan.collins@gmail.com> wrote:
> > On 10 April 2019 21:56:41 BST, "Björn Larsson" <bjorn.x.larsson@telia.com> wrote: > >Could then the \($x) syntax be a good compromise between > >readability & implementation? >
This syntax does make sense to me, although only as I've seen it before in Haskell, which does something similar: https://wiki.haskell.org/Anonymous_function I think that people will get used to whatever becomes common.

Kosit Supanyo

7 years ago
Hi internals, This is my first write to this list but I've been followed your discussions quite a while ago. For a brief introduction, my name is Kosit, I'm a programmer from Thailand and I've been using PHP since version 3 (for a short period before moving to PHP4). I'm a fan of `fn` syntax and OK to go with it but I would like to propose some extended syntax & behavior about binding. What if we can omit the `use` keyword at all and use only second parentheses for variable & reference binding and make the presence of second parentheses turn off implicit variable binding. $a = 0; $f1 = fn(): int => $a; $b = 0; $f2 = fn(): int () => $b; equivalent to $a = 0; $f1 = function () use ($a) { return $a; }; $b = 0; $f2 = function () { return $b; }; And what if we can omit parentheses at all if fn has no parameters. $f = fn => $this->doSomethingWithAB($a, $b); $multiStmtBody = fn { // ... }; When people want to import references (and addtional variables) they have to do it explicitly like before but without `use` keyword. $f = fn($y): array (&$arr, $x) => $this->doSomethingWithArrAndXY($arr, $x, $y); equivalent to $f = function ($y): array use (&$arr, $x) { return $this->doSomethingWithArrAndXY($arr, $x, $y); }; Second parens without `use` keyword may be ugly but can be seen as an abbreviation of old closure syntax. This can eliminate possible problems of reference binding (switching) syntax described in the RFC that may cause undesired behavior and performance problem because `use (&)` will make all variables by-reference bound. Summary: 1. No `use` keyword for binding. 2. The presence of second parentheses will turn off implicit binding. 3. Can omit parentheses if fn has no parameters. I apologize in advance for my bad English but I hope my idea can be taken into consideration or at least can be transformed into another useful idea. Regards, Kosit On Mon, Apr 8, 2019 at 9:07 PM Nikita Popov <nikita.ppv@gmail.com> wrote:
> > On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> wrote: > > > Hi internals, > > > > Motivated by the recent list comprehensions RFC, I think it's time we
took
> > another look at short closures: > > > > https://wiki.php.net/rfc/arrow_functions_v2 > > > > This is based on a previous (withdrawn) proposal by Levi & Bob. It uses > > the syntax > > > > fn($x) => $x * $multiplier > > > > and implicit by-value variable binding. This example is roughly
equivalent
> > to: > > > > function($x) use($multiplier) { return $x * $multiplier; } > > > > The RFC contains a detailed discussion of syntax choices and binding
modes.
> > > > Regards, > > Nikita > > > > Heads up: I plan to start voting on this RFC tomorrow if nothing new comes > up. > > Most of the discussion was (as expected) about the choice of syntax. > Ultimately I think there are many reasonable choices we can make here, but > we should stick to a specific proposal for the purposes of the RFC vote. > None of the given arguments convinced me that some other syntax is > *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a > matter of some choices being slightly better in one case and slightly
worse

M. W. Moe

7 years ago
Hello, for now what I see is a bit of everything: - adding a contextual keyword/alias to function - enforce by reference - a lack of coherence too mockups (I like the arrow idea but won't ever replace `use` functionalities) "keeping the unnecessary arrow" class bar { public fn foo(int $x, int $y) { return fn($x) [&$y] => { $x * $y; }; } } "aliasing function keyword to fn; aliasing use keyword with brackets syntax" class bar { public fn foo(int $x, int $y) { return fn($x) [&$y] { $x * $y; } } } On Tue, Apr 9, 2019 at 3:29 PM Kosit Supanyo <webdevxp.com@gmail.com> wrote:

M. W. Moe

7 years ago
and maybe one day if public, protected, private, interface, abstract i.e java impurities are finally removed: class bar { owned var $m_a : float = 0.0; var $b : object = null; fn foo(int $x, int $y) : int { return fn($x) [&$y] { $x * $y; }; } owned fn bar() : void { return; } } On Tue, Apr 9, 2019 at 5:33 PM M. W. Moe <mo.mu.wss@gmail.com> wrote:

Nikita Popov

7 years ago
On Mon, Apr 8, 2019 at 4:06 PM Nikita Popov <nikita.ppv@gmail.com> wrote:
> On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> wrote: > >> Hi internals, >> >> Motivated by the recent list comprehensions RFC, I think it's time we >> took another look at short closures: >> >> https://wiki.php.net/rfc/arrow_functions_v2 >> >> This is based on a previous (withdrawn) proposal by Levi & Bob. It uses >> the syntax >> >> fn($x) => $x * $multiplier >> >> and implicit by-value variable binding. This example is roughly >> equivalent to: >> >> function($x) use($multiplier) { return $x * $multiplier; } >> >> The RFC contains a detailed discussion of syntax choices and binding >> modes. >> >> Regards, >> Nikita >> > > Heads up: I plan to start voting on this RFC tomorrow if nothing new comes > up. > > Most of the discussion was (as expected) about the choice of syntax. > Ultimately I think there are many reasonable choices we can make here, but > we should stick to a specific proposal for the purposes of the RFC vote. > None of the given arguments convinced me that some other syntax is > *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a > matter of some choices being slightly better in one case and slightly worse > in another. My personal runner-up would be \($x, $y) => $x*$y, but I > suspect that there are some people who are more strongly biased against > "sigil salad" than I am... > > Nikita >
So, there's been quite a bit of extra discussion here... unfortunately I can't say that it really clarified anything, we're still circling around different syntax choices, with the main contenders being fn, \ and ==>. fn($x) => $x fn($x, $y) => $x*$y \$x => $x \($x, $y) => $x*$y $x ==> $x ($x, $y) ==> $x*$y I think the main qualities of these possibilities are: * Implementation complexity: fn and \ are easy, ==> is hard (lexer hack). * Availability of reduced syntax: \ an ==> have a special single-argument syntax, fn doesn't. * Obviousness/readability: fn and ==> are obvious, while \ is not. Especially \$x => $x looks quite obscure to the uninitiated (is that a variable escape, like it would be in strings?) At this point I'm considering to either a) move forward with fn() as the choice I'd consider most likely to gather a consensus or b) have a secondary three-way vote between these three syntax choices. Nikita

Björn Larsson

7 years ago
Den 2019-04-14 kl. 18:52, skrev Nikita Popov:
> On Mon, Apr 8, 2019 at 4:06 PM Nikita Popov <nikita.ppv@gmail.com> wrote: > >> On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> wrote: >> >>> Hi internals, >>> >>> Motivated by the recent list comprehensions RFC, I think it's time we >>> took another look at short closures: >>> >>> https://wiki.php.net/rfc/arrow_functions_v2 >>> >>> This is based on a previous (withdrawn) proposal by Levi & Bob. It uses >>> the syntax >>> >>> fn($x) => $x * $multiplier >>> >>> and implicit by-value variable binding. This example is roughly >>> equivalent to: >>> >>> function($x) use($multiplier) { return $x * $multiplier; } >>> >>> The RFC contains a detailed discussion of syntax choices and binding >>> modes. >>> >>> Regards, >>> Nikita >>> >> Heads up: I plan to start voting on this RFC tomorrow if nothing new comes >> up. >> >> Most of the discussion was (as expected) about the choice of syntax. >> Ultimately I think there are many reasonable choices we can make here, but >> we should stick to a specific proposal for the purposes of the RFC vote. >> None of the given arguments convinced me that some other syntax is >> *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a >> matter of some choices being slightly better in one case and slightly worse >> in another. My personal runner-up would be \($x, $y) => $x*$y, but I >> suspect that there are some people who are more strongly biased against >> "sigil salad" than I am... >> >> Nikita >> > So, there's been quite a bit of extra discussion here... unfortunately I > can't say that it really clarified anything, we're still circling around > different syntax choices, with the main contenders being fn, \ and ==>. > > fn($x) => $x > fn($x, $y) => $x*$y > > \$x => $x > \($x, $y) => $x*$y > > $x ==> $x > ($x, $y) ==> $x*$y > > I think the main qualities of these possibilities are: > > * Implementation complexity: fn and \ are easy, ==> is hard (lexer hack). > * Availability of reduced syntax: \ an ==> have a special single-argument > syntax, fn doesn't. > * Obviousness/readability: fn and ==> are obvious, while \ is not. > Especially \$x => $x looks quite obscure to the uninitiated (is that a > variable escape, like it would be in strings?) > > At this point I'm considering to either a) move forward with fn() as the > choice I'd consider most likely to gather a consensus or b) have a > secondary three-way vote between these three syntax choices. > > Nikita
Hi, Even if a consensus wasn't reached I feel that there has been quite a constructive discussion, where the pros and cons were drilled down for the syntax alternatives at hand. So having no voting rights myself, but alternative B for voting looks ok in my eyes. One could ask having three alternatives or two? OTOH, those three alternatives are now on the table and nothing else, so all three. But if implementation of ==> are much to overwhelming, only two. r//Björn L

Benjamin Morel

7 years ago
Even though I was originally hoping for something closer to JS syntax, considering Nikita's summary it looks like the best contender is still fn(), as originally proposed. At least it looks like a function indeed, to the uninitiated. So FWIW, I think that a vote for the fn() syntax only still makes sense. The risk with the 2 or 3 options is never being able to reach a concensus: is a relative majority or an absolute majority for one of the syntaxes acceptable, or are you required by the RFC process to get a 2/3 majority for this vote as well? If so, considering the discussion so far, I think this will be hard to achieve with 2 choices, let alone with 3. - Ben

Björn Larsson

7 years ago
Den 2019-04-15 kl. 13:48, skrev Benjamin Morel:
> Even though I was originally hoping for something closer to JS syntax, > considering Nikita's summary it looks like the best contender is still > fn(), as originally proposed. > At least it looks like a function indeed, to the uninitiated. > > So FWIW, I think that a vote for the fn() syntax only still makes > sense. The risk with the 2 or 3 options is never being able to reach a > concensus: is a relative majority or an absolute majority for one of > the syntaxes acceptable, or are you required by the RFC process to get > a 2/3 majority for this vote as well? If so, considering the > discussion so far, I think this will be hard to achieve with 2 > choices, let alone with 3. > > - Ben
If it lands in a secondary three way vote I would assume it's the vote getting the most votes. Otherwise the RFC could land in a limbo, getting yes on feature but no on syntax. Good to get assumption confirmed though... r//Björn L

Larry Garfield

7 years ago
On Mon, Apr 15, 2019, at 6:48 AM, Benjamin Morel wrote:
> Even though I was originally hoping for something closer to JS syntax, > considering Nikita's summary it looks like the best contender is still > fn(), as originally proposed. > At least it looks like a function indeed, to the uninitiated. > > So FWIW, I think that a vote for the fn() syntax only still makes sense. > The risk with the 2 or 3 options is never being able to reach a concensus: > is a relative majority or an absolute majority for one of the syntaxes > acceptable, or are you required by the RFC process to get a 2/3 majority > for this vote as well? If so, considering the discussion so far, I think > this will be hard to achieve with 2 choices, let alone with 3. > > - Ben
I don't think the wiki currently supports it, but that's exactly what ranked choice voting is for. :-) --Larry Garfield

Stephen Reay

7 years ago
> On 14 Apr 2019, at 23:52, Nikita Popov <nikita.ppv@gmail.com> wrote: > > On Mon, Apr 8, 2019 at 4:06 PM Nikita Popov <nikita.ppv@gmail.com> wrote: > >> On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> wrote: >> >>> Hi internals, >>> >>> Motivated by the recent list comprehensions RFC, I think it's time we >>> took another look at short closures: >>> >>> https://wiki.php.net/rfc/arrow_functions_v2 >>> >>> This is based on a previous (withdrawn) proposal by Levi & Bob. It uses >>> the syntax >>> >>> fn($x) => $x * $multiplier >>> >>> and implicit by-value variable binding. This example is roughly >>> equivalent to: >>> >>> function($x) use($multiplier) { return $x * $multiplier; } >>> >>> The RFC contains a detailed discussion of syntax choices and binding >>> modes. >>> >>> Regards, >>> Nikita >>> >> >> Heads up: I plan to start voting on this RFC tomorrow if nothing new comes >> up. >> >> Most of the discussion was (as expected) about the choice of syntax. >> Ultimately I think there are many reasonable choices we can make here, but >> we should stick to a specific proposal for the purposes of the RFC vote. >> None of the given arguments convinced me that some other syntax is >> *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a >> matter of some choices being slightly better in one case and slightly worse >> in another. My personal runner-up would be \($x, $y) => $x*$y, but I >> suspect that there are some people who are more strongly biased against >> "sigil salad" than I am... >> >> Nikita >> > > So, there's been quite a bit of extra discussion here... unfortunately I > can't say that it really clarified anything, we're still circling around > different syntax choices, with the main contenders being fn, \ and ==>. > > fn($x) => $x > fn($x, $y) => $x*$y > > \$x => $x > \($x, $y) => $x*$y > > $x ==> $x > ($x, $y) ==> $x*$y > > I think the main qualities of these possibilities are: > > * Implementation complexity: fn and \ are easy, ==> is hard (lexer hack). > * Availability of reduced syntax: \ an ==> have a special single-argument > syntax, fn doesn't. > * Obviousness/readability: fn and ==> are obvious, while \ is not. > Especially \$x => $x looks quite obscure to the uninitiated (is that a > variable escape, like it would be in strings?) > > At this point I'm considering to either a) move forward with fn() as the > choice I'd consider most likely to gather a consensus or b) have a > secondary three-way vote between these three syntax choices. > > Nikita
As someone without voting rights (and thus you can take this with a grain of salt), given what you’ve highlighted I believe your option (a) is the obvious one: You said yourself, that `==>` is a more complex/hard implementation (which is bad) and that `\` is non obvious/obscure, and (IMO) it’s worse as far as readability goes. As I’ve said before, I expect to use this feature (if it passes) very little if at all, but I still appreciate that `fn()...` keeps reasonably-familiar/obvious syntax, because even if I choose not to write using this feature, I’ll invariably have to read someone else’s code that does use it. Cheers Stephen

Björn Larsson

7 years ago
Den 2019-04-14 kl. 18:52, skrev Nikita Popov:
> On Mon, Apr 8, 2019 at 4:06 PM Nikita Popov <nikita.ppv@gmail.com> wrote: > >> On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> wrote: >> >>> Hi internals, >>> >>> Motivated by the recent list comprehensions RFC, I think it's time we >>> took another look at short closures: >>> >>> https://wiki.php.net/rfc/arrow_functions_v2 >>> >>> This is based on a previous (withdrawn) proposal by Levi & Bob. It uses >>> the syntax >>> >>> fn($x) => $x * $multiplier >>> >>> and implicit by-value variable binding. This example is roughly >>> equivalent to: >>> >>> function($x) use($multiplier) { return $x * $multiplier; } >>> >>> The RFC contains a detailed discussion of syntax choices and binding >>> modes. >>> >>> Regards, >>> Nikita >>> >> Heads up: I plan to start voting on this RFC tomorrow if nothing new comes >> up. >> >> Most of the discussion was (as expected) about the choice of syntax. >> Ultimately I think there are many reasonable choices we can make here, but >> we should stick to a specific proposal for the purposes of the RFC vote. >> None of the given arguments convinced me that some other syntax is >> *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a >> matter of some choices being slightly better in one case and slightly worse >> in another. My personal runner-up would be \($x, $y) => $x*$y, but I >> suspect that there are some people who are more strongly biased against >> "sigil salad" than I am... >> >> Nikita >> > So, there's been quite a bit of extra discussion here... unfortunately I > can't say that it really clarified anything, we're still circling around > different syntax choices, with the main contenders being fn, \ and ==>. > > fn($x) => $x > fn($x, $y) => $x*$y > > \$x => $x > \($x, $y) => $x*$y > > $x ==> $x > ($x, $y) ==> $x*$y > > I think the main qualities of these possibilities are: > > * Implementation complexity: fn and \ are easy, ==> is hard (lexer hack). > * Availability of reduced syntax: \ an ==> have a special single-argument > syntax, fn doesn't. > * Obviousness/readability: fn and ==> are obvious, while \ is not. > Especially \$x => $x looks quite obscure to the uninitiated (is that a > variable escape, like it would be in strings?) > > At this point I'm considering to either a) move forward with fn() as the > choice I'd consider most likely to gather a consensus or b) have a > secondary three-way vote between these three syntax choices. > > Nikita
Hi again , I came to think on BC impact of fn() syntax. The RFC mentions 12 matches and 1 in namespaces. Should one conclude that the BC impact is low or is their other aspects to consider? I myself uses fn as a dummy function name when writing "test" code. r//Björn L

Nikita Popov

7 years ago
On Wed, Apr 17, 2019 at 11:23 AM Björn Larsson <bjorn.x.larsson@telia.com> wrote:
> Den 2019-04-14 kl. 18:52, skrev Nikita Popov: > > On Mon, Apr 8, 2019 at 4:06 PM Nikita Popov <nikita.ppv@gmail.com> > wrote: > > > >> On Wed, Mar 13, 2019 at 4:56 PM Nikita Popov <nikita.ppv@gmail.com> > wrote: > >> > >>> Hi internals, > >>> > >>> Motivated by the recent list comprehensions RFC, I think it's time we > >>> took another look at short closures: > >>> > >>> https://wiki.php.net/rfc/arrow_functions_v2 > >>> > >>> This is based on a previous (withdrawn) proposal by Levi & Bob. It uses > >>> the syntax > >>> > >>> fn($x) => $x * $multiplier > >>> > >>> and implicit by-value variable binding. This example is roughly > >>> equivalent to: > >>> > >>> function($x) use($multiplier) { return $x * $multiplier; } > >>> > >>> The RFC contains a detailed discussion of syntax choices and binding > >>> modes. > >>> > >>> Regards, > >>> Nikita > >>> > >> Heads up: I plan to start voting on this RFC tomorrow if nothing new > comes > >> up. > >> > >> Most of the discussion was (as expected) about the choice of syntax. > >> Ultimately I think there are many reasonable choices we can make here, > but > >> we should stick to a specific proposal for the purposes of the RFC vote. > >> None of the given arguments convinced me that some other syntax is > >> *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a > >> matter of some choices being slightly better in one case and slightly > worse > >> in another. My personal runner-up would be \($x, $y) => $x*$y, but I > >> suspect that there are some people who are more strongly biased against > >> "sigil salad" than I am... > >> > >> Nikita > >> > > So, there's been quite a bit of extra discussion here... unfortunately I > > can't say that it really clarified anything, we're still circling around > > different syntax choices, with the main contenders being fn, \ and ==>. > > > > fn($x) => $x > > fn($x, $y) => $x*$y > > > > \$x => $x > > \($x, $y) => $x*$y > > > > $x ==> $x > > ($x, $y) ==> $x*$y > > > > I think the main qualities of these possibilities are: > > > > * Implementation complexity: fn and \ are easy, ==> is hard (lexer > hack). > > * Availability of reduced syntax: \ an ==> have a special > single-argument > > syntax, fn doesn't. > > * Obviousness/readability: fn and ==> are obvious, while \ is not. > > Especially \$x => $x looks quite obscure to the uninitiated (is that a > > variable escape, like it would be in strings?) > > > > At this point I'm considering to either a) move forward with fn() as the > > choice I'd consider most likely to gather a consensus or b) have a > > secondary three-way vote between these three syntax choices. > > > > Nikita > > Hi again , > > I came to think on BC impact of fn() syntax. The RFC mentions > 12 matches and 1 in namespaces. Should one conclude that > the BC impact is low or is their other aspects to consider? I > myself uses fn as a dummy function name when writing > "test" code. >
Yes, the impact is expected to be pretty much limited to my https://github.com/nikic/iter library (where I will rename the namespace in the upcoming 2.0 version) and test code. Nikita

Larry Garfield

7 years ago
On Sun, Apr 14, 2019, at 11:52 AM, Nikita Popov wrote:
> So, there's been quite a bit of extra discussion here... unfortunately I > can't say that it really clarified anything, we're still circling around > different syntax choices, with the main contenders being fn, \ and ==>. > > fn($x) => $x > fn($x, $y) => $x*$y > > \$x => $x > \($x, $y) => $x*$y > > $x ==> $x > ($x, $y) ==> $x*$y > > I think the main qualities of these possibilities are: > > * Implementation complexity: fn and \ are easy, ==> is hard (lexer hack). > * Availability of reduced syntax: \ an ==> have a special single-argument > syntax, fn doesn't. > * Obviousness/readability: fn and ==> are obvious, while \ is not. > Especially \$x => $x looks quite obscure to the uninitiated (is that a > variable escape, like it would be in strings?) > > At this point I'm considering to either a) move forward with fn() as the > choice I'd consider most likely to gather a consensus or b) have a > secondary three-way vote between these three syntax choices. > > Nikita
I was under the impression from your earlier comments that ==> made the lexer too unhappy to even consider. Is that not the case? From a usability POV, I think ==> has the edge; it's reasonably self-documenting and has a short-circuit version that is still highly readable and not confusing. It also fits the "think of it as an expression not a function call" mindset, which is important. The only downside is the implementation complexity. I think you have final call on whether that would be too-ugly implementation-wise. If it doesn't make the lexer too unhappy ==> is my preference, I think. \$x I'd probably get used to, even if it is a bit ugly. fn() is the "safe" option: Most verbose but keeps the lexer happy. --Larry Garfield

Björn Larsson

7 years ago
Den 2019-04-17 kl. 16:14, skrev Larry Garfield:
> On Sun, Apr 14, 2019, at 11:52 AM, Nikita Popov wrote: > >> So, there's been quite a bit of extra discussion here... unfortunately I >> can't say that it really clarified anything, we're still circling around >> different syntax choices, with the main contenders being fn, \ and ==>. >> >> fn($x) => $x >> fn($x, $y) => $x*$y >> >> \$x => $x >> \($x, $y) => $x*$y >> >> $x ==> $x >> ($x, $y) ==> $x*$y >> >> I think the main qualities of these possibilities are: >> >> * Implementation complexity: fn and \ are easy, ==> is hard (lexer hack). >> * Availability of reduced syntax: \ an ==> have a special single-argument >> syntax, fn doesn't. >> * Obviousness/readability: fn and ==> are obvious, while \ is not. >> Especially \$x => $x looks quite obscure to the uninitiated (is that a >> variable escape, like it would be in strings?) >> >> At this point I'm considering to either a) move forward with fn() as the >> choice I'd consider most likely to gather a consensus or b) have a >> secondary three-way vote between these three syntax choices. >> >> Nikita > I was under the impression from your earlier comments that ==> made the lexer too unhappy to even consider. Is that not the case? > > From a usability POV, I think ==> has the edge; it's reasonably self-documenting and has a short-circuit version that is still highly readable and not confusing. It also fits the "think of it as an expression not a function call" mindset, which is important. The only downside is the implementation complexity. I think you have final call on whether that would be too-ugly implementation-wise. > > If it doesn't make the lexer too unhappy ==> is my preference, I think. \$x I'd probably get used to, even if it is a bit ugly. fn() is the "safe" option: Most verbose but keeps the lexer happy. > > --Larry Garfield
Spot on I would say! The comment "think of it as an expression not a function call" captures my own hesitation for the fn() syntax quite well. Anyway it's in voting, so glad we finally got this truck moving :) r//Björn L

Net Mo

7 years ago
I like it. Only exception is: ``` fn&() => ...; ``` Which I would prefer to see reserved for the purpose that you've written as: ``` fn() use(&) => ...; ``` The & symbol of "return by ref", should be placed on the right of the parentheses, near the return type: ``` fn(int &$x)&: int => $x; fn(&$x)& => $x; ``` The same thing could be allowed on regular functions and methods. currently you'd write ``` public function &bar(): int{ /* ... */ } public function &baz(){ /* ... */ } ``` Since 7.4 one would be allowed to write this to mean the same thing: ``` public function bar()&: int{ /* ... */ } public function baz()&{ /* ... */ } ``` Would you guys agree on making a second RFC later changing this after and if this RFC passes and before 7.4 is released?