Is default argument value the capture syntax in lambda

I searched through the docs to find capture syntax about lambda and did not find nothing. The other languages like C++, Swift, Rust use special syntax for capture.

I just test the following snippet. And find out if the default argument value is a variable for lambda, it is a capture. I think this is pretty simple and smart. Please correct me if I was wrong.

Thanks

def outer():
    o = 3
    inner = lambda i, o=o: i * o
    return inner

print(outer()(5))

Your code creates a variable o local to the lambda, distinct from the o local to outer. The default value is evaluated in outer scope, though.
A clearer version of your code (using different names for distinct variables):

def outer():
    o = 3
    inner = lambda i, p=o: i * p
    return inner

print(outer()(5))

Note that instead of naming a lambda by assigning it to a variable, in Python it’s almost always better to use def to create a named function:

def outer():
    o = 3
    def inner(i, p=o):
        return i * p
    return inner

print(outer()(5))

Anyway. AFAIK, “capture” in the languages you mention is closer to using a variable from the outer scope directly:

def outer():
    o = 3
    return lambda i: i * o

print(outer()(5))

(Internally, Python creates a cell for the variable to allow it to “outlive” the outer call.)

1 Like

Thanks Petr

If the lambda is a long def, others need to read the whole function body to find out what outer variables it uses.

Before lambda was introduced in C++, the language uses bind() function to pass more values besides those specified in parameter parentheses to function. The lambda capture is better than bind in C++ in my opinion. Lambda is also better than function because it can capture values, I think.

If the lambda is a long def, others need to read the whole function
body to find out what outer variables it uses.

True. They have to do that for a lambda too, but at least it is
(usually) only one line.

Before lambda was introduced in C++, the language uses bind() function
to pass more values besides those specified in parameter parentheses to
function. The lambda capture is better than bind in C++ in my opinion.
Lambda is also better than function because it can capture values, I
think.

A lambda just a short way to define a single expression function, with
no inherent name. This:

inner = lambda i, p=o: i * p

is equivalent to this:

def inner(i, p=o):
    return i * p

The closure and so forth behave the same.

Cheers,
Cameron Simpson cs@cskk.id.au

1 Like

Not exactly equivalent: with def, the function’s __name__ is set, so the name will e.g. appear in tracebacks.
But otherwise the functionality is the same.