Code block literals

Alex Martelli aleax at aleax.it
Thu Oct 9 11:58:10 EDT 2003


Dave Benjamin wrote:

> Alex Martelli wrote:
>> The only annoyance here is that there is no good 'literal' form for
>> a code block (Python's lambda is too puny to count as such), so you
>> do have to *name* the 'thefunc' argument (with a 'def' statement --
>> Python firmly separates statements from expressions).
> 
> Here's my non-PEP for such a feature:
> 
> return { |x, y|
>      print x
>      print y
> }
> 
> Which would be the equivalent of:
> 
> def anonymous_function(x, y):
>      print x
>      print y
> return anonymous_function

Oh, and what should:

return {
    }

MEAN?  An empty dictionary, like today, or the equivalent of

return lambda: None

i.e. an empty argument-less function?

This is just reason #1 why this syntax is not satisfactory (I
guess it could be forced by mandating || to mean "takes no
args" -- deviating from Ruby in that sub-issue, though).  The
second point is the use of punctuation in a way that no other
Python syntactic context allows -- it really feels alien.

Further, something that is more often than not desired by
people who desire code blocks is that they *don't* start a
new scope.  Ruby fudges it with an ad-hoc rule -- use of
variables already existing outside is "as if" you were in
the same scope, use of new variables isn't (creates a new
variable on each re-entry into the block via yield, right?).
Clearly we can't use that fudge in Python.  So, this is a
semantic problem to solve for whatever syntax.  Can we find
any approach that solves ALL use cases?  I don't know, but my
personal inclination would be to try saying that such a block
NEVER define a new lexical scope, just like list comprehensions
don't -- i.e. in this sense such blocks would NOT be at all
equivalent to the functions produced by a def statement (lots
of implementation work, of course) -- all variables that might
look like locals of such a block would instead be considered
locals of the "enclosing" scope (which isn't enclosing, in a
sense, as there's no other new scope to enclose...;-).

SOME explicit termination is no doubt necessary if we want to
allow returning e.g. a tuple of two or more such functions --
which is why we can't try taking another (and less repellent
to Pythonic syntax) leaf from Ruby's book (using do instead
of { -- requires making do a keyword -- and leaving out the
end that Ruby always requires, of course):

return do(x, y):
    print x
    print y

there would be no way to write something more after this
block but within the same expression if the only termination
was dedenting; perhaps:

return ( do(x, y):
    print x
    print y
), ( do(x, y):
    print y
    print x
)

i.e. with parentheses around the do-expression (if you need
to put anything more after it) might help here.

> Then, merge map, filter, and reduce into the list type, so we can play

Why?  So you can't e.g. reduce an arbitrary iterator (e.g., genererator),
tuple, array.array, ..., any more?  We'd be better off without them, IMHO.
I see no advantage, over e.g. itertools, in associating these syntactically
to sequences (any kind or all kinds) or even iterators.


Alex





More information about the Python-list mailing list