On Thu, Aug 10, 2017 at 11:45 PM, Steve D'Aprano <steve+pyt...@pearwood.info> wrote: > On Fri, 11 Aug 2017 08:49 am, Ben Finney wrote: > >> The comprehension encourages thinking in sets: an operation that takes a >> collection as input, and emits a different collection, through one >> conceptual operation. >> >> Adding ‘while’ in there encourages thinking not in terms of a single >> set-based operation, but an iteration of separate operations. That >> confuses the model, and I no longer have a coherent model about which to >> reason what the syntax might mean. > > > Sorry Ben, you've completely lost me. > > If you had said that tradition functional style operations such as: > > map(func, iterable) > > filter(pred, iterable) > > "encourages thinking in sets: an operation that takes a collection as input, > and > emits a different collection, through one conceptual operation" > > then I would completely agree with you. I agree that is absolutely true: > traditional functional programming idioms encourage thinking of looping as a > single conceptual operation. For simplicity, both map() and filter() are often > implemented as a for loop that operates on one item at a time, in order, but > conceptually the map and filter could operate in parallel on all items at > once. > > But that's not the case for list comprehensions and generator expressions > (which > use almost exactly the same syntax). The sequential, one-item-at-a-time nature > isn't a mere implementation detail, it is an essential part of the semantics > of > the comprehension. > > Comprehension syntax makes the sequential loop explicit: the loop is right > there > in the syntax: > > [expr for x in iterable]
This is a peculiarity of Python. Here's a list comprehension in Haskell, which has supported them since version 1.0 in 1990, much longer than Python: [x * 2 | x <- L, x * x > 3] The same thing in Erlang: [2*X || X <- L, X*X > 3] C#: var ns = from x in L where x*x > 3 select x*2; (Note "from", not "for") Scheme: (list-ec (: x 100) (if (> (* x x) 3)) (* x 2)) The grand-daddy of them all, NPL (which actually called them "set comprehensions" after mathematics): setofeven(X) <= <:x: x in X & even(x) :> Nothing about any of these suggests a loop or a requirement for serial processing. Granted, there are other languages I've not listed here that use loop syntax like Python. >> Though ‘for’ is used elsewhere in Python to mean iteration, ‘for’ also >> has strong connotation in mathematics for set-based operations (“the >> result is foo for all bar, if baz”). So the same confusion doesn't >> occur: this is a comprehension which is about set-based thinking, which >> is supported by all the semantic connotations of the syntax. > > I don't understand this. I *think* what you're saying is "I have internalised > the explicit for-loop and think of it as a filter plus a map and no longer > think of it as a for-loop", but I'm not sure. More like, "Python has externalized the list comprehension as a for loop despite the rich tradition to the contrary." -- https://mail.python.org/mailman/listinfo/python-list