[Python-Dev] a flattening operator?

Josiah Carlson jcarlson at uci.edu
Wed Apr 19 00:16:08 CEST 2006


"tomer filiba" <tomerfiliba at gmail.com> wrote:
> isn't the latter more elegant?

According to my experience with Python, as well as my interpretations of
the zens, no. -1

> and the zen supports my point:
> (*) Beautiful is better than ugly --> f(*(args + (7,))) is ugly

But explicit is better than implicit, and in this case, it would likely
be better to just use a keyword argument lastarg=7.  If the function
called merely accepts *args and **kwargs, and you are passing args
unchanged somewhere else, it may be more explicit to redefine f to be...

    def f(args, kwargs):
        ...

Then use it like...

    f(args + (7,))

Not quite as ugly as the worst-case option were you were describing
moments ago.

> (*) Flat is better than nested --> less parenthesis

I believe that zen was in regards to overly-nested object hierarchies
and namespaces.

> (*) Sparse is better than dense --> less noise

I believe that zen was in regards to using spaces between operations, as
well as using line breaks between sections of code so as to express a
visual 'separating' of ideas.


> (*) Readability counts --> again, less noise

Use keyword arguments for single arguments, ...

> (*) Special cases aren't special enough to break the rules --> then why
> are function calls so special to add a unique syntactic sugar for them?

By necessity, function defintions require a unique syntax to make
calls different from anything else you can do with an object. 
Specifically, we have f() because () are unambiguous for calling
functions due to various reasons.


> the flattening operator would work on any sequence (having __iter__ or
> __next__), not just tuples and lists. one very useful feature i can
> think of is "expanding" generators, i.e.:
>
> print xrange(10) # ==> xrange(10)
> print *xrange(10) # ==> (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

One major problem with this is that except for function calls, * is the
multiplication operator, which operates on two arguments.  *foo is an
operation on a single argument, and without parenthesis, would be
ambiguously parsed.  Further, I would prefer not to see this
monstrosity:

    print x*(*y)

Which would print out x copies of the sequence y.


With all of that said, there is a recent discussion in the python 3k
mailing list which has been discussing "Cleaning up argument list
parsing".  The vast majority of your ideas can be seen as a
variant of the discussion going on there.  I haven't been paying much
attention to it mostly because I think that the current convention is
sufficient, and allowing people to do things like...

    foo(*arglist1, b, c, d=d_arg, *arglist2, **kwargs)

...is just begging for a mess.

 - Josiah



More information about the Python-Dev mailing list