a = b = 1 just syntactic sugar?

Steven Taschuk staschuk at telusplanet.net
Sat Jun 7 20:36:07 EDT 2003


Quoth Ed Avis:
> Steven Taschuk <staschuk at telusplanet.net> writes:
> 
> >We already have closures, don't we?
  [...]
> Which Python version does this require?  (The machine to hand has only
> 1.5.2, although normally I use 2.2 or so.)

I'm not sure, actually.  That example, and the one below, were
copied from 2.2.2 interactive sessions.

> >Or do you want to be able to rebind names in outer scopes?
> 
> I mean things like
  [...example...]

As written your example does require the ability to rebind
variables in outer scopes, which is not possible.  But you could
use a mutable type instead, to achieve the same effect:

    >>> def make_adder():
    ...     x = [0]
    ...     def incr():
    ...         x[0] += 1
    ...         return x[0]
    ...     return incr
    ... 
    >>> f = make_adder()
    >>> g = make_adder()
    >>> f(), f(), g(), g()
    (1, 2, 1, 2)

This output, of course, implies the existence of more than one
binding for x (which, no doubt, is why you chose it for your
example).

Some prefer using objects for this kind of thing.  They're more
introspectable, for one thing.

  [...]
> >(Where are the complaints about having to name small classes?)
> 
> OTOH, think how awkward it would be if you had to name
> small expressions:

Nice counterpoint!

  [...]
> >The main problem is syntactic; thus Terry's suggestion that you
> >produce a grammar rule for your proposal.  (That means BNF, not an
> >informal description such as "anything that can fit on a line".
> 
> How about
> 
>     lamda_form ::=
>                 "lambda" [parameter_list]: simple_stmt
> 
> As you know, simple_stmt is a statement that fits on one line.

Well, I'm not sure about that characterization of simple_stmt
(e.g., compound statements can fit on one line too), but let it be.

First note that, at present, the tuple comma is of lower
precedence than lambda:
    lambda x: x, 3
is a tuple, not a function returning a tuple.  This certainly has
to be preserved, for backwards compatibility.

Now consider:

    swap = lambda L,i,j: L[i], L[j] = L[j], L[i]

How is the parser to know, once it has read as far as
    lambda L,i,j: L[i],
whether this is the end of the lambda_form?  It would be, with the
present syntax.

> [...] It looks
> as though it is lambda that is particularly peculiar, even though in
> fact it is just inheriting the statement/expression divide from other
> parts of the language.  Elsewhere you don't have to care about the
> difference, because any expression can be used as an expression_stmt.

But not the reverse -- statements cannot be used in expressions.
All of the following are illegal, for example:

    while print x:
        # ...

    if del x[0]:
        # ...

    y = 3 + 4*(assert x > 1)

You don't usually need to think about the statement/expression
distinction, I agree, but *not* because they're interchangeable in
most contexts -- that's simply false.  It's that the division
between them is almost perfectly done, so you never even think to
put a statement in an expression (unless you have a C background
and weird ideas about assignment).

If there is a problem here, imho it is that lambda makes people
want to put statements in expressions, thereby bringing to centre
stage a distinction which is usually unobtrusive.  Anonymity is a
red herring; so are closures; the important point is that lambdas
are expressions and defs are statements.

-- 
Steven Taschuk             "The world will end if you get this wrong."
staschuk at telusplanet.net     -- "Typesetting Mathematics -- User's Guide",
                                 Brian Kernighan and Lorrinda Cherry





More information about the Python-list mailing list