reset password
Author Message
jpatel77
Posts: 44
Posted 21:43 Mar 12, 2019 |

I was trying to use Dr Abbott's code that allows me to use a specific operator (@ or *) for function composition. However, since the resultant of these operators returned a function, I could not chain multiple compositions (like add1 . add2 . add1 in haskell :) ). So I made a minor change (wrapped the lambda) to the original code that allows us to chain multiple compositions too. Just replace these methods in the existing code:

def __matmul__(self, other):
    return Composable(lambda *args, **kw: self.func(other.func(*args, **kw)))

def __mul__(self, other):
    return Composable(lambda *args, **kw: self.func(other.func(*args, **kw)))

print((add1 @ add2 @ add2)(5), (add1 * add2 * add2)(5)) # => 10 10

Good thing is, this does the composition from right to left, just exactly what we want.

I have one question though. There is one line update_wrapper(self, func) inside __init__ . What is the purpose of that line? I read the document but could not understand what is the impact of that line in our code. I even commented that line out, and behavior is just the same as before. 

 

Last edited by jpatel77 at 01:22 Mar 14, 2019.
rabbott
Posts: 1649
Posted 23:31 Mar 12, 2019 |

Very good! I hadn't noticed the problem--and don't even have the time now to look at your fix. But I see that it works.

The call to update_wrapper copies attributes from the original function to the wrapped function. It has no effect on the wrapped function's functionality.

Try 

print(add1.__name__)

with and without update_wrapper.

jpatel77
Posts: 44
Posted 23:44 Mar 12, 2019 |

Oh I see. That makes sense now.