Re: PEP 309 (Partial Function Application) Idea
for a new function, named parameter might be a better choise, but for existing function, placeholder would be better, since you don't need to modify the exiting code. -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 309 (Partial Function Application) Idea
sorry, should be existing -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 309 (Partial Function Application) Idea
for a new function, named parameter might be a better choise, but for existing function, placeholder would be better, since you don't need to modify the existing code. -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 309 (Partial Function Application) Idea
Ronald Mai wrote: Here is a reference implementation: _ = lambda x: x.pop(0) def partial(func, *args, **keywords): def newfunc(*fargs, **fkeywords): newkeywords = keywords.copy() newkeywords.update(fkeywords) newargs = (lambda seq: tuple([(a == _ and a(seq)) or a for a in args] + seq))(list(fargs)) return func(*newargs, **newkeywords) newfunc.func = func newfunc.args = args newfunc.keywords = keywords return newfunc Here is example of use: def capture(*args): return args partial(capture)() () partial(capture, _)(1) (1,) partial(capture, _, 2)(1) (1, 2) partial(capture, 1)(2) (1, 2) partial(capture, 1, _)(2) (1, 2) partial(capture, 1, _)() IndexError: pop from empty list partial(capture, 1, _, _)(2, 3) (1, 2, 3) Other implementations I have seen (boost::bind comes to mind) use ordered placeholders such as _1, _2, _3, etc to provide more flexibility in adaptation: partial(capture, a, _1, _2)(b, c) (a, b, c) partial(capture, a, _2, _1)(b, c) (a, c, b) I don't see mention of this in the PEP, but it's a nice feature to have IMO. -- Giovanni Bajo -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 309 (Partial Function Application) Idea
Giovanni Bajo wrote: Ronald Mai wrote: Here is a reference implementation: _ = lambda x: x.pop(0) def partial(func, *args, **keywords): def newfunc(*fargs, **fkeywords): newkeywords = keywords.copy() newkeywords.update(fkeywords) newargs = (lambda seq: tuple([(a == _ and a(seq)) or a for a in args] + seq))(list(fargs)) return func(*newargs, **newkeywords) newfunc.func = func newfunc.args = args newfunc.keywords = keywords return newfunc Here is example of use: def capture(*args): return args partial(capture)() () partial(capture, _)(1) (1,) partial(capture, _, 2)(1) (1, 2) partial(capture, 1)(2) (1, 2) partial(capture, 1, _)(2) (1, 2) partial(capture, 1, _)() IndexError: pop from empty list partial(capture, 1, _, _)(2, 3) (1, 2, 3) Other implementations I have seen (boost::bind comes to mind) use ordered placeholders such as _1, _2, _3, etc to provide more flexibility in adaptation: partial(capture, a, _1, _2)(b, c) (a, b, c) partial(capture, a, _2, _1)(b, c) (a, c, b) I don't see mention of this in the PEP, but it's a nice feature to have IMO. -- Giovanni Bajo Since python has named parameter(and I assume this PEP would support it as well), is it really that useful to have these place holder things ? As when the parameter list gets long, named param should be easier to read. The only case I find it useful is for binary ops where I would like to either bind the left hand side or the right hand side but that can be handled easily with a flip function as in haskell. -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 309 (Partial Function Application) Idea
[EMAIL PROTECTED] wrote: Since python has named parameter(and I assume this PEP would support it as well), is it really that useful to have these place holder things ? Probably not so much, you're right. As when the parameter list gets long, named param should be easier to read. The only case I find it useful is for binary ops where I would like to either bind the left hand side or the right hand side but that can be handled easily with a flip function as in haskell. I'm not sure I'd like a specialized flip function, compared to the numbered placeholders solution. -- Giovanni Bajo -- http://mail.python.org/mailman/listinfo/python-list
PEP 309 (Partial Function Application) Idea
In my opinion, Ellipsis might be in the middle, not only in leftmost or rightmost, so a placeholder approach can be much more flexible and convenient. Here is a reference implementation: _ = lambda x: x.pop(0) def partial(func, *args, **keywords): def newfunc(*fargs, **fkeywords): newkeywords = keywords.copy() newkeywords.update(fkeywords) newargs = (lambda seq: tuple([(a == _ and a(seq)) or a for a in args] + seq))(list(fargs)) return func(*newargs, **newkeywords) newfunc.func = func newfunc.args = args newfunc.keywords = keywords return newfunc Here is example of use: def capture(*args): return args partial(capture)() () partial(capture, _)(1) (1,) partial(capture, _, 2)(1) (1, 2) partial(capture, 1)(2) (1, 2) partial(capture, 1, _)(2) (1, 2) partial(capture, 1, _)() IndexError: pop from empty list partial(capture, 1, _, _)(2, 3) (1, 2, 3) Chris Perkins : Random idea of the day: How about having syntax support for currying/partial function application, like this: func(..., a, b) func(a, ..., b) func(a, b, ...) That is: 1) Make an Ellipsis literal legal syntax in an argument list. 2) Have the compiler recognize the Ellipsis literal and transform the function call into a curried/parially applied function. So the compiler would essentially do something like this: func(a, ...) == curry(func, a) func(..., a) == rightcurry(func, a) func(a, ..., b) == rightcurry(curry(func,a), b) I haven't though this through much, and I'm sure there are issues, but I do like the way it looks. The ... really stands out as saying something is omitted here. Chris Perkins -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 309 (Partial Function Application) Idea
Steven Bethard [EMAIL PROTECTED] wrote: getting attributes with defaults[1]: objs.sort(key=lambda a: getattr(a, 'lineno', 0)) objs.sort(key=getattr(__, 'lineno', 0) Yes, this exact example is one of the (very) few that I found in the standard library where the syntax actually helps. Places where you might be able to use it (with some changes): using bound methods[1][2]: map(lambda x: x.strip(), lst) map(str.strip(), lst) #!! doesn't work for unicode map(methodcaller('strip'), lst) # proposed by Alex Martelli __.strip() # note that calling strip on __ would have to # return a curryable looking for one arg... Yes, the bound method problem is what convinced me to give up on this. One can hardly write strip() (yes, that's four dots). But note that there is a library out there that does precisely this (and much more, if I remember) - I believe it's in David Mertz's Xoltar toolkit. It does allow you to write _.strip() and get a curried callable (He uses _, a single underscore, as the magic thingy, which is odd considering its established meaning in interactive mode). If we could add an object to the builtins (or elsewhere) called __ that works as I proposed for ..., and also behaves like the things in David Mertz's library (sorry, don't remember exactly where to find it, or what it's called, and don't have time to look it up right now), then this might really get interesting. Then we could do any of: getattr(__, 'lineno', 0) __.strip() __.foo().bar(__) adding method to an instance[1]: self.plural = lambda n: int(n != 1) and _maybe_ even: self.plural = int(__ != 1) But wait - on second thought, __ is a legal identifier now, unlike ..., so we can't have the compiler messing around with expressions like foo(x, __), can we. OK, now I really give up on the whole idea! Chris Perkins -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 309 (Partial Function Application) Idea
Reinhold Birkenfeld wrote: Steven Bethard wrote: Chris Perkins wrote: Random idea of the day: How about having syntax support for currying/partial function application, like this: func(..., a, b) func(a, ..., b) func(a, b, ...) That is: 1) Make an Ellipsis literal legal syntax in an argument list. 2) Have the compiler recognize the Ellipsis literal and transform the function call into a curried/parially applied function. So the compiler would essentially do something like this: func(a, ...) == curry(func, a) func(..., a) == rightcurry(func, a) func(a, ..., b) == rightcurry(curry(func,a), b) I haven't though this through much, and I'm sure there are issues, but I do like the way it looks. The ... really stands out as saying something is omitted here. The interaction of this with keyword args and omitted args is problematic (as is the case for rightcurry, in fact). I can't think of a good way to explain what _should_ happen for a function defined as def function(*args, **kwargs): ... when you: def fun(bug, frog, verb): ... f1 = function(1, ..., frog=3) f2 = f1(..., 4) f2() Keywords were why I did no rightcurry definition in the first place; I couldn't convince myself there was a good, obvious, resolution. --Scott David Daniels [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 309 (Partial Function Application) Idea
Scott David Daniels wrote: Chris Perkins wrote: Random idea of the day: How about having syntax support for currying/partial function application, like this: func(..., a, b) func(a, ..., b) func(a, b, ...) That is: 1) Make an Ellipsis literal legal syntax in an argument list. 2) Have the compiler recognize the Ellipsis literal and transform the function call into a curried/parially applied function. So the compiler would essentially do something like this: func(a, ...) == curry(func, a) func(..., a) == rightcurry(func, a) func(a, ..., b) == rightcurry(curry(func,a), b) The interaction of this with keyword args and omitted args is problematic (as is the case for rightcurry, in fact). I can't think of a good way to explain what _should_ happen for a function defined as def function(*args, **kwargs): ... when you: def fun(bug, frog, verb): ... f1 = function(1, ..., frog=3) f2 = f1(..., 4) f2() Keywords were why I did no rightcurry definition in the first place; I couldn't convince myself there was a good, obvious, resolution. I agree that it's not obvious what _should_ happen in complex cases. I wrote up a psuedo-implementation to play with, just to get a feel for it. It works only on @curryable functions, and I use __ in place of I think that's about as close as I can get in pure Python. def curryable(func): This hurts my brain a little bit, but I _think_ it works. def proxyfunc(*args, **kwds): if list(args).count(Ellipsis) 1: raise TypeError('Your mother was a hampster...') if Ellipsis in args: @curryable def curried(*a, **k): kwdict = kwds.copy() kwdict.update(k) epos = list(args).index(Ellipsis) return func(*(args[:epos] + a + args[epos+1:]), **kwdict) return curried return func(*args, **kwds) return proxyfunc def test(): __ = Ellipsis @curryable def fun(bug, frog, verb): print bug, frog, verb f1 = fun(1, __, frog=3) f2 = f1(__, 4) try: f2() except TypeError, e: print e # multiple values for keyword 'frog' f1 = fun(1, __, verb=3) f2 = f1(__, 4) f2() f2(verb=99) try: f1(__, 2, __) except TypeError, e: print e if __name__ == '__main__': test() After playing with this a bit, I found the semantics to be reasonably obvious once I got used to it; at least in the cases I tried. I'd be quite happy to have anything fishy throw an exception. Cases where I would actually use this would be quite simple, I think. On the other hand, I'm not convinced that this construct would be especially useful. I spent some time looking at uses of lambda in the standard library, hoping to find lots of examples where a (...) function would be more readable, but I eventually gave up. (Found dozens of cases where a list-comp or genexp would be better, though). While I think that func(x, ...) is more readable than partial(func, x), I'm not sure that I would use either of them often enough to warrant special syntax. If anyone disagrees, feel free to petition python-dev; I don't expect to pursue this any further. Thanks to all for your comments. Chris Perkins -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 309 (Partial Function Application) Idea
Chris Perkins wrote: [snip implementation] While I think that func(x, ...) is more readable than partial(func, x), I'm not sure that I would use either of them often enough to warrant special syntax. Interesting. Thought it might be worth listing a few of the current places people use lambdas (and lambda replacements like operator.attrgetter/itemgetter) that this might be useful, and a few of the places where it probably wouldn't be. Places where it might be useful: getting attributes: lambda obj: obj.attr attrgetter('attr') getattr(__, attr) getting attributes with defaults[1]: objs.sort(key=lambda a: getattr(a, 'lineno', 0)) objs.sort(key=getattr(__, 'lineno', 0) Places where you might be able to use it (with some changes): using bound methods[1][2]: map(lambda x: x.strip(), lst) map(str.strip(), lst) #!! doesn't work for unicode map(methodcaller('strip'), lst) # proposed by Alex Martelli __.strip() # note that calling strip on __ would have to # return a curryable looking for one arg... Places where I can't see how to use it: creating a function out of nothing[2]: button.setlabel(lambda: 'Click Me!') button.setlabel('Click Me!'.__str__) # works 'cause str returns self adding arguments[1]: lambda x: adding method to an instance[1]: self.plural = lambda n: int(n != 1) So I guess it's a cool idea, but I don't know if it's really going to pacify anyone who is upset about losing lambda... (Not that I'm suggesting that was your intention -- but it's something that's been recently on my mind.) Steve [1]http://mail.python.org/pipermail/python-list/2004-December/257990.html [2]http://www.artima.com/forums/flat.jsp?forum=106thread=98196 -- http://mail.python.org/mailman/listinfo/python-list
PEP 309 (Partial Function Application) Idea
Random idea of the day: How about having syntax support for currying/partial function application, like this: func(..., a, b) func(a, ..., b) func(a, b, ...) That is: 1) Make an Ellipsis literal legal syntax in an argument list. 2) Have the compiler recognize the Ellipsis literal and transform the function call into a curried/parially applied function. So the compiler would essentially do something like this: func(a, ...) == curry(func, a) func(..., a) == rightcurry(func, a) func(a, ..., b) == rightcurry(curry(func,a), b) I haven't though this through much, and I'm sure there are issues, but I do like the way it looks. The ... really stands out as saying something is omitted here. Chris Perkins -- http://mail.python.org/mailman/listinfo/python-list
Re: PEP 309 (Partial Function Application) Idea
Chris Perkins wrote: Random idea of the day: How about having syntax support for currying/partial function application, like this: func(..., a, b) func(a, ..., b) func(a, b, ...) That is: 1) Make an Ellipsis literal legal syntax in an argument list. 2) Have the compiler recognize the Ellipsis literal and transform the function call into a curried/parially applied function. So the compiler would essentially do something like this: func(a, ...) == curry(func, a) func(..., a) == rightcurry(func, a) func(a, ..., b) == rightcurry(curry(func,a), b) I haven't though this through much, and I'm sure there are issues, but I do like the way it looks. The ... really stands out as saying something is omitted here. Interesting idea, but I have a feeling that it probably won't fly for a couple of reasons: (1) The existing use of Ellipsis doesn't have anything to do with your suggested use. I think people are generally opposed to giving keywords/symbols in Python two very different meanings. This is one of the reasons Guido never liked the a, b, *c = iterable syntax. (2) Emphasis recently on python-dev has been away from syntax changes and towards expansion of the standard library. You would have to make a _very_ good case that the new syntax is merited. Generally I do like the idea -- I think a lot of the cases that people have made for keeping lambda could be discarded with something like this... But it'd need an extremely well thought out PEP (and an implementation of course) and even then, I wouldn't get my hopes up. STeVe -- http://mail.python.org/mailman/listinfo/python-list