PEP 312 - Making lambdas implicit worries me, surely it's just the name 'lambda' that is bad...

Stephen Horne intentionally at blank.co.uk
Wed Mar 12 21:38:15 EST 2003


On 06 Mar 2003 20:21:12 +0000, Alexander Schmolck <a.schmolck at gmx.net>
wrote:

>Erik Max Francis <max at alcyone.com> writes:
>
>> But that has no bearing on whether Python should also have a compact form
>> _for the sole purpose of being compact_.
>
>No one suggests such a thing!  I think there are maybe 4 different levels at
>which the mere conciseness of a construct FOO (with a hypothetical, more
>verbose alternative, FOO_VERBOSE) can affect a language:
>
>1. FOO is used in the same places as FOO_VERBOSE would, but the code becomes
>   more (or less) readable (e.g. ``Bignum(1).add(3)`` 'vs' ``1l + 3``)

'+' is a common operation that everyone understands. 'lambda' is not.
Completely removing the best clue to what's going on (ie a keyword to
look up in the documentation) does not aid readability.

>2. FOO is used in places where FOO_VERBOSE wouldn't be used, because it is too
>   cumbersome (e.g. I'd wager that people more readily use dicts in python
>   than HashTables in java).

Having had to explain lists and dictionaries to a couple of
programmers who'd only used statically typed languages before, I can
say that some irritation would have been avoided if the respective
syntaxes were...

  list {1, 2, 3, 4, ...}

  dict {1 : 2, 3 : 4, ...}

It's not so much the "oh that - that's a list" that causes the
problem. It's the explaining that list support is built in, doesn't
require a library class, doesn't specify the implementation, etc etc.
At the end of that, I've lost the thread of whatever I was doing
before. All avoidable if the people involved could look up the keyword
and find out for themselves.

Well - probably 30 mins out of my life in total. Hardly a big issue.
But let's get back to the point...

I don't know how HashTables work in Java, but I do know that there is
a happy medium for conciseness - like lossy compression, smaller
representations are only better to a point. And the decision on where
to stop is inherently a subjective one.

For me, when a construct has no explicit indicator of what it's doing
it usually means the compression has gone a step or two too far.
Explicit does not always mean a keyword ('+' for instance is explicit
enough), but quite often that is what is required.

Every language has a few 'overcompressed' syntaxes. This isn't
necessarily a bad thing. These syntaxes tend to define the style of a
particular language, and they reflect the languages priorities. If
there are too many highly compressed notations, though - and
particular if some are rarely used except by code-obfuscators - it
leads to unreadable code. In particular, if each symbol is put to too
many different uses, the results can rapidly get very confusing.

The C comma operator is probably the definitive example of conciseness
gone mad. The comma is most often used as a separator punctuation, so
the comma as an evaluate-and-discard operator is far from intuitive
when its first seen. It works extremely well when used for in-step
loops, but its wider generality leads to no end of confusion and
errors. For example, what does the following code output...

  int x = 0;

  switch (x)
  {
    case 0, 1 :  cout << "First case passed"   << endl;  break;
    default   :  cout << "Default case passed" << endl;  break;
  }

The correct answer is "Default case passed" - the first case evaluates
the '0' but discards it, and only actually tests for the '1'. But can
you honestly claim that result is intuitive?

The fact is that the C comma should (at least in my opinion) never
have been used as an evaluate-and-discard operator. Either a more
explicit operator should have been used, or else the comma should have
been recognised as a special separator in 'for' and 'while' clauses
specifically designed for setting up in-step loops without the more
general evaluate-and-discard meaning. If it did that, even the
intended purpose would have been enhanced in C++ - you could write...

  for (int i = 0, float j = 1.0; i++, j *= 1.1; i < 100)
  {
    ...
  }

As things stand, this is illegal - you can't combine the 'int' and
'double' declarations in one statement using the evaluate-and-discard
operator, though if it was just a separator it could have been seen as
separating two independent statements.

By being too general, too concise, and by 'overloading' the comma
symbol, the C evaluate-and-discard operator contributes significantly
to the readability, maintainability and reliability problems in that
language - and gets in the way of even the task it is designed to
support.

Python has a fair share of highly compressed syntaxes, but it also has
a style which favours readability. Adding a new highly compressed
syntax should be considered very carefully, and should really only be
done if the syntax is likely to be put to everyday use by average
programmers - ie if most people who would have a reason to read Python
source code would recognise it immediately.

As much as I like lambdas, they simply aren't used that much by most
programmers - and I seriously doubt that dropping the 'lambda' keyword
would make that much difference.

And besides, the syntax should certainly be distinguished from plain
expressions by more than a colon - a symbol which already has several
uses in Python.

>3. FOO's conciseness affects the design of interfaces of other functions (so
>   that they become in some way better, or more general -- e.g. `ifAbsent` vs
>   `.get`).

The strength of the 'ifAbsent' notation, however, isn't just about
having a single concise notation - it's tightly coupled to the overall
design of SmallTalk, and I'm not convinced you can draw useful
conclusions about conciseness in general from it.

>4. FOO's conciseness renders certain hypothetical language extensions
>   unnecessary (e.g. control construct syntax, and to some extent even macros,
>   in smalltalk).

I'm not convinced an abbreviated lambda could achieve this any more
than the existing lambda - e.g. you could only render control constuct
syntax less readable, and macros don't exist anyway in Python.

>Now 3 and 4 are of course quite rare, (but all other things being equal),
>rather desirable. I think smalltalk's blocks satisfy all 4 (and smalltalk,
>although different, is not completely unlike python).

Python has it's own style, and lambdas - while extremely useful for
certain tasks - are not a fundamental part of that style. Smalltalks
codeblocks seem much more fundamental to that languages style. This is
a significant difference.

>Of course adding a (amongst other things, highly syntactically constrained and
>possibly rather restricted) lightweight anonymous function equivalent to
>python at this stage might not be worth while the trouble (and increase in
>complexity). Also, as you and others remarked, certain syntactic possiblities
>might be errorprone or unreadable.

Changing the subject a second, this can be linked to a the idea of
using XML as a source language.

The editor might display a marker in place of the lambda. Select the
marker, and a drop-down editing pane (or separate window or whatever)
could appear, containing the body of the lambda complete with
indentation-based block structures. As the layout of the lambda body
is independent of the layout of the code that it is embedded in,
readability is improved and certain syntax related issues are avoided.

>Nonetheless, I think the ability to easily pass chunks of code around (and no
>-- lambda does not qualify; or I'd like to see how you rewrite a smalltalk
>program by replacing blocks with something like lambda

A naive translation of Python code to Smalltalk would also be pretty
awkward.

>) that close over the
>current environment, even if added to python now, is unlikely to affect the
>only point 1 (as you seem to imply).

Everything you've said has some truth to it, but IMO the specifics of
PEP312 raise serious issues that run counter to each of those points.
The comparison with the C comma operator should give anyone good
reason to fear the PEP312 syntax.





More information about the Python-list mailing list