[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

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.