Lambda functions that have a single parameter are a common thing, e.g. for 
"key" functions: `sorted(items, key=lambda x: x['key'])`. For these cases 
however, the rather long word "lambda" together with the repetition of the 
parameter name, results in more overhead than actual content (the `x['key']`) 
and thus makes it more difficult to read. This is also a difficulty for `map` 
and `filter` for example where there's lots of visual overhead when using a 
lambda function and hence it's difficult to read: `filter(lambda x: x > 0, 
items)` or `map(lambda x: f'{x:.3f}', items)`.

Hence the proposal is to add a new syntax via the new token `?`. For the 
examples above:

* `sorted(items, key=?['key'])`
* `filter(? > 0, items)`
* `map(f'{?:.3f}', items)`

The rules are simple: whenever the token `?` is encountered as part of an 
expression (at a position where a name/identifier would be legal), the 
expression is replaced by a lambda function with a single parameter which has 
that expression as a return value, where any instances of `?` are replaced by 
the name of that single parameter. For example:

* `?['key']` translates to `lambda x: x['key']`
* `? > 0` translates to `lambda x: x > 0`
* `f'{?:.3f}'` translates to `lambda x: f'{x:.3f}'`
* `?*?` translates to `lambda x: x*x`

With the difference that the replacement function would use an unnamed 
parameter, i.e. not shadowing any names from outer scopes. So `? * x` would use 
`x` from enclosing scopes, not as the lambda parameter.

Regarding operator precedence, the rules would be similar as for lambda 
functions, i.e. it will include as much in the expression as it would for a 
lambda function.

To find more example use cases, I used `grep -rnE 'lambda 
[_a-zA-Z][_a-zA-Z0-9]*:' Lib/` on the CPython standard library to find single 
parameter lambda functions and there are various results coming up (although 
not all are applicable, e.g. because they return a constant value). I'll 
include a few examples below, but the actual list is much longer:

```
modes[char] = max(items, key=lambda x: x[1])
modes[char] = max(items, key=?[1])  # proposed new syntax

obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__")))
obj = unwrap(obj, stop=hasattr(?, "__signature__"))

s = re.sub(r"-[a-z]\b", lambda m: m.group().upper(), s)
s = re.sub(r"-[a-z]\b", ?.group().upper(), s)

members.sort(key=lambda t: (t[1], t[0]))
members.sort(key=(?[1], ?[0]))
```

Of course, there is no requirement to use `?` as the token, it could be any 
other character that's currently not used by Python, i.e. `$` or `!` would be 
possible too.
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/HADJG5L6ML7JRYKPRCSNJGWBY4NPG5NH/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to