[Python-Dev] Function Operators

Christopher Olah christopherolah.co at gmail.com
Sun Jul 18 14:48:04 EDT 2010


Firstly, apologies for posting to the wrong list. Since I was fiddling
around with a modification to the language, if the implementation
details of something I'd never expect to get accepted, I'd thought
python-dev might be appropriate... In retrospect, it is fairly clear
that it was the wrong choice.

Secondly, the problem with using decorators is that it doesn't make it
so that all functions do this by default. If one is going to decorate
every function they use/declare, lambdas look preferable.

In any case, thank you for your help.

Christopher


On Sun, Jul 18, 2010 at 1:43 PM, Thomas Jollans <thomas at jollans.com> wrote:
> 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.co at 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
>>>>
>
>
>



More information about the Python-list mailing list