Let's get onto it already: if you aren't familiar with expressions made with
lambda
keyword, there is following syntax:
lambda [p1[, p2[, p3[, ]]]]: <return-code-scrap>
where
[p1[, p2[, p3[, ... ]]]]
are parameters. Because they are encased with squared parentheses, they are optional.
<return-code-scrap>
can be anything, the
return
keyword shouldn't be used to precede the value from either
variable or function, which should be returned. If
lambda
expression was assigned to a variable, that variable becomes
callable.
c1lambda: 3 once called, returns 3. Lack of parameters
c2lambda x: x once called, returns anything passed to the parameter
c3_1lambda x1, x2: (x1, x2) once called, returns anything passed to the parameters, in a 2-item tuple
c3_2lambda x1, x2: x1, x2 shortened tuple notation doesn't work on lambda expressions, x2 is undefined after comma
c3_3lambda x1, x2: x1, lambda expression is placed in a tuple, call as c3_3[0](x1, x2)
These examples are quite simple, however, the one with
c3_2
variable would bind with some explanations: if we allowed shortened tuple notation, as in
return x1, x2
,
this would bind with different error, if that expression was appended to a parameter (no matter, if positional-only or keyword-only). There rather come up with version with
variable
c3_1
. Lambda expressions in C++, comparing to these in Python, are
extensible, because their bodies are defined via curly brackets
{}
.
auto c1[]() { return 3; };
This one is equivalent to previous example with
c1
variable. The C language does not support lambda expressions, while C++ has them since
C++11. In Python, you don't use curly parentheses, but mere circled brackets
()
and indentations.
But let's go back to lambda expressions in Python. In my opinion, they need improvement. I did read a book, which author is Julien Danjou, titled
Serious Python. Black-Belt
Advice on Deployment, Scalability, Testing and More (2019), and author of this book presented its better alternative -
functools.partial
class, in page 143.
Python 3 working team had also aspirations to remove the
lambda
keyword, along with its expressions, but because programmers had no different way to implement it,
it has been finally kept, as-is (Danjou in his book only said that in Python 3
lambda
keyword was qualified to be removed).
Lambda expressions can only contain one line of the code, so this is not like syntax for factual functions. In most cases we can create a function, and pass it to a variable or parameter
without circled parentheses.
def c1_tmp():
return 3
c1c1_tmp once called, returns 3. Lack of parameters
Next difference concerning lambda expressions in Python and C++ is that the second language allows (and even requires) to provide parameter types. But unlike in Python, types in both
C and C++ cannot be united unless... the
std::variant
generic class. In Python, you cannot type hint any of provided parameters in a lambda expression,
what forces programmers to create a function, and pass it to a variable or parameter, without circled brackets. To re-create example with
c2
variable, all we would need
is generic type.
auto c2[]<typename T>(T v) { return v; };
To do the same in Python, we will need to create a function again, just as:
from typing import TypeVar
TTypeVar(T)
def c2_tmp(v: T):
return v
c2c2_tmp once called, returns anything passed to the parameter
So what do I want? As I said, extending possibilities of lambda expressions in Python, so that it becomes more satisfying to create callback variable (referring to JavaScript). Parameters
list, just like in normal functions, but also in lambda expressions in C++, should be encased with circled brackets. Doing this allow to extend the code with leading
lambda
keyword. Code will become elastic. Circled parentheses would also allow type hinting for parameters, without being scared of colon after which begins return code part of lambda expression.
Below new version of lambda expressions syntax:
syntax for Python versions least than 3.12
from typing import TypeVar
T1TypeVar(T1)
T2TypeVar(T2)
T3TypeVar(T3)
...
lambda ([p1[: T1][, p2[: T2][, p3[: T3][, [: ]]]]]): <return-code-scrap>
syntax for Python versions equal or greater than 3.12
lambda [T1, T2, T3, ]([p1[: T1][, p2[: T2][, p3[: T3][, [: ]]]]]): <return-code-scrap>
This syntax doesn't have to overwrite the current syntax, as we saw from the beginning of this article. Moreover, I think syntax shouldn't be deputized with the one I just coined, because
seeing this code in Python 2 (for example) would lead to syntax error, and libraries written with old lambda expression syntax would need to migrate to Python 3 utterly and base on this
syntax. So keeping the old lambda expression syntax is completely mandatory. If instead of
<return-code-scrap>
we put regular lambda body, its code will become less
understanding and will decrease readability, it also will become less logical, especially when passing lambda expression to a parameter, and again would push programmers to define their
own functions with
def
keyword. I know that lambda expressions can be replaced with instances of class
functools.partial
, but since
lambda
expressions
remain in Python 3, we could care for its development.
Article written by Aveyzan on 26th August 2024, 0:21 AM according to time in Greenwich