Skip to content

Instantly share code, notes, and snippets.

@EEmery
Last active May 18, 2021 07:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EEmery/f48229b3d05754a34f95c130e1e0f157 to your computer and use it in GitHub Desktop.
Save EEmery/f48229b3d05754a34f95c130e1e0f157 to your computer and use it in GitHub Desktop.
Threading Functions with Python (Similar to Clojure's Threading Macro/Arrow Macro)
# Author: Eduardo Emery
#
# The function `thread_functions` below implements in Python a Clojure macro
# called "Threading", also known as "Arrow Macro". As explained in the guide,
# the macro "convert nested function calls into a linear flow of function
# calls, improving readability" (https://clojure.org/guides/threading_macros).
#
# The goal of `thread_functions` is to sequentially execute functions from a
# starting point, to improve readability. It receives an initial set of
# parameters and a set of functions. The initial parameters are applied to
# the first function, the result is then applied to the next function and so
# on.
#
# The presented function can be applied to multiple or even only one function.
# It is also capable of handling functions that return iterables.
#
# Below `thread_functions`, it is implemented a few very simple functions
# that can be used to demonstrate the use. At the end, the variable `r` holds
# the final result of applying it.
def thread_functions(*init_args):
def execute_functions(*functions_list):
x = functions_list[0](*init_args)
for func in functions_list[1:]:
try:
x = func(*x)
except TypeError:
x = func(x)
return x
return execute_functions
# Use case example:
def add_1(x):
return x + 1
def x_and_1(x):
return x, 1
def reduce_two(x, y):
return x + y
def add_y(y):
return lambda x: x + y
r = thread_functions(1)(
add_1,
x_and_1,
reduce_two,
add_1,
x_and_1,
reduce_two,
add_y(2))
print(r)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment