On 05/09/2015 06:45 PM, Andrew Barnert via Python-ideas wrote:
On May 9, 2015, at 08:38, Ron Adamron3200@gmail.com wrote:
> > >
On 05/09/2015 03:21 AM, Andrew Barnert via Python-ideas wrote:
>> >I suppose you could write (root @ mean @ (map square)) (xs),
Actually, you can't. You could write (root @ mean @ partial(map, square))(xs), but that's pretty clearly less readable than root(mean(map(square, xs))) or root(mean(x*x for x in xs). And that's been my main argument: Without a full suite of higher-level operators and related syntax, compose alone doesn't do you any good except for toy examples.
How about an operator for partial?
root @ mean @ map $ square(xs)
I'm pretty sure that anyone who sees that and doesn't interpret it as meaningless nonsense is going to interpret it as a variation on Haskell and get the wrong intuition.
Yes, I agree that is the problems with it.
But, more importantly, this doesn't work. Your square(xs) isn't going to evaluate to a function, but to a whatever falling square on xs returns. (Which is presumably a TypeError, or you wouldn't be looking to map in the first place). And, even if that did work, you're not actually composing a function here anyway; your @ is just a call operator, which we already have in Python, spelled with parens.
This is following the patterns being discussed in the thread. (or at least an attempt to do so.)
The @ and $ above would bind more tightly than the (). Like the doc "." does for method calls. But the evaluation is from left to right at call time. The calling part does not need to be done at the same times the rest is done. Or at least that is what I got from the conversation.
f = root @ mean @ map & square result = f(xs)
The other examples would work the same.
Actually I'd rather reuse the binary operators. (I'd be happy if they were just methods on bytes objects BTW.)
compose(root, mean, map(square, xs))
Now you're not calling square(xs), but you are calling map(square, xs), which is going to return an iterable of squares, not a function; again, you're not composing a function object at all.
Yes, this is what directly calling the functions to do the same thing would look like. Except without returning a composed function.
And think about how you'd actually write this correctly. You need to either use lambda (which defeats the entire purpose of compose), or partial (which works, but is clumsy and ugly enough without an operator or syntactic sugar that people rarely use it).
The advantage of the syntax is that it is a "potentially" (a matter of opinion) alternative to using lambda. And apparently there are a few here who think doing it with lambda's or other means is less than ideal.
Personally I'm not convinced yet either.