[PSA MEMBERS] Re: [Types-sig] Suggestions for python 2
Edward Welbourne
Edward Welbourne <eddy@chaos.org.uk>
Mon, 17 Jan 2000 18:37:20 GMT
>> * certain tools the functional programmers crave, notably a truly
>> faithful implementation of currie()
>
> not required: python lambdas subsume what can be done with
> currying.
Unfortunately, unless I'm missing something, this is only true when you
know the call-signature of the function you are packaging. Without safe
tunnels, I can see no way of handling even the simple case of `provide
the first argument to a function given no knowledge of how many
arguments the caller is going to give it': the currie()d result has to
use *args in its argument-list, yet we need arguments which supply it
with the function to call and the given first argument; these have to
appear before the *args (unless something has changed and no-one has
told me), consequently they will be over-ridden by the first few
arguments passed in by the caller of the constructed function:
def currieone(func, one):
def result(*args, f=func, o=one):
return apply(f, (o,) + args)
return result
as safe tunnels would put it; if f and o precede *args (which they
currently must, as I understand it), the result is doomed because
lambda f=func, o=one, *args: apply(f, (o,) + args)
called with args (a, b, c) would bind a in as f (over-riding the default
supplied, func), b as o (ditto, one), leaving args = (c,), so it would
attempt to call a(b, c) where func(one, a, b, c) was our intent.
Can you show me a piece of valid python (using lambdas or otherwise)
which achieves this effect ?
Granted, it can all be done (one of the first toys I built in python) as
a class ... but I need stuff like it before I can implement class ...
and we get so much more out of liberalising the position of *args and
**kwds relative to the name=value parameters. Like, for instance, the
ability to have a function take arbitrarily many positional arguments
along with some keyword-arguments without the former and the latter
getting tangled up with one another - the things I call generators
commonly use (*bases, dict=None, meth=None, **what) ... unless dict and
meth keywords are used when the function is invoked, the function will
see them as None, no matter how many arguments are passed.
And, just for clarity, I don't particularly want this for the functional
tools (cute though I find them, fun though I find it to build them, and
useful though they are as sample things to check a system is powerful
enough to support) so much as for the expressive clarity of, for
instance,
def join(*strings, glue=' '):
return string.joinfields(strings, glue)
invokable as join('hello', 'there', 'all', 'you', 'pythoneers') or, if
different padding is wanted, join('in', "Tim's", 'style', glue='-'),
without having to put [] around the sequence of strings that aren't the
keyword-supplied glue.
Eddy.