On 2013-11-14, at 16:05 , Steven D'Aprano firstname.lastname@example.org 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.
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.
In most of those languages, y likely isn’t explicitly typed and its type will be inferred depending on how it’s used.
If y is declared as an int, then it's an error. But you can’t do this in Python.
But it’ll likely blow up a few lines below when you try to perform arithmetic operations on a function (not that this is a good thing, but it’s no different from a function returning an unexpected None)
But to handle a vararg function, you'd need a separate syntax for partializing vs. calling.
We have that. It's called functools.partial :-)
Aside: am I the only one who wishes there was a functools.rpartial, that binds from the right instead of the left?
I’ve wanted this as well. Or the ability to somehow “fill holes”. Scala- or Clojure-type parse transforms are pretty neat for that (write the call with holes/placeholders, the call is deferred as a function taking arguments to fill the placeholders)
Examples of Scala have already been provided, in Clojure it’s an explicit reader form:
#(foo 1 2 %)
is equivalent (and expanded) to
(fn [arg] (foo 1 2 arg))