[Python-Dev] Serial function call composition syntax foo(x, y) -> bar() -> baz(z) (original) (raw)

Bengt Richter bokr at oz.net
Fri Feb 17 22:59:19 CET 2006


Cut to the chase: how about being able to write

baz(bar(foo(x, y)),z)

serially as

foo(x, y) -> bar() -> baz(z)

via the above as sugar for

baz.__get__(bar.__get__(foo(x, y))())(z)

?

I.e., you'd have self-like args to receive results from upstream. E.g.,

def foo(x, y): return 'foo(%s, %s)'%(x,y) ... def bar(stream): return 'bar(%s)'%stream ... def baz(stream, z): return 'baz(%s, %s)'%(stream,z) ... x = 'ex'; y='wye'; z='zed'

then (faked)

foo(x, y) -> bar() -> baz(z) 'baz(bar(foo(ex, wye)), zed)'

would do (actual)

baz.get(bar.get(foo(x, y))())(z) 'baz(bar(foo(ex, wye)), zed)'

(or if the callable has no get, use new.instancemethod methodology behind the scenes)

This is to provide an alternative to serial composition of function calls as methods of returned objects, which sometimes looks nice, but may have strange coupling of types and functionality. E.g. you could define classes to be able to write the above as

foo(x, y).bar().baz(z)    

and that's effectively what is being done by the -> notation. The get stuff is really just on-the-fly bound method generation without passing the instance class argument. But -> allows the composition without creating knowledge coupling between the foo, bar, and baz sources. It just has to be realized that this way of composition works via the first argument in passing through prior results.

BTW, note that in the above foo(x, y) is just the first expression result being fed into the chain, so a constant or any expression can be the first, since it just becomes the argument for the innermost nested call. I.e.,

'abcd' -> binascii.hexlify()

for >>> new.instancemethod(binascii.hexlify, 'abcd', str)() '61626364'

Note that it's valid to leave off the () -- IOW simply, a->b is sugar for b.get(a) (or the instancemethod equivalent)

(faked) 'expr' -> baz <bound method ?.baz of 'expr'> (actual)

baz.get('expr') <bound method ?.baz of 'expr'>

and then

baz.get('expr')('zee') 'baz(expr, zee)'

What do you think?

Regards, Bengt Richter



More information about the Python-Dev mailing list