Well, I think what makes it clear to me is keeping in mind that this proposed functools.pipe is function composition in the first place, and applicability for instant piping, syntactic conveniences, etc, are secondary considerations.
You can think of pipe:
new_func = pipe(func1, func2)
# Is the same as:
new_func = lambda x: func2(func1(x))
# Or with full signature support of 1st callable:
new_func = lambda *args, **kwds: func2(func1(*args, **kwds))
Seems like a perfectly normal pattern. E.g.:
flat_array = [0, 1, 2, 3, 4, 5] # known shape - (3, 2)
array2d = batched(obj, 3)
transposed = list(zip(*array2d)
Similar would be completely acceptable in some iterator recipe.
Yup. I will collate some real life use cases if it comes to that, but the base real life use case is simply Function composition - Wikipedia
And potential use cases can be found in many places.
E.g. map first argument lambda composing 2 functions: Code search results · GitHub
And there are many different cases that function composition applies to. Of course, I don’t suggest that it should replace all of them, but it would definitely find its niches.
Having that said I would replace all of my lambda with it whenever possible as it has no disadvantages and some advantages:
- Performance - faster than
lambdain some cases - Serialisability
- Ability to inspect the chain of composed functions
Other reasons why others might want to use it:
- Inheritable class for which one can make operators
- Some might simply like it better