[Python-3000] More wishful thinking
Talin
talin at acm.org
Sun Apr 16 23:43:29 CEST 2006
Guido van Rossum <guido <at> python.org> writes:
> On 4/15/06, Talin <talin <at> acm.org> wrote:
> > Another grab-bag of language ideas / wishes. Some of these are
> > items that have been raised before on other lists - I want to get them
> > written down so that they can be rejected quickly :)
> >
> > 1) I don't know if this is already on the table, but I sure would like
> > to be able to have more options as far as mixing positional and
> > keyword arguments.
>
> I agree. Please produce a patch that implements what you want.
All right, in that case, I'd like to post a general implementation
strategy for criticism before I end up going too far down the
wrong path.
As I see it, the problem breaks down into 3 parts:
-- parsing
-- representing the argument list
-- executing a call
The parsing part is fairly straightforward. The new syntax would
allow keyword arguments to appear anywhere in the argument
list, intermixed with positional arguments, and after the varargs
argument.
(It would be possible to have non-keyword arguments after the
varargs argument as well, but that's harder to implement, and I
don't really see the value in it.)
The kwargs argument would remain unchanged - there's no real
reason to allow it to be moved around in the argument list.
So the argument list syntax would be (in psuedo-grammar):
(keyword | positional )* [*varargs] keyword* [**kwargs]
(This is of course omitting all of the complexities of generator
expressions for the moment.)
Representing the argument list. The current _arguments struct
looks like this:
struct _arguments {
asdl_seq *args;
identifier vararg;
identifier kwarg;
asdl_seq *defaults;
};
The approach that I would take would be to remove the 'vararg',
and instead put the vararg argument into args. A special sentinel
value in the *defaults array (say, (void*)-1) would be used to
indicate that this argument was a varargs argument.
Thus, for each argument (other than kwargs), you would have
both an argument name and a default, where a NULL value indicated
a positional argument, a non-NULL value indicated a keyword argument,
and a sentinel value indicated a varargs argument.
Executing a call: This is the tricky part. Specifically, we want to insure
that the mapping of values to formal parameters remains the same
for existing code.
Start with a list of unfilled slots, one per formal parameter, including
the varargs parameter.
for each argument:
if it is a keyword argument:
find a the named slot;
if found:
if it is already filled, raise TypeError
otherwise fill the slot with the argument
else if there's a kwargs,
add it there
else
raise TypeError
if it is a positional argument
if the next slot is a varargs slot
append to the vararg list
else
fill the slot with the argument
increment the slot index
There might be a more optimal implementation of this, in particular
it should be possible to create the varargs tuple in a single allocation
rather than having to build it up incrementally.
Anyway, if this seems unreasonable, or if you find any bugs let me
know. I have a lot on my plate at the moment, so I don't know when
I will get around to making the patch, but hopefully soon.
-- Talin
More information about the Python-3000
mailing list