Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Easier way to chain futures ignoring return value #154

Open
rohanpm opened this issue Aug 29, 2019 · 0 comments
Open

Easier way to chain futures ignoring return value #154

rohanpm opened this issue Aug 29, 2019 · 0 comments

Comments

@rohanpm
Copy link
Owner

rohanpm commented Aug 29, 2019

It seems there's often a need to write code which:

  • chains some steps A, B, C in sequence
  • but doesn't need to keep the returned values from each step

A good example is doing some sequence of operations on an object via future-returning method calls, where each step doesn't need any arguments provided by earlier steps, e.g. x.do_foo() -> x.do_bar(), x.do_baz()

Right now, this can be achieved by code like this which is relatively awkward:

# Helper needed to avoid lazy binding
def return_value(x, _):
  return x

futures = []
for x in items:
  f = x.do_foo()
  # don't care what do_foo returned, make it return the x
  f = f_map(f, return_value(x))
  # then do next step
  f = f_flat_map(f, lambda obj: obj.do_bar())
  # repeat same dance again...
  f = f_map(f, return_value(x))
  f = f_flat_map(f, lambda obj: obj.do_baz())
  futures.append(f)

This is much uglier than it should be. Let's try to come up with some helper functions or something else to make this cleaner.

Possible ideas:

# f_chain(fn1, fn2, ...) => Future[return value of last function]
# chain a series of future-returning functions 
# should first argument be a function, or a future?
futures = []
for x in items:
  f = f_chain(
    x.do_foo,
    x.do_bar,
    x.do_baz)
  futures.append(f)
# f_thread(x, fn[x]1, fn[x]2, ...) => Future[return value of last function]
# thread a value through a series of functions
# note: try to think of a better name than "thread" due to clash with the other common meaning
futures = []
for x in items:
  # lambdas here still a bit ugly:
  f = f_thread(x,
    lambda x: x.do_foo(),
    lambda x: x.do_bar(),
    lambda x: x.do_baz())

  # On the other hand, if caller uses standalone functions, it works much better
  f = f_thread(x, do_foo, do_bar, do_baz)

  futures.append(f)

A major concern here is avoiding the gotcha of lazy binding of a loop's variable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants
@rohanpm and others