http://tomerfiliba.com/blog/Infix-Operators/ [fish-logo] tomer filiba low-level python hacker and author of RPyC, Construct and Plumbum. writes about python, algorithms, software architecture and whatever else comes to mind. blog about projects code etc recent posts Some Notes on 'D for the Win' D for the Win Construct Plus Plus A Python Crash Course for the Statically Typed Programmer Tales of a Stressed Kernel Pool Request TTYs: Never gets boring Academia Cartesian Tree-Product Travolta NXT A Survey of Construct 3 New Experiences Formal Logic Loads of Plumbum Plumbum Hits v1.0 Hypertext: In-Python Haml I, for one, welcome our Singularity overlord New Beginnings Splitbrain Python ReHelloWorld Javaism, Exceptions, and Logging: Part 2 kvlm mdbrym `l gyvs, p khd l mdbr bshkl Javaism, Exceptions, and Logging: Part 1 RPCs, Life and All Reed-Solomon Codec Some Notes on RPyC 3.2.x RPyC 3.2.2 Released The Future of Construct Introducing Plumbum - Shell Combinators Infix Operators in Python January 22, 2012 [rps] As you may already know, there are 3 kinds of operators calling-notations: prefix (+ 3 5), infix (3 + 5), and postfix (3 5 +). Prefix (as well as postfix) operators are used in languages like LISP/Scheme, and have the nice property of not requiring parenthesis -- there's only one way to read an expression like 3 5 + 2 *, unlike 3 + 5 * 2. On the other hand, it reduces code readability and the locality of operators and their arguments. This is why we all love infix operators. Now imagine I have a function, add(x,y), and I have an expression like add(add(add(5,6),7),8)... wouldn't it be cool if I could use infix notation here? Sadly though, Python won't allow you to define new operators or change how functions take their arguments... but that doesn't mean we have to give up! Haskell, for instance, allows you to define custom operators and set their precedence, as well as invoking "normal" functions as infix operators. Suppose you have a function f(x,y) -- you can invoke it like f 5 6 or 5 `f` 6 (using backticks). This allows us to turn our previous expression, add(add(add(5,6),7),8), into 5 `add` 6 `add` 7 `add` 8, which is much more readable. But how can we do this in Python? Well, there's this Cookbook recipe that provides a very nice way to achieving the same functionality in Python (adapted a little by me): from functools import partial class Infix(object): def __init__(self, func): self.func = func def __or__(self, other): return self.func(other) def __ror__(self, other): return Infix(partial(self.func, other)) def __call__(self, v1, v2): return self.func(v1, v2) Using instances of this peculiar class, we can now use a new "syntax" for calling functions as infix operators: >>> @Infix ... def add(x, y): ... return x + y ... >>> 5 |add| 6 11 Surrounding decorated functions with pipes (bitwise ORs) allows them to take their parameters infix-ly. Using this, we can do all sorts of cool things: >>> instanceof = Infix(isinstance) >>> >>> if 5 |instanceof| int: ... print "yes" ... yes And even curry functions: >>> curry = Infix(partial) >>> >>> def f(x, y, z): ... return x + y + z ... >>> f |curry| 3 >>> g = f |curry| 3 |curry| 4 |curry| 5 >>> g() 12 Ain't that cool? Please enable JavaScript to view the comments powered by Disqus. Content published under Creative Commons Attribution-ShareAlike 3.0 Unported License