Re: [PHP-DEV] Re: [RFC] Arrow functions / short closures

This is only part of a thread. view whole thread
March 15, 2019 02:21 ("Larry Garfield")
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 > > 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