a = b = 1 just syntactic sugar?

Ed Avis ed at membled.com
Sat Jun 7 23:19:35 CEST 2003


Steven Taschuk <staschuk at telusplanet.net> writes:

>We already have closures, don't we?
>
>    >>> def f(x):
>    ...     def g(y):
>    ...         return x + y
>    ...     return g
>    ... 
>    >>> q = f(3)
>    >>> q(4)
>    7

Which Python version does this require?  (The machine to hand has only
1.5.2, although normally I use 2.2 or so.)

>Or do you want to be able to rebind names in outer scopes?

I mean things like

  def make_adder():
    x = 0
    def incr():
      x += 1
      return x
    return incr

  f = make_adder()
  g = make_adder()
  print f(), f(), g(), g() # 1 2 1 2

I do apologize for not testing this on the latest Python release, but
I will upgrade this machine from 1.5.2 soon so I can test my programs
before posting them to the newsgroup.

Anyway, it's my understanding from past discussions that there is only
one make_adder.x variable thoughout the whole program.  But I could be
horribly, horribly confused.

>Is anonymity really the point?  If so, it seems quite a minor one to
>me -- it's just not that big a deal to have to name a small function.

No, you're right, anonymity isn't really it; what I meant was the
style of passing around code references and particularly those that
can carry some scope with them.

>(Where are the complaints about having to name small classes?)

OTOH, think how awkward it would be if you had to name
small expressions:

    expr0 = f()
    expr1 = 55
    result = expr0 + expr1

instead of

    result = f() + 55

OK - defining functions, even in a heavily 'functional' style of
programming, happens much less often than creating expressions so the
tradeoffs are different.  Still, I find that lambda often makes code
more readable by letting you group related things together.

>Moreover, if the act of defining the function does not bind a name to
>it, you need to get a reference to it some other way.  The obvious
>thing to do is to have the function-defining text be an expression
>which evaluates to the function object (so you stick it in a list or
>whatever).  That in turn, as Python syntax is now, entails that it
>can only contain expressions.

Indeed.  I know that the current restrictions on lambda are
syntactic.  However, if the syntax were changed so that lambda could
contain any one-line construct, that might make it more useful and
less bizarre-seeming.

>But Lisp doesn't use indentation to delimit blocks, nor does it
>distinguish between statements and expressions, so the comparison is
>uninformative.

Just to be clear I wasn't advocating a big multiline lambda with a
whole indented block underneath it, which I admit would be too
complicated to work nicely into current expression syntax.

>Do you have a language in mind which is a better analogue to Python
>and could teach us more about these issues?

I'm afraid I can't think of any because Python is the only language I
know that treats assignment as binding a name to a (possibly
immutable) object rather than mutating the state of an existing
object.

So in C, a variable 'int x;' denotes an area of memory where an
integer sits, and you can do things to the integer like change its
value, increment it, and of course get the value.  Perl is also like
this except that the value could change from being an integer to a
string or some other type.  (Actually, you can rebind names in Perl
but that's not the normal programming style.)  In Python you can
rebind the name x to a different integer (= and +=) but there is no
way to modify the object pointed at except by calling methods on it -
and integers do not have a 'set' method.

Maybe Tcl is closer to Python since its 'set' appears to define names
rather than changing an existing value.  Tcl has a wacky 'upvar'
mechanism to access names defined in an enclosing scope.  But I think
this is dynamic scope - the caller's scope, not the scope defining the
called function - so I don't think it can be used to implement
closures.  But it would suprise me if Tcl didn't have _some_ way to do
full closures, you can warp the language to do almost anything.

>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.

>>What is strange is not so much the grammar rule for lambda itself, as
>>the dividing line between what is a statement and what an expression.
>
>Fwiw, I agree somewhat with this.  (It just doesn't bother me at all
>in practice.)

It didn't bother me at all (well, when first starting to learn the
language I wondered why 'print' had a different syntax to other calls,
and whether I could define my own procedures that could be called in
the same way) until I bumped into the lambda restrictions.  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.

-- 
Ed Avis <ed at membled.com>




More information about the Python-list mailing list