a = b = 1 just syntactic sugar?

Ed Avis ed at membled.com
Thu Jun 5 17:54:01 EDT 2003


Michael Chermside <mcherm at mcherm.com> writes:

>>It seems a bit perverse that setattr is allowed in lambda expressions
>>but assignment is not; that you can call setdefault to update a
>>dictionary, but not simply set the dictionary's elements; that you can
>>do sys.stdout.write but not print; that you can call a function which
>>asserts but not call assert.

>True, but as usual, there's a reason for it. Lambda was intended[1]
>for one purpose and one purpose only... to permit simple anonymous
>functions to be used in places where the succinctness makes it more
>readable than using def to make a named function. Such places are
>rare except when using functional style programming, where they are
>quite common. But in functional style programming you (nearly always)
>do NOT want expressions to have side effects.

I would accept this argument, except for the four examples I mentioned
above.  They are all things which have side effects, and which are not
excluded from appearing in lambda expressions.  The distinction
between what can appear in a lambda and what can't seems arbitrary, it
is certainly not based on side effects.

>So lambda is defined to allow only expressions, and is *intended* for
>simple, side-effect-free functions. While there's nothing
>*preventing* you from calling a function with side effects, the
>prohibition on using statements tends to discourage it.

The trouble is that you pay a high price for this 'discouragement'.
The amount of trouble it causes doesn't seem worthwhile given that it
fails in is key aim to avoid side effects.

If the language made a meaningful distinction between statements,
which can have side effects, and expressions, which cannot, then I
would understand that.  But the current division seems so arbitrary.
I gave a list of examples at the top of this article so I won't repeat
it here.

>Good style is encouraged, but you can violate the rules if you really
>want to (and know what you're doing).

The trouble is that IMHO the current lambda rules do not encourage
good style.

Suppose, for example, you want to write a short one-line function that
operates on positive numbers.  Good style suggests you document this
precondition in the code with an assert, which will also serve to
check it at run time.  Good style might also suggest that the function
is best written inline, rather than as a named definition elsewhere.
That is an aesthetic judgement for the individual programmer, of
course, but suppose it seems like the best style here.

Now you cannot write something like

    lambda x: assert(x > 0), sqrt(x) + 55

So you can't put assertions in your anonymous functions?  This doesn't
encourage good style.  The other cases like having to use setattr
tricks instead of = don't seem to encourage clear coding either.

>I find lambda to be quite nice, but ONLY when used for very small
>side-effect-free functions.

If lambda really were restricted to that then the restrictions would
make some kind of semantic sense.  At the moment they seem to be more
like a syntactic and historical accident - I can't see any sensible
rule that would allow sys.stdout.write but prohibit print.

>And if I had a complaint, it wouldn't be about the (rarely needed and
>easily worked-around) prohibition on assignment statements, but about
>the (frequently needed and impossible to work around) lack of a
>conditional expression.

Yes, it would be nice if if-else could be used as an expression, as in
Haskell or Lisp or other functional languages.  But can't you work
around this with

    condition and if_branch or else_branch

This is probably less clear than if-then-else, which is another
example of how the current lambda rules tend to obfuscate code rather
than clarify it.  But the workaround works well enough once you get
used to it.

-- 
Ed Avis <ed at membled.com>




More information about the Python-list mailing list