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

Idea: Compose class should be iterable #553

Open
ZeroBomb opened this issue Sep 25, 2022 · 2 comments
Open

Idea: Compose class should be iterable #553

ZeroBomb opened this issue Sep 25, 2022 · 2 comments

Comments

@ZeroBomb
Copy link

ZeroBomb commented Sep 25, 2022

It would be really nice to be able to iterate all the funcs in compose, without having to combine the first and funcs properties. It would let you immediately use Compose objects as iterables in the itertoolz functions.

For an example, consider the simple logging strategy outlined in my gist here:
https://gist.github.com/ZeroBomb/8ac470b1d4b02c11f2873c5d4e0512a1

As written, I need to define this somewhat extraneous function

def get_funcs(composition):
    return (composition.first,)+composition.funcs

in order to map over those functions and re-compose:

@curry
def interleave_map(func, items):
    # [1,2,3] -> [func(1), 1, func(2), 2, func(3), 3]
    return interleave([map(func, items), items])

# define a debug function that interleaves logging funcs inbetween each func in an existing composition
debug = compose_left(get_funcs, interleave_map(passthru_log), star(compose_left))

if the Compose class were iterable, I could completely eliminate the get_funcs function, and comfortably feed the compose object directly into interleave:

def debug(composition):
    return compose_left(*interleave_map(passthru_log, composition))
@mentalisttraceur
Copy link

mentalisttraceur commented Oct 27, 2022

My compose exposes all composed callables as the .functions attribute, in case that helps.

@ZeroBomb
Copy link
Author

Some other observations on iterable compositions:

Idempotence

There is a sense in which compose is idempotent:

compose(*compose(f1, f2, f3)) == compose(f1, f2, f3)

Is that good? I don't know, but it seems profound.

Trivial mapping over compositions

It is now basically trivial to update the functions inside compositions you've already made

def log(func):
    def inner(*args, **kwargs):
        print(f"callin' {func.__name__}")
        return func(*args, **kwargs)
    return inner

compose(*map(log, preexisting_composition))

Suggests future direction for combining compositions

It seems pretty straightforward to propose some kind of helper function to make this a little more straightforward

compose(*composition2, *composition1)

but it's not that bad as-is.

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