On Thu, Apr 05, 2018 at 06:24:25PM -0400, Peter O'Connor wrote:
Well, whether you factor out the loop-function is a separate issue. Lets say we do:
smooth_signal = [average = compute_avg(average, x) for x in signal from average=0]
Is just as readable and maintainable as your expanded version, but saves 4 lines of code. What's not to love?
Be careful about asking questions which you think are rhetorical but aren't. I can think of at least half a dozen objections to this:
- I'd have no idea what it means without the context of reading this thread.
- That you call it "MapReduce" while apparently doing something different from what other people call MapReduce:
- That it uses = as an expression, and the keyword `from` in a weird way that doesn't make sense to me.
- The fact that it requires new syntax, so it isn't backwards compatible. Even if I loved it and your proposal was accepted, I couldn't use it for at least two years. If I'm writing a library that has to work with older versions of Python, probably not for a decade.
- That there's no obvious search terms to google for if you come across this in code and don't know what it means ("that thing that looks like a list comprehension but has from in it").
(And yes, before you object, list comps have the same downside.)
- The fact that this uses a functional idiom in the first place, which many people don't like or get. Especially when they start getting complex.
If you haven't already already done so, you ought to read the numerous threads from last month on statement local name bindings:
The barrier to adding new syntax to the language is very high. I suspect that the *only* chance you have for this sort of comprehension will be if one of the name binding proposals is accepted. That will give you *half* of what you want:
[(compute_avg(average, x) as average) for x in signal]
[(average := compute_avg(average, x)) for x in signal]
only needing a way to give it an initial value. Depending on the way comprehensions work, this might be all you need:
average = 0 smooth_signal [(average := compute_avg(average, x)) for x in signal]
assuming the := syntax is accepted.
An alternative would be to push for a variant of functools.reduce that yields its values lazily, giving us:
smooth_signal = list(lazy_reduce(compute_avg, x, 0))