Pythonification of the asterisk-based collection packing/unpacking syntax

Joshua Landau joshua.landau.ws at gmail.com
Sun Dec 18 11:04:58 EST 2011


I'm just going to throw myself in the conversation obtusely.I felt we
needed some real code. These are literally the first two samples I had on
hand.

!!! OUT OF CONTEXT REAL CODE ALERT !!!

###################################

formatter = formatter.format(**color).replace("(","{").replace(")","}")
print("\n\n".join(formatter.format(**d) for d in db))

# vs #

formatter = formatter.format(::(),
::color).replace("(","{").replace(")","}")
print("\n\n".join(formatter.format(::(), ::d) for d in db))

# What do we do for "format(**kwargs)"?
# With the current guess of mine, I'm thinking "what does ::() do?" and
"why are there two double-colons?".
# Aside from that it looks not much different/worse.

# and #

def checkLoad(self, *args, **kwargs):
 if getattr(self, x) == None: getattr(self, loadx)()
if fakeself:
 return function(getattr(self, x), *args, **kwargs)
 else:
return function(self, *args, **kwargs)
return checkLoad

# vs #

def checkLoad(self, tuple::args, dict::kwargs):
if getattr(self, x) == None: getattr(self, loadx)()
 if fakeself:
return function(getattr(self, x), ::args, ::kwargs)
 else:
 return function(self, ::args, ::kwargs)
return checkLoad

# It looks much the same, but how does it benefit me?
# "*args" is very distinct from "**kwargs" in my opinion. "tuple"/"dict"
doesn't have that.
# That said, the second works better with my syntax highlighter (although
pylint then swears at me).

#############################################################

Before I actually put the syntax in context I hated this. Now I just really
dislike it.

There is one big thing bugging me: How do I do: "foo(**kwargs)"? My
solution was to use "foo(::(), ::kwargs)", but it's obviously not a great
alternative.

There is another, smaller one. Wrapper functions often just want to pass
values straight through them. They don't care that it's a tuple. They don't
care that it's a dict. They're just going to throw it across. Without "def
foo(::args)" syntax, that's just a waste of a lookup. With "def
foo(::args)" syntax you lose the discrimination of args and kwargs,
resulting in the same problem above. Finally, it's uglier when without.

I do have one suggestion:
foo(*args, **kwargs): pass

foo(tuple(*) args, dict(**) kwargs): pass

foo(dict(**) kwargs): pass

foo(*, bar="spam"): pass

# this is illegal because unbound "catchalls" don't catch anything, as they
do today
foo(tuple(*), bar="spam"): pass

I'll leave you to guess how it works. If you can't it's obviously not
obvious enough.

Advantages:
"*" means a catchall, as it should.
"*" is distinct from "**".
With syntax highlighting, it's pretty obvious what is going on.
It's backwards compatible (the main reason it's not "tuple(*):args").

*My main problem is: use case? I've had none at all.*
If only 1% of users want it, it's not right to make the 99% change. Saving *one
line and 50 microseconds* per hundred uses of (*/**) is not a valid
argument.And don't make us all change all our code just to satisfy that.
The only argument you can make is readability, but (*/**) is more explicit
than a lookup, just because it's not dependant on position (args/kwargs
argument) and it's always a real tuple and dict.

def tuple(): 1/0
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20111218/7ec037bb/attachment-0001.html>


More information about the Python-list mailing list