currying at language level (was: Re: add_command)

Alex Martelli aleax at aleax.it
Mon May 13 14:51:44 EDT 2002


On Monday 13 May 2002 19:31, holger krekel wrote:
> Alex Martelli wrote:
> > I'd love to have built-in currying, but the syntax
> > sugar you propose is clearly too limited (e.g., how
> > does it apply to keyword-arguments?)
>
> does it need to? IOW what problems do you expect?

I expect a language that doesn't treat named arguments
as 'first class' (==just as important as positional ones) in
SOME but not ALL cases.  Isn't that absolutely obvious?!

The 'orthogonality' of Python is #1 key to its power AND
simplicity.  You need mighty powerful arguments indeed
for BREAKING orthogonal, uniform behavior, as should
be self-evident.  So, what are your mighty powerful
arguments for proposing to mandate such a breach?  IF
you can come up with them, I may give counter-arguments
and counter-examples.  But the meta-argument is more
important: you don't break regularity without a darned good
reason or three in support; you don't even THINK of doing so.


> i think the usual TypeErrors when e.g. supplying multiple
> values for an argument are straight forward to come up
> with.

No doubt.  So?

> yes. Only it is not so easy to get even a
> builtin to provide 'enough' convenience. Consider one of

You may be overrating convenience wrt regularity and
simplicity.

> my currying implementations which does it like so:
>
> f1=PrebindFunc(f, BINDLATER, 2, BINDLATER, karg1="hehe")
>
> But how can you get around the special name 'BINDLATER'?
> Take 'XXX'? Somehow it doesn't seem right to me to
> try to makeup a name. Not unless there is a standardization
> on ONE name which is hard to achieve.

Why would a special character * 'seem right' if a well chosen
argument name doesn't?  How is * allegedly clearer?


> > > IMHO currying is a well-understood concept
> >
> > It sure is _in a specific way_, the one analyzed and
> > widely used by Dr Haskell Curry: applying a function
> > f (which you could consider an "N-argument function"
> > in traditional terms) to an argument a to yield a new
> > anonymous function which you could consider an "N-1
> > argument function" in traditional terms.
>
> I don't know haskell, sorry, but just currying the
> leftmost arguments is quite restrictive and doesn't
> fit to python's functio model IMO.

Dr Haskell Curry is the mathematician in whose honor both
the Haskell language and the currying technique are named.

There is no practical difference between:

f x = g x y

and

h x = g y x

although in the latter case you can abbreviate as

h = g y

there's nothing "quite restrictive" about not having some ad hoc
abbreviation in the former case -- it's easy enough to add a where
clause anyway, should you need one.

Currying only positional arguments doesn't fit Python -- keyword
ones need fully equal status.  What exactly do we need to express,
and how?  What about the equivalent of, say:

lambda n1, n2: f(n2, n1)

don't we need THAT, too?  If arbitrary sets of arguments can be
pre-set, why is it satisfactory that the *ordering* (since args are
sequences, not really sets) must be identical between original
and any curried forms?

I *don't* think these are "well understood concepts" (while currying
as invented by Dr Curry surely IS -- but, you consider it "quite
restrictive").  We need a consensus on the exact functionality
package to be supplied.  You seem to take it for granted that
"currying is a well understood concept" means your exact take on
it is universal and widely accepted -- no named args need apply,
ordering cannot be altered, but any subset of args can be pre-bound
(...can I supply defaults for some, while still leaving them overridable
at calltime?  Why not?).  I claim it most surely isn't -- the simple
("quite restrictive" according to you) version invented by Dr Curry
_IS_, anything beyond that isn't -- we don't have consensus on
exactly what functionality this "extended currying" should supply.


> > But this doesn't mean we know exactly what should be
> > done in presence of named/optional arguments and other
> > cases of variadic functions.  "Currying the 1st and
> > 3rd args of a 3-argument functions" is also a somewhat
> > unexplored realm AFAIK.
>
> If people knew how to do it and if it were easy to type
> they'd like it, i guess. Wouldn't you?

Maybe, maybe not.  Instinctively, I'm horrified at the very idea
of requiring entirely new syntax (neutron bombs, not just big
guns) and STILL not getting anywhere near the complete
functionality that's obviously a possible request.

> It may be *a bit* like with 'yield'. Once you get it you
> don't want to live without it. But you didn't know before.
> Or maybe _you_ did :-)

No, but neither did I have any pre-judgments about it (nor did
I ever claim "yielding is a widely understood concept" as a way to
cover up the novelty of the exact functionality being introduced:-).

It may be possible to offer all functionality in a way that turns
out to be regular and simple enough, e.g.
	curry(f, Arg(1), Arg(0))
to swap the first two positional arguments,
	curry(f, 2, Arg())
to insert a 2 as 1st arg and shift all other args right by one,
	curry(f, 2, Arg(1:))
to insert a 2 instead of the 1st actual arg (ignoring it) and leave
all others alone, etc, etc.  That magical Arg thing could even be
used plain rather than called to indicate "Arg(i) where i is the
progressive number of this argument to curry after the callable",
used as in "Arg(2, 'name')" to indicate that this may be passed
as named argument ' name' alternatively, etc.

Maybe, and maybe not.  We're talking of "signature adaptation".
How far do we need to go?  How easy will it be to explain, how
easy to use, how complete in its coverage of so-called-currying
needs?  I don't think we have anywhere like complete
understanding of this complicated set of issues.


Alex





More information about the Python-list mailing list