The pros/cons of generators

This is strange request. I am not a Python developer but instead a JavaScript developer. However, Python is the only other language I know that has generators. In the JS community generators are not well received as far as I can tell.

I personally find them beautiful, easy to understand, and maintain. But when I use them in JavaScript I get lots of negative feedback. Visceral opposition and even attempts to defend my choices are summarily dismissed as poor opinion.

Since Python implemented generators long before JavaScript did I would love to hear from this community what your thoughts are on generators. Is the procedural style of yield statements, loops over iterators, and list comprehension worth the effort? Or is the functional programming style now the only path?

What technical advantages do generators offer that array methods do not? What experiences have others had using generators? Are they more a neat trick but not practical in production code? Or are they a miss-understood game changer?

Most documentation, scuttlebutt, and blogs only offer technical how to and lack any information on the why to use, when to use, and when not to use. How can I help articulate the good reasons for generators when there is very little blog posts and documentation about them?

Thanks in advance.

There are LOTS of advantages to generators, but it all depends on context. What are the generators doing? If they’re nothing more than lazy arrays, their only benefit is, well, their laziness - it’s a tradeoff in performance and space compared to eagerly computing the full array. But there are a few other ways they can be used. For example, you can have an infinite-length generator, capable of being iterated over until you find what you need, without worrying about pre-planning your input size. The behaviour of subsequent “array elements” can be changed by signalling the generator (since you can send a value into the generator as well as getting one out of it).

There’s definitely a much stronger cultural acceptance of generators in Python than there is in JavaScript, and I suspect this is partly because they’ve been around in Python much longer; but when used correctly, they are extremely elegant ways of organizing coroutines, or deferring (or even removing the need for) expensive calculations. When you get negative feedback for using them, try to figure out why - is it that an array method would be just as clean, just as simple, and potentially faster? Then use the array method. But is it because, even though a generator is better, the other person just isn’t as familiar with them? Then stick to generators and help to educate people :slight_smile:

Generators (or similar concepts) exist in a number of languages. According to Generator (computer programming) - Wikipedia they have been around since 1975, although among languages that are still in use today, Python would be the oldest. They come by various names; personally, I’m tickled by Pike’s choice to call them “continue functions”, since they’re functions that… return… but still continue :smiley: They’re incredibly useful in a small set of situations, and somewhat useful in a much broader set, so my personal recommendation is: Go ahead and keep using them. Haters gonna hate.

1 Like

I wrote the PEP that introduced genrators to Python, so I may be too close to it to be objective.

I cut my teeth on generators in the Icon language, in which every expression “is a generator”. For example, the literal “2” is a generator with a result sequence of length 1, the single integer 2. The expression “x < y” is a generator that yields y if x is less than y, or fails (yields no result) if x >= y. So Python’s chained comparisons, like “x < y < z”, seem to work the same way in Icon, but for very different reasons.

Icon is typically used for non-numeric computation, and especially for combinatorial search algorithms (Icon was inspired by trying to expose the innards of SNOBOL4’s string pattern-matching machinery for general algorithmic use). Simple generators are just plain the bee’s knees for that, for reasons partly explained in the cited PEP.

I still use generators every day in Python. They’re a delight! Curiously. I never had much use for the fancier “async” extensions, and seemingly nobody had much use for Icon’s fancier full-blown coroutine extensions either (even among Icon’s developers, coroutines were viewed as an academic research project).

As to the JS community’s opinion, Matthew 7:6 comes to mind:

Give not that which is holy unto the dogs, neither cast ye your pearls before swine, lest they trample them under their feet, and turn again and rend you.