[Python-Dev] Partial function application 'from the right'

Ben North ben at redfrontdoor.org
Fri Jan 30 19:35:15 CET 2009


Hi,

> [ Potential new  "functools.partial_right", e.g.,
>
>    split_comma = partial_right(str.split, '.')
> ]

Thanks for the feedback.  Apologies if (as was suggested) this should
have gone to python-ideas; I thought as a fairly small extension to
existing functionality it would be OK here.  I'll try to summarise the
responses.

There was some very luke-warm support.

Terry Reedy suggested it would be worth posting a patch to the tracker,
for the record, even if it turns out to be rejected.

Nick Coghlan made more clear than I did the main reason a
'partial_right' would be useful:

> [...] some functions and methods written in C (such as string methods)
> *don't* [support keyword args], so partial's keyword support doesn't
> help.
>
> A functools.rpartial would go some way towards addressing that.

On the other hand, Collin Winter asked for more evidence that real
benefit (beyond mere 'completeness' of the functools module) would
result.  I don't really have to hand anything more than the three cases
mentioned in my original email (str.split, math.log, itertools.islice),
but since the change is so small, I thought the feature worth raising.

Leif Walsh pointed out that you could achieve the same effect by
defining your own function.  This is true, but functools.partial exists
because it's sometimes useful to create such functions either more
concisely, or anonymously.  A 'partial_right' would allow more such
functions to be so created.

Peter Harris was negative on the idea, pointing out that after

   g = partial_right(f, 7)

you don't know which argument of 'f' the '7' is going to end up as,
because it depends on how many are supplied in the eventual call to 'g'.
This is true, and would require some care in partial_right's use.  Peter
also wondered

> There's probably a reason why Haskell doesn't do this...

I have only written about five lines of Haskell in my life, so take this
with a hefty pinch of salt, but:  Haskell does have a 'flip' function
which reverses the order of a function's arguments, so it looks like you
can very easily build a 'partial_right' in Haskell, especially since
standard functions are in curried form.

There was some discussion (started by Antoine Pitrou) of an idea to
generalise 'partial' further, potentially using the Ellipsis object, to
allow arbitrarily-placed 'holes' in the argument list.  E.g.,

   split_comma = partial(str.split, ..., ',')

In some ways I quite like the even-more-completeness of this idea, but
think that it might be the wrong side of the complexity/benefit
trade-off.  Scott David Daniels pointed out that using Ellipsis would
have the downside of

> [...] preventing any use of partial when an argument could be an the
> Ellipsis instance.

This could be fixed by making the general form be something with the
meaning

   partial_explicit(f, hole_sentinel, *args, **kwargs)

where appearances of the exact object 'hole_sentinel' in 'args' would
indicate a hole, to be filled in at the time of the future call.  A user
wanting to have '...' passed in as a true argument could then do

   g = partial_explicit(f, None, 3, ..., 4, axis = 2)

or

   hole = object()
   g = partial_explicit(f, hole, 3, ..., hole, 4, axis = 2)

if they wanted a true '...' argument and a hole.  (I might have the
syntax for this wrong, having not played with Python 3.0, but I hope the
idea is clear.)

There was some concern expressed (by Daniel Stutzbach, Alexander
Belopolsky) that the meaning of '...' would be confusing --- 'one hole'
or 'arbitrary many holes'?

I think the extra complexity vs extra functionality trade-off is worth
considering for 'partial_right', but my personal opinion is that a
'partial_explicit' has that trade-off the wrong way.

I'll try to find time to create the patch in the tracker in the next few
days, by which time perhaps it'll have become clearer whether the idea
is a good one or not.

Thanks,

Ben.


More information about the Python-Dev mailing list