On 07/18/2010 05:52 PM, Reid Kleckner wrote: > Usual disclaimer: python-dev is for the development *of* python, not > *with*. See python-list, etc.
Moving to python-list. Please keep discussion there. > > That said, def declares new functions or methods, so you can't put > arbitrary expressions in there like type(f).__mul__ . > > You can usually assign to things like that though, but in this case > you run into trouble, as shown below: > >>>> def func(): pass > ... >>>> type(func) > <class 'function'> >>>> def compose(f, g): > ... return lambda x: f(g(x)) > ... >>>> type(func).__mul__ = compose > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > TypeError: can't set attributes of built-in/extension type 'function' > > As the interpreter says, it doesn't like people mucking with operator > slots on built in types. > > Finally, if you like coding in that very functional style, I'd > recommend Haskell or other ML derived languages. Python doesn't > support that programming style very well by choice. > > Reid > > On Sun, Jul 18, 2010 at 8:34 AM, Christopher Olah > <christopherolah...@gmail.com> wrote: >> Dear python-dev, >> >> In mathematical notation, f*g = z->f(g(z)) and f^n = f*f*f... (n >> times). I often run into situations in python where such operators >> could result in cleaner code. Eventually, I decided to implement it >> myself and see how it worked in practice. >> >> However, my intuitive implementation [1] doesn't seem to work. In >> particular, despite what it says in function's documentation, function >> does not seem to be in __builtin__. Furthermore, when I try to >> implement this through type(f) (where f is a function) I get invalid >> syntax errors. >> >> I hope I haven't made some trivial error; I'm rather inexperienced as >> a pythonist. >> >> Christopher Olah >> >> >> [1] Sketch: >> >> def __builtin__.function.__mul__(self, f): >> return lambda x: self(f(x)) >> >> def __builtin__.function.__pow__(self, n): >> return lambda x: reduce(lambda a,b: [f for i in range(n)]+[x]) As Reid explained, you can't just muck around with built-in types like that. However, you can "use a different type". If you're not familiar with Python decorators, look them up, and then have a look at this simple implementation of what you were looking for: >>> class mfunc: ... def __init__(self, func): ... self.func = func ... self.__doc__ = func.__doc__ ... self.__name__ = func.__name__ ... def __call__(self, *args, **kwargs): ... return self.func(*args, **kwargs) ... def __mul__(self, f2): ... @mfunc ... def composite(*a, **kwa): ... return self.func(f2(*a, **kwa)) ... return composite ... def __pow__(self, n): ... if n < 1: ... raise ValueError(n) ... elif n == 1: ... return self.func ... else: ... return self * (self ** (n-1)) ... >>> @mfunc ... def square(x): return x*x ... >>> @mfunc ... def twice(x): return 2*x ... >>> (square*twice)(1.5) 9.0 >>> addthree = mfunc(lambda x: x+3) >>> addfifteen = (addthree ** 5) >>> addfifteen(0) 15 >>> -- http://mail.python.org/mailman/listinfo/python-list