[Python-ideas] Elixir inspired pipe to apply a series of functions
Jan Wrobel
wrr at mixedbit.org
Thu Jun 13 20:06:10 CEST 2013
Hello,
I've recently stumbled upon a Joe Armstrong's (of Erlang) blog post
that praises an Elixir pipe operator:
http://joearms.github.io/2013/05/31/a-week-with-elixir.html
The operator allows to nicely structure code that applies a series of
functions to transform an input value to some output.
I often end up writing code like:
pkcs7_unpad(
reduce(lambda result, block: result.append(block),
map(decrypt_block,
pairwise([iv] + secret_blocks))))
Which is dense, and needs to be read backwards (last operation is
written first), but as Joe notes, the alternative is also not very
compelling:
decrypted_blocks = map(decrypt_block, pairwise([iv] + secret_blocks))
combined_blocks = reduce(lambda result, block: result.append(block))
return pkcs7_unpad(combined_blocks)
The pipe operator nicely separates subsequent operations and allows to
read them in a natural order without the need for temporary variables.
Something like:
[iv] + secret_blocks |> pairwise |> map, decrypt_block |> \
reduce, lambda result, block: result.append(block) |> \
pkcs7_unpad
I'm not sure introducing pipes like this at the Python level would be
a good idea. Is there already a library level support for such
constructs? If not, what would be a good way to express them? I've
tried a bit an figured out a following API
(https://gist.github.com/wrr/5775808):
Pipe([iv] + secret_blocks)\
(pairwise)\
(map, decrypt_block)\
(reduce, lambda result, block: result.append(block))\
(pkcs7_unpad)\
()
The API is more verbose than the language level operator. I initially
tried to overload `>>`, but it doesn't allow for additional arguments.
It is also somehow smelly, because `()` returns a different type of
value if it is invoked without an argument. Any suggestions how this
could be improved?
Best regards,
Jan
More information about the Python-ideas
mailing list