[Python-ideas] @partials = decorators

Ian Cordasco graffatcolmingov at gmail.com
Sat Feb 8 23:46:06 CET 2014


On Sat, Feb 8, 2014 at 4:41 PM, Ron Adam <ron3200 at gmail.com> wrote:

>
>
> On 02/08/2014 11:55 AM, Ron Adam wrote:
>
>>
>> On 02/06/2014 05:14 AM, Nick Coghlan wrote:> On 6 February 2014 20:34, Ron
>> Adam<ron3200 at gmail.com>  wrote:
>>
>
>  Hmmm...  Could the @ syntax be generalised in this case?
>>
>>       @foo(func)    Partial waiting for rest...
>>
>>
>> Then the more general case...
>>
>>       a_op = @foo(op)   # Partial waiting for rest.
>>       a_x = @a_op(x)
>>       a = a_x(y)
>>
>> That would be cool, unifies decorators and partials with decorator syntax!
>>
>>
>> I think it's even back-words compatible if you allow this equivalency.
>>
>>      def foo(x, y):
>>         ...
>>
>>      @foo(x, y)  ==  foo(x, y)    # An identity partial
>>
>>
>> And the decorator case becomes...
>>
>>      @partial
>>      def func():
>>        ...
>>
>> And we get this equivalency as well....
>>
>>      @partial == partial       # I think this could work.
>>
>>
>> The reason these things are interesting to me is that, I've been thinking
>> about the order of function arguments and if there could be some
>> generalised concepts that can be applied to that problem.  Being able to
>> use normal functions effectively in these ways,  (with partials, and
>> continuations), is related to the order of the arguments and how they are
>> commonly used.
>>
>
> Here's a rough python version...  It currently gets tripped up on optional
> arguments, but it does work for non optional cases.
>
> I think a builtin, along with the new signatures capabilities could fix
> those cases.
>
> (and to address Stevens conserns.. It would be explicit and won't effect
> the beginner cases if you don't use the @...
>
> In this example I'm using P.  And a builtin function could work just as
> well.  Although I would like the @ syntax to just work without the function.
>
> It's just a first attempt, with probably a lot of issues to be handled
> still, but it does show it's doable.
>
> Cheers,
>    Ron
>
>
> #-------------------------------
>
> # A builtin could do this much better.
> class P:
>     def __init__(self, f, *args, **kwds):
>         self.f = f
>         self.args = args
>         self.kwds = kwds
>     def __call__(self, *args, **kwds):
>         args = list(self.args) + list(args)
>         kwds.update(self.kwds)
>         try:
>             return self.f(*args, **kwds)
>         except TypeError:
>             return self.__class__(self.f, *args, **kwds)
>
>
> #  This the easy way to write decorators!!!  :-)
> @P
> def deco(f, *args):
>     print("Got: ", args)
>     return f(*args)
>
>
> # And a partial function example with it.  :-)
> @P
> @deco
> def foo(x, y, z):
>     return x + y + z
>
> print(foo(1, 2, 3))
> print(foo(1, 2)(3))
> print(foo(1)(2)(3))
> #-------------------------
>
> The output...
>
> ra:~ >python3 partial_deco.py
> Got:  ()
> Got:  (1, 2, 3)
> 6
> Got:  (1, 2)
> Got:  (1, 2, 3)
> 6
> Got:  (1,)
> Got:  (1, 2)
> Got:  (1, 2, 3)
>
> 6
>

I experimented with something similar over at
https://github.com/sigmavirus24/curryer but never released it. It's fairly
well tested but I'm not sure I'd use it for anything other than a toy.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140208/1d960581/attachment-0001.html>


More information about the Python-ideas mailing list