[Python-ideas] A suggestion for Python 3 vs Python 2
Haoyi Li
haoyi.sg at gmail.com
Thu Nov 14 19:02:00 CET 2013
> creating partial applications of functions shouldn't be so common in
real-world code that it needs to be so concise.
I don't quite agree with this; I think a lot of people use some sort of
partial application every day and just don't know it.
- Of the times you use lambda, how often does it redirects all arguments to
a single function, with the rest hard coded?
- How often do you instantiate a class (with some args), call a method on
that class (with some args) and then throw it away, never to be seen again?
Both of these are basically crufty approximations for partial application,
and I see them pretty often, especially the second one.
On Thu, Nov 14, 2013 at 9:45 AM, Andrew Barnert <abarnert at yahoo.com> wrote:
> On Nov 14, 2013, at 7:05, Steven D'Aprano <steve at pearwood.info> wrote:
>
> > On Wed, Nov 13, 2013 at 07:13:19PM -0800, Andrew Barnert wrote:
> >
> >> I know this is getting way off topic, but the real problem with doing
> >> curried/auto-partial functions in Python isn't the parens, it's the
> >> variable arguments. An auto-partial function has to accumulate
> >> parameters if it doesn't get enough, execute when it does. (Currying
> >> gives you that for free, because it means you only get one argument at
> >> a time, but you can do auto-partials without currying.)
> >
> > I disagree. The real problem is the ambiguity. Given:
> >
> > y = divmod(x)
> >
> > did I intend for y to be a partial function, or did I mean to type
> > divmod(x, 3) but mess up? Given how few coders come from a functional
> > programming background, my money is that it's an error.
>
> This may be a reason not to do it, but it's not something that makes it
> hard or impossible to do it. Variable arguments _are_ something that makes
> it hard or impossible to do it.
>
> > In languages with static typing, it's easy for the compiler to resolve
> > this: if y is declared as a function object, then I meant for the
> > partial application. If y is declared as an int, then it's an error. But
> > you can't do this in Python.
>
> That's not how it works in any of the languages we're talking about. They
> have a type inference system, usually based on Hindley-Milner, not a
> C-style nominal type system.
>
> Of course sometimes declared (or elsewhere-inferred) variable types will
> resolve an ambiguity during unification, but that's not the usual case;
> declared or inferred function types do so far more often. divmod is
> int*int->int*int (or, in a curried language, int->int->int*int), and
> therefore this expression is only typable if it's a partial, and y's type
> is inferred from the type the expression has as a partial. (And if you've
> declared y to have an explicit type that isn't compatible with the partial,
> you get a unification error.)
>
> If you allow varargs functions, where the type can be int->int or
> int*int->int, HM doesn't work. And, not coincidentally, none of these
> languages allow varargs functions.
>
> > [...]
> >> But to handle a vararg function, you'd need a separate syntax for
> >> partializing vs. calling.
> >
> > We have that. It's called functools.partial :-)
>
> Yes, but the (sub-)thread started off with (summarizing) "I wish we had
> something more brief/simple/Scala-like for partials than
> functools.partial". And functools.partial is not an answer to that.
>
> > Aside: am I the only one who wishes there was a functools.rpartial, that
> > binds from the right instead of the left?
>
> I've often wanted that. I've even built it a few times. It has the same
> problem with keyword arguments and keyword-only params that auto-partialing
> does, but it doesn't feel like as much of a limitation--you just wouldn't
> ever use it in those cases (especially since you can often just bind the
> argument by keyword in those cases).
>
> I've also occasionally wanted a partial where you specify the indices of
> the arguments as keywords (which gives you rpartial just by using -1), so I
> could more easily bind the second of three (or even of variable) arguments.
> But that comes up less often.
>
> >> Using a different operator like [] or % or << seems attractive at
> >> first, but it can't handle keywords.
> >> You could add a method, so spam._(n=5) returns partial(spam, n=5), but
> >> ._ is hideous, and anything meaningful like bind or partial is no
> >> longer a shortcut.
> >
> > And why is this a problem?
>
> I assume you're not asking about why ._ being hideous is a problem, but
> why .partial being not a shortcut is a problem, right?
>
> Offering foo.partial(n=5) as an alternative for partial(foo, n=5) doesn't
> provide any benefit--it's not easier to read, more obvious to write,
> shorter, or better in any other way. It just gives you two obvious ways to
> do it instead of one. Which is bad.
>
> > You read code more often than you type it,
> > and quite frankly, creating partial applications of functions shouldn't
> > be so common in real-world code that it needs to be so concise.
>
> It's common in many application areas. For example, I have a row of radio
> buttons. Instead of defining 5 separate callback functions, I write one
> callback function that takes a number from 0 to 4, and then I bind each
> button to partial(callback, n).
>
> Many people today instead bind each button to a lambda, I suspect because
> the tkinter tutorials all use lambda for this purpose instead of partial.
>
> I've also seen people write an explicit make_btn_callback function so they
> can bind each button to make_btn_callback(n)
>
> Anyway, compare these three and tell me you see zero benefit in the last
> one:
>
> Button(frame, str(i), lambda event: click(i, event))
> Button(frame, str(i), partial(click, i))
> Button(frame, str(i), click(i, ...))
>
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20131114/b98faac8/attachment.html>
More information about the Python-ideas
mailing list