I've been reading the recent cross-posted flamewar, and read Guido's

article where he posits that embedding multi-line lambdas in

expressions is an unsolvable puzzle.

So for the last 15 minutes I applied myself to this problem and come up

with this off-the-wall proposal for you people. Perhaps this idea has

been proposed before, I don't know.

The solutions I have seen all assume that the lambda must be completely

inlined within the expression: the expression is interrupted by the

lambda, which is then completely specified (arguments and body) and the

expression somehow continues (and this is where syntactic problems

occur, giving rise to un-Python-like repugnancies).

But suppose that the expression and the multi-line lambda body are

reordered? That is to say, the expression is written normally, and the

mlambda expressions in it serve as /markers/ indicating that body

material follows. This results in the most Python-like solution.

Suppose lambda() occurs without a colon

a = lambda(x, y), lambda(s, t), lambda(u, w): u + w

statement1

statement2

lambda:

statement3

statement4

The first two lambdas do not have a colon after them. This means that

they have multi-line bodies which follow this statement, and there must

be as many bodies as there are lambdas. The third lambda is a regular

one-expression lambda, entirely written right there.

The bodies are made up of the statements which follow. If there is only

one body, it's simply the indented material. If there are two or more

lambdas in the expression, additional bodies are required, introduced

by lambda: statements, which are at the same indentation level as the

expression which contains the lambda markers.

Of course, the bodies have their respective lambda parameters in scope.

So statement1 and statement2 have access to x and y, and statement3 and

statement4 have access to s and t.

Problem solved, with no Python repugnancies.

The way you can embed indented material in an expression is by not

physically embedding it.

If you want to be completely anally retentive, you can require that the

expression which has lambda bodies after it has to be terminated by a

colon:

a = lambda(x, y), lambda(s, t), lambda(u, w): u + w:

statement1

statement2

lambda:

statement3

statement4

If we take out the last two lambdas, this reduces to:

a = lambda(x, y):

statement1

statement2

Here, the colon terminates the lambda-containing statement. It is not

the colon which introduces the body of a one-expression lambda. E.g.:

a = lambda(x, y): x + y

a = lambda(x, y):

return x + y

The two are disambiguated by what follows. You get the picture.

More examples: lambda defined in a function call argument

a = foo(lambda (x, y)):

return x + y

Confusing? Not if you read it properly. "A lambda function is

constructed with arguments x, y and passed to foo, and the result is

assigned to a. Oh, and by the way, the body of the

lambda is: return x + y."