6 ms·
I think the idea is that a loop in many cases doesn't express your intent. What you might want to do is to "set the property 'foo' to 'bar' on all items in an a
by mekkkkkk 5y ago
I think the idea is that a loop in many cases doesn't express your intent. What you might want to do is to "set the property 'foo' to 'bar' on all items in an array".
What you might write is "create a variable and set it to zero, then iterate that variable as long as it's smaller than the number of items in the array, and do this between each iteration: take the item at the variables index and set its property 'foo' to 'bar'".
Of course any programmer will instantly see what's going on, but that's not from clarity but from prior experience and familiarity.
- rand_r 5y agoThis seems perfectly clear. for item in array: item.foo = bar
- maest 5y agoarray.'foo = bar Is clearer. Or, at least, would be, if one were accustomed to the (fictitious) adverb '. There's no need for all the ceremony around specifying "for x in y: <some function describing what to do with x>"
- deleted 5y ago[deleted]
- jcelerier 5y agoIt isn't. "For x in y" is literally what we say when speaking as humans unlike that quote thing.
- maest 5y agoI don't find that to be a convincing argument, because it suggests we should write "foo applied to bar" instead of "foo(bar)" in your code. It's just notation, just because it's new, doesn't mean it's bad. There's maybe an argument to be made about there being _too much_ notation to learn, but notation makes sense for fundamental concepts (which loops clearly are). Notation is important. It condenses thought and refines the concepts, making them more visible. In fact, some valid mathematical theory came about from figuring out proper notation and then playing around with it, sometimes in non-rigorous (albeit intuitive ways). e.g. consider how physicists wildly move dx and dy around in differential equations (much to mathematicians' dismay) Ancient greek geometry textbooks were written in long form: "the square of the hypotenuse side is equal to the sum of squares of the other two sides". We can all agree that the "a^2+b^=c^2" notation is better.
- mekkkkkk 5y agoThat's an awkward way to speak. "Take each of my gizmos, then put it in the gizmo box" for gizmo in gizmos: gizmo.put_in_box() vs "Put all my gizmos in the gizmo box" gizmos.'put_in_box()
- hinkley 5y agoOr “paint all my gizmos red”.
- RHSeeger 5y agoYour first statement is unambiguous. Your second sentence is ambiguous. It could mean 1. Put all of my gizmos in a single gizmo box, together, OR 2. Put each of my gizmos in its own gizmo box
- mekkkkkk 5y agoAre you talking about the pseudo code or the readable sentences? I hope my point comes across even if there's some linguistic nuance I'm missing.
- RHSeeger 5y agoI'm talking about the readable sentences. The one you labelled as "an awkward way to speak" was unambiguous. The phrasing it seems you preferred was ambiguous. Personally, if I have to write the sentence down and the consumer of the sentence can't ask questions to clarify, I prefer the unambiguous wording. Ie, say exactly what you mean or you may not get what you want. > A wife asks her husband, a software engineer, “Could you please go shopping for me and buy one carton of milk, and if they have eggs, get 6!” A short time later the husband comes back with 6 cartons of milk. The wife asks him, “Why the hell did you buy 6 cartons of milk?” He replied, “They had eggs.”
- jbluepolarbear 5y agoThe second code doesn’t put all the gizmos in the gizmo box. That’s your intent, but not the reality. All that syntax says is apply function to all elements. It is syntactic sugar for the code you put above; it’s a for each loop.
- hinkley 5y agoI think you will find that those “humans” you’ve been hanging out with are all programmers or mathematicians. “Humans” don’t talk like this. Most of them have never heard of set theory.
- photochemsyn 5y agoNot necessarily. The later expression might be more common though: "For every item in this truck, remove that item and put in in the warehouse." "While this truck is not empty, keep unloading items to the warehouse."
- jcelerier 5y agoMaybe it's just my mother tongue, but "pour chaque entrée dans la base de données, prends la moyenne et affiche-la" sounds pretty ok (literally in English, for each entry in the database, take the average and print it)
- deleted 5y ago[deleted]
- nickjj 5y ago> "For x in y" is literally what we say when speaking as humans unlike that quote thing. What about: "Can you unload the truck?" The current context gives us implied knowledge that we're talking about the items in the truck and where it's getting unloaded to, such as a warehouse if we're near a warehouse door. We only expand on that verbally when we need to such as "Can you throw out the empty boxes in the truck?". I think this is why programming is nonintuitive, you have to include important steps with very precise words that often go unsaid. Even "throw out" wouldn't convert to the correct intent if a computer executed that statement as is. You would end up literally throwing the empty boxes out of the truck instead of putting them into a dumpster or garbage can (the likely intent based on this example).
- rand_r 5y agoThat does look pretty nice for this example. I think the problem with it is that introduces too much new syntax that you have to memorize. The beauty of a for loop is that you can do _anything_ with it. And it all works with the same syntax. for item in array: item.foo = bar for item in array: item.foo = item.foo * 2 for item in array: my_bar_func(item.foo) If you special case certain uses of a for loop and add language syntax around it, of course you can make code terser. But it's nice to rely on a small set of very generally useful syntax.
- pasquinelli 5y agodepends on how many different types of loops there really are. now _that_ would make an interesting article.
- dragonwriter 5y ago> The beauty of a for loop is that you can do _anything_ with it. That’s also the curse: a generic loop can be almost anything (looping over an iterable can't quite express anything, but it can do a lot), so seeing it tells you nothing. C-style loops can do more (literally anything), and loop-over-iterable syntax has been generally preferred where it can be applied because it tells you more (even if only a little more) about what the block of code is doing up-front. Constructs that are more specific than loop-over-iterable can be correspondingly more expressive.
- kaidon 5y ago> all the ceremony It's not _that_ verbose -- the trade off in clarity is pretty stark IMO. In practice many people move between languages frequently daily. This syntax and semantics it provides are fairly different from that of popular languages.
- pletnes 5y agoWith numpy, this would just be item.foo [:] = bar. Much more readable to me - the whole «for» thing is superfluous.
- maest 5y agoNeat trick. Didn't know about it. In pandas it would be item.foo = bar, _as long as_ bar isn't something you can iterate over.
- pletnes 5y agoNumpy is all about this. E.g y = np.sin(x). X and y are arrays and you can think of them as «all values of x and y» or «the physical variables x and y»
- jbluepolarbear 5y agoThese comments from people who don’t write software and only use programming for data science. Numpy is superfluous for anyone that doesn’t need it.
- kergonath 5y agoIndeed. Also, this notation was lifted straight from Fortran 90 (which itself got it from Matlab, Algol, and the primitive slicing that was possible in older FORTRANs). The idea that a concise notation is helpful for the concept of “put a thing in all the buckets of an array” really is quite old. It does make a lot of sense.
- convolvatron 5y agothere is also a pretty big difference in what a compiler can do if we express the computation as a set of operations that transform the sets rather than a little rats nest of mutations and jumps. if you wanted to vectorize the set/jmp version, you'd be trying to tease apart a problem which is undecidable in the limit. vectorizing the transformer version is trivial.
- kristjansson 5y agoThere’s also the reverse: writing as a loopless operation forces the programmer to write code that can be easily vectorized.
- FalconSensei 5y agoIn python, the way you write this is more similar to how we express the intent, using dict/list comprehension. But the thing is, for anything more complex that your example, the comprehension notation is harder to read and make changes if you are not really used to it
- BeFlatXIII 5y agoPythonic for loops are more or less `for item in list: <block of code>`. Sill no manual management of array indices.
- dagmx 5y agoThat's only true for languages that don't support looping over an iterable directly. Or if you need the index while iterating too. Python, Rust, Swift, C++, ObjC and more all support the equivalent of a foreach loop today. That perfectly shows intent
- jakear 5y agoAgreed, and based on the list here: https://en.m.wikipedia.org/wiki/Foreach_loop https://en.m.wikipedia.org/wiki/Foreach_loop the only popular language without for each is C.
- CuriousCosmic 5y agoAnd even then, a decent number of data structures provided in headers on *nixes provide for each macros.
- tomtomtom777 5y agoTrue. It is possible though for a language to avoid these iteration constructs as if they are needless plumbing as well. Consider the elegant type system of the XQuery language: In XQuery, the root type is a flattened sequence. Flattened means not just that [1, [2, 3]] is flattened to [1, 2, 3], but also the a single object 42 is equivalent to a sequence of one object [42]. This means that if I write: declare function local:prefixName($name) { fn:concat("prefix-", $name) } I can invoke it with a single name or a sequence of names without any explicit iteration. It has drawbacks but using XQuery certainly highlights how much code we normally waste dealing with "things" and "sequences of things" separately. (Than again working with XQuery also highlights how much code one can waste dealing with XML namespaces :)
- mekkkkkk 5y agoAdmittedly it's a worst case scenario, but the broader point still holds even with a foreach. You are still picking out each item individually instead of operating on the collection which is what you intend to do. You write "do this for every apple: peel it", instead of "peel the apples".