a = b = 1 just syntactic sugar?

Ed Avis ed at membled.com
Mon Jun 9 22:07:10 CEST 2003

Steven Taschuk <staschuk at telusplanet.net> writes:

>>    swap = (lambda L,i,j: L[i], L[j] = L[j], L[i])

>The problem with this plan is the amount of lookahead required for
>the parser to decide among possible parse trees.

You're right.  Since LL(1)-ness is a good property to have, my
suggestion of putting simple_stmt directly inside lambda will not

I don't plan to get into a tar-pit of proposing ever more complex and
baroque grammar changes, each one in turn being shot down by someone
finding an unparseable or ambiguous or counterintuitive code sample.
But I would like to have a second attempt.

>I actually think parentheses directly around the statement is a
>more promising approach.

I was just about to post that when I thought I should read the rest of
your reply first ;-).

Hmm, so maybe there would have to be two cases, one containing an
expression as at present, and a second case

lambda_form ::= 
             "lambda" [parameter_list]: "(" simple_stmt ")"

This would, I believe, fix the with 'the rest of the language' such as
the is-it-a-tuple-or-not example you cite.  But there is the problem
that the two different productions for lambda overlap, after all, an
expression can be wrapped in ( ) and so '(e)' might be the expression
(e) or the expression_stmt e.  With the idea of inserting an implicit
'return' before expression_stmts inside lambda functions, the
semantics of the two would be the same so it might not matter.

Or maybe the bracketing could be used to avoid the 'implicit return'
peculiarity altogether.  The meaning of lambda x: expr could be
defined to be the same as a named function containing 'return expr'.
While the meaning of lambda x: (simple_stmt) would be defined to be
like a named function containing simple_stmt.  If we arrange that the
first grammar rule always matches in preference to the second, then
existing constructs like 'lambda x: (3)' would not change in meaning.
I hope this makes some sense.

(I'm tempted to say that if starting from scratch I would allow only
one-line statements inside lambdas, and require explicit 'return'.  Or
else I would not require 'return' inside named functions but return
the value of the last expression_stmt evaluated.  Either way I'd want
to make lambda function bodies and named function bodies act the same
way as far as possible.  Anyway, starting from scratch is not an
option here.)

The trouble with bracketing is that the code you write is no longer so
obvious.  -- What, I have to put () round the body of my lambda
function?  I don't do that for ordinary function bodies.  I have to
put () around 'print' but not around 'sys.exit()' - why?  And so on.
So if putting brackets round the body of the anonymous function is the
only way to make it work, I might say that it is too surprising and
inconsistent with ordinary function definitions, exactly the same
complaints I had against the status quo.

Yes, life would be easier if all lambda functions currently had
'return expr' rather than just 'expr' as their body.  But if only
expressions are allowed, this is just syntactic salt and in any case
not backwards compatible.

>In the grammar, precedence is implicit in the nesting of productions,
>e.g., 'not' has a higher precedence than 'and' just because not_test
>occurs in expansions of and_test and not (directly) vice versa.

Right, that clarifies things.

Ed Avis <ed at membled.com>

More information about the Python-list mailing list