Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

add_command

2 views
Skip to first unread message

Gorny

unread,
May 12, 2002, 12:43:01 PM5/12/02
to
Hi,

Is there a way of doing something so a menu-command can call
the callback function with (more) or other arguments??

So you could use instead of this:

status = Menu()
status.add_command(label='wh00t', command=self.func)

something like:

status.add_command(label='wh00t', command=self.func,
argskeyword=tuple_containing_args)

Gorny

--
"Spread the sources"
http://gorny.cjb.net

Alex Martelli

unread,
May 12, 2002, 1:11:29 PM5/12/02
to
Gorny wrote:

> Hi,
>
> Is there a way of doing something so a menu-command can call
> the callback function with (more) or other arguments??

Sure, you're just looking for a special case of currying as covered in
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52549 .

> So you could use instead of this:
>
> status = Menu()
> status.add_command(label='wh00t', command=self.func)
>
> something like:
>
> status.add_command(label='wh00t', command=self.func,
> argskeyword=tuple_containing_args)

If it's a tuple it's unlikely to hold _keyword_ arguments --
more likely it will hold positional ones, no?

Anyway, the special-case you need is something line (in Python 2.2,
or 2.1 with "from __future__ import nested_scopes"):

def curry(func, *args, **kwds):
def curried(): return func(*args, **kwds)
return curried

then you'll call something like

status.add_command(label='wh00t',
command=curry(self.func, *tuple_containing_args))


Alex


Gorny

unread,
May 13, 2002, 3:35:02 AM5/13/02
to

"Alex Martelli" <al...@aleax.it> schreef in bericht
news:5nxD8.33442$CN3.1...@news2.tin.it...

> Gorny wrote:
> >
> > status.add_command(label='wh00t', command=self.func,
> > argskeyword=tuple_containing_args)
>
> If it's a tuple it's unlikely to hold _keyword_ arguments --
> more likely it will hold positional ones, no?

Aargh of course...*flame me*

> Anyway, the special-case you need is something line (in Python 2.2,
> or 2.1 with "from __future__ import nested_scopes"):
>
> def curry(func, *args, **kwds):
> def curried(): return func(*args, **kwds)
> return curried
>
> then you'll call something like
>
> status.add_command(label='wh00t',
> command=curry(self.func, *tuple_containing_args))

Allright, that'll do fine. I've read the corresponding PEP and it seems
perfectly clear to me. But in the future (as of 2.3) I assume that you
don't have to import anything and the nested_scopes are implemented
within Python's core?

Alex Martelli

unread,
May 13, 2002, 4:34:38 AM5/13/02
to
Gorny wrote:
...

>> Anyway, the special-case you need is something line (in Python 2.2,
>> or 2.1 with "from __future__ import nested_scopes"):
>>
>> def curry(func, *args, **kwds):
>> def curried(): return func(*args, **kwds)
>> return curried
>>
>> then you'll call something like
>>
>> status.add_command(label='wh00t',
>> command=curry(self.func, *tuple_containing_args))
>
> Allright, that'll do fine. I've read the corresponding PEP and it seems
> perfectly clear to me. But in the future (as of 2.3) I assume that you
> don't have to import anything and the nested_scopes are implemented
> within Python's core?

You don't have to import anything in Python 2.2, either - I was just
mentioning the import as needed in Python _2.1_, which is still out
and about (the current stable release of Zope needs 2.1.3, I think).

You can also curry in Python 1.5.2 should you need to -- it's just
a _little_ bit clunkier perhaps:

def curry(func, *args, **kwds):
def curried(f=func, a=args, k=kwds):
return apply(f, a, k)
return curried

This works in any Python release (1.5.2 and later, at least) and,
apart from clarity or *tiny* performance differences, the only real
issue is that with this version you might accidentally call the
function built and returned from curry with an argument and thus
break the mechanism -- the 2.2 solution has no such risk (the
function built and returned from that version of curry takes no
arguments whatsoever, so trying to call it with an argument at
once raises an exception; the 1.5.2 solution uses "default
values of arguments" to compensate for the lack of lexically
nested scopes).


Alex

holger krekel

unread,
May 13, 2002, 4:49:55 AM5/13/02
to
Alex Martelli wrote:
> You can also curry in Python 1.5.2 should you need to -- it's just
> a _little_ bit clunkier perhaps:
>
> def curry(func, *args, **kwds):
> def curried(f=func, a=args, k=kwds):
> return apply(f, a, k)
> return curried

Alex, what do you think about integrating the
currying-concept into python's syntax like so:

def normalfunc(arg1,arg2,arg3): pass

curryfunc = normalfunc(arg1, *, arg3)

and curryfunc would be a one-argument function [1].
I'm sure you can explain to me in concise
words why this is the wrong thing (tm) :-)
IMHO currying is a well-understood concept
which would serve well at the language level.

regards,

holger


[1] the '*' should and can be recognized by the parser
to avoid *any* performance decreases for
normal function calls. One may allow
or enforce '***' to make it more visible.


Alex Martelli

unread,
May 13, 2002, 5:55:18 AM5/13/02
to
holger krekel wrote:
...

>> def curry(func, *args, **kwds):
>> def curried(f=func, a=args, k=kwds):
>> return apply(f, a, k)
>> return curried
>
> Alex, what do you think about integrating the
> currying-concept into python's syntax like so:

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?) and doubtful
in several ways (is currying important enough to
deserve special syntax, and, if so, what is the right
sugar for it?). A more sensible, gradualistic
approach might be to look for consensus on the exact
functionality that can be encapsulated in a built-in,
or even as a curry function that might be part of a
new FP module -- _that_ one we might stand a chance to
get into the standard library, perhaps. If and when
currying becomes so popular as to deserve its own
special syntax sugar, then it may be a better time to
debate the details of that sugar.

> 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.

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.


Alex

holger krekel

unread,
May 13, 2002, 1:31:32 PM5/13/02
to
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 think the usual TypeErrors when e.g. supplying multiple
values for an argument are straight forward to come up
with.

> (is currying important enough to
> deserve special syntax, and, if so, what is the right
> sugar for it?)

There are some good reasons IMO for making it a syntax thing
but first the concepts, agreed.

> A more sensible, gradualistic
> approach might be to look for consensus on the exact
> functionality that can be encapsulated in a built-in,
> or even as a curry function that might be part of a
> new FP module -- _that_ one we might stand a chance to
> get into the standard library, perhaps. If and when
> currying becomes so popular as to deserve its own
> special syntax sugar, then it may be a better time to
> debate the details of that sugar.

yes. Only it is not so easy to get even a
builtin to provide 'enough' convenience. Consider one of
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.

> > 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.

> 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?

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 :-)

holger


Alex Martelli

unread,
May 13, 2002, 2:51:44 PM5/13/02
to
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


Thomas Heller

unread,
May 13, 2002, 4:02:41 PM5/13/02
to
"Alex Martelli" <al...@aleax.it> wrote in message news:mailman.1021316005...@python.org...

> It may be possible to offer all functionality in a way that turns
> out to be regular and simple enough, e.g.
IF we are already brainstorming, here are my thoughts:

> curry(f, Arg(1), Arg(0))
curry(f, Arg[1, 0])

> to swap the first two positional arguments,
> curry(f, 2, Arg())

curry(f, 2, Arg[:])


> to insert a 2 as 1st arg and shift all other args right by one,

> curry(f, 2, Arg(1:))
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.
>

This class lets you play with this 'syntax':

class ARG:
def __getitem__(self, magic):
return magic

> 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
>

Thomas


holger krekel

unread,
May 14, 2002, 5:32:01 AM5/14/02
to
<taken back to the the list, hope that's ok with you>

Paul Foley wrote:


> On Mon, 13 May 2002 10:49:55 +0200, holger krekel wrote:
>
> > Alex Martelli wrote:
> >> You can also curry in Python 1.5.2 should you need to -- it's just
> >> a _little_ bit clunkier perhaps:
> >>
> >> def curry(func, *args, **kwds):
> >> def curried(f=func, a=args, k=kwds):
> >> return apply(f, a, k)
> >> return curried
>
> > Alex, what do you think about integrating the
> > currying-concept into python's syntax like so:
>
> > def normalfunc(arg1,arg2,arg3): pass
>
> > curryfunc = normalfunc(arg1, *, arg3)
>

> Python already has it:
>
> curryfunc = lambda x: normalfunc(arg1, x, arg3)
>
> now that Python has lexical scoping.

your are right and this obsoletes my suggestion mostly.
Using lambdas seems cleaner than introducing new syntax.

And introducing a builtin like 'curry' (see alex post)
tends to be wordier and harder to read than your simple
solution. IMO the '*' syntax thing may make the intention
of prebinding arguments a bit more obvious than lambdas
or a builtin but it's (probably) not worth thinking about.

regards,

holger


holger krekel

unread,
May 14, 2002, 5:40:23 AM5/14/02
to
Alex Martelli wrote:

> 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?!

This doesn't make it obvious to me. I guess you mean that
curring with named arguments should work as well?! Then i would
probably say that 'arg1=***' could be allowed also...

please note that i started this discussion with:
"alex, what do you think about ...", NOT with
"hey all, I have a PEP language change proposal".
And that was precisely because i thought i might be
on the path to all evil and that it would be easy for you
to point it out.

> 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.

i didn't intend to break orthogonality as might be evident.
if you simply show the non-orthogonality that would be enough.

But as Paul Foley already pointed out, today's lambdas in
combination with lexical scoping offer a good way for
most 'prebinding' wishes, so further discussion does not
seem to make much sense.

Additionally, i should not have talked so much about currying
as 'prebinding' was what i actually meant.

thanks for your answers,

holger


0 new messages