[Python-ideas] Syntactic sugar to declare partial functions
Steven D'Aprano
steve at pearwood.info
Sat Aug 4 13:57:45 EDT 2018
On Sat, Aug 04, 2018 at 09:03:50AM -0700, Fabrizio Messina wrote:
> At the moment we have to load the *partial* function from the *functool*
> library, and apply it to an existing function
[...]
> While partial expose the mechanism excellently its instantiation method is,
> at times, not very friendly,
I disagree with *both* of those statements.
As an implementation of partial function application, partial() has a
couple of weaknesses:
- no support for applying arguments from the right, except by keyword;
- no automatic or easy way to inherit docstrings from the original
function;
- even if you manually set the partial function object's docstring,
help() ignores it. (That's possibly not partial's fault.)
On the other hand, I think that
partial(func, arg, kw=value)
is plenty friendly.
> I would like to propose a syntactic sugar to
> create partial functions, in the case you create a partial function using *curly
> braces*:
[...]
> add_2 = add{2}
Too obscure. What do curly braces have to do with partial function
application? It seems pretty arbitrary.
I know that ultimately ALL conventions are arbitrary, but we already
have a couple of very strong conventions for curly braces (dicts and
sets) and mathematicians have a few strong conventions for partial
function application and currying, neither of which uses curly brackets.
Besides, if we ever did support some sort of function-call-like syntax
using braces spam{...} I would hope it would be for something more
important than partial function application.
You should consider prior art:
- Scala uses a special value, which when passed to a function,
returns a new function:
# using Python syntax
def add(a, b): return a+b
add1 = add(1, _) # like partial(add, 1)
- Perl6 gives all functions an "assuming" method:
add1 = add.assuming(1)
- ML and Haskell define all functions as single-argument functions.
Multiple arguments are actually just syntactic sugar:
func(a, b, c) # syntactic sugar for func(a)(b)(c)
so partial application from the left is trivial:
add1 = add(1)
- but most other languages that I know of use a function or keyword
"partial" (or sometimes, and inaccurately, "curry").
> Now all this can already be done with partial,
Indeed it can.
> but adding this syntactic
> sugar would reduce the perception of `partial` as an advanced feature,
> alleviating the use of closures created only for the sake of avoiding an
> explicit partial.
I don't think that is the case. I think that partial, and currying, are
both relatively advanced features. Many programmers never quite grasp,
or become comfortable with, functions as values.
If we were to push partial application as a mainstream technique, and
I'm not saying we should, but if we did, my vote would be to give
function (and method) objects a partial method:
add1 = add.partial(1)
although possibly a less jargon name would be nicer:
add1 = add.given(1)
--
Steve
More information about the Python-ideas
mailing list