
On Tue, Jun 29, 2021 at 05:17:36PM +1000, Chris Angelico wrote:
What if you loop over the values in the range(0, 10) but skip all of the odd numbers? Is that two concepts too?
Of course it is. Think about somebody who knows about looping, and knows what range() does, but has no concept of odd numbers. (Perhaps a very precocious child.) They would easily understand `for i in range(0, 10, 2)` but have no idea how to skip odd numbers. If that example is too implausible for you, how about skipping the antisigma numbers? https://oeis.org/A024816 Going back to odds and evens, you even described it as two steps: 1. loop over the values in the range(0, 10) 2. but skip all of the odd numbers. That's two distict steps. You are correct that it gives the same practical result as the single step: 1. loop over the values in the range(0, 10, 2) but that's okay. There are many operations which are functionally equivalent (they give the same results) but are conceptually different: * the number of days in a week; * the average of 6 and 8; * a quarter of 28; * the fourth prime number; * the number of Dwarves in the story of Snow White; * the number of Deadly Sins in christian theology; * the number of examples I used to illustrate this. As a programmer, you of course are perfectly entitled to change your code to a functionally equivalent but conceptually distinct operation, if you care more about the results than how you get the results. (E.g. loop unrolling changes something which is conceptually a loop into something which is conceptually *not* a loop, since they are functionally equivalent.)
Because we have an easy way to spell that: range(0, 10, 2).
Sure. But why do we care so much about this trivial special case? Remember that the condition can be as general as we like. How about looping over numbers between 0 and a trillion whose bit count (number of 1s in binary) is a perfect number, except for those which are prime? More practically, if you have some arbitrarily complicated iterable, and you wish to skip some of those items according to some arbitrarily complicated condition known only at runtime: for url in filter( lambda url: url not in skiplist, map(make_url, webspider.follow_all(depth=10000)) ): if (url not in seen and is_image(url.filetype) and image:=Image.read(url) and image.detect_faces(**params).match_any(*targets) ): process(url) do you still think that's conceptually a single operation? "Process the URLs I want, duh!" *wink* -- Steve