On Sat, Feb 8, 2014 at 4:41 PM, Ron Adam
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
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.