3 ms·
Clojure, for those unfamiliar with the language, unsurprisingly, does in fact allow for both 'for' and 'while' loops, and are part of the core language library.
by archgoon 6y ago
Clojure, for those unfamiliar with the language, unsurprisingly, does in fact allow for both 'for' and 'while' loops, and are part of the core language library.
https://clojuredocs.org/clojure.core/while https://clojuredocs.org/clojure.core/while
https://clojuredocs.org/clojure.core/for https://clojuredocs.org/clojure.core/for
And here are examples picked from a random repository of these constructs being used in the wild:
https://github.com/ring-clojure/ring/search?q=while https://github.com/ring-clojure/ring/search?q=while
What clojure does do is also provide a number of higher level control constructs, and, by the nature of the syntax of the language, puts them on the same level as 'while' and 'for', which themselves are part of a library, rather than baked into the language itself.
This can, of course, be done in other languages, using fluent interfaces.
https://en.wikipedia.org/wiki/Fluent_interface https://en.wikipedia.org/wiki/Fluent_interface
But is typically much more awkward and harder to compose. Also, you typically have to wrap expressions in lambdas.
- didibus 6y agoNot to be too nit-picky, but it doesn't actually have a for-loop. The for you linked to is not a for-loop but a for-each loop (simply called for). Well it is actually more restricting even then a for-each loop, as it maps over elements and can only return a collection of the same length as it iterates over. That said, you're correct it does have a pseudo while-loop. Though it will still force you to use a managed mutable container along with it, which is still safer than without. Also, it's a very ackward while-loop, as it doesn't support continue or break, that's because in reality it isn't a real while-loop, it's a fake while-loop built on top of a recursive loop. And for all other readers, it's true, Clojure doesn't disallow the use of less abstract less safe construct, it simply makes them more ackward to use and not the default and obvious choice. The reason for this is also something the article didn't bring up, but higher level safer abstractions often come with a performance cost. This is why most languages have escape hatches for whatever safety mechanism they provide, and why Rust lang loves to talk about "zero-cost" abstractions.
- dkersten 6y agoClojure's "for" is really a list comprehension function, but Clojure's "doseq" is more or less what you'd expect from a for loop (like Python's anyway or any other range-based for).
- didibus 6y agoPython's for isn't a for-loop either, it's a for-each loop also sometimes called a for-in loop. In that sense, neither Python nor Clojure have real for-loops. But Python gets much closer, because Clojure's doseq is similar to its while, it is actually syntax sugar for a recursive loop, and not an imperative loop. While Python's for is an imperative for-each loop, which supports the statements break, continue and return inside it.
- dkersten 6y agodoseq isn’t imperative because it doesn’t support break or continue? That doesn’t make sense.
- didibus 6y agoOh sorry, I meant to say iterative, not imperative. Basically all loops in Clojure are implemented in terms of recursion (loop/recur) and not jumps. Which is why there's no break, continue or return statements. Whatever categories you assign them in, I was more trying to show the differences between Python's for and Clojure's doseq. And also show that neither are your classic for-loop.
- dkersten 6y agoIt is iterative too, though: it iterates through an input sequence. > Whatever categories you assign them in, I was more trying to show the differences Fair enough. I take your overall point, I just don't think that not being a classic for-loop matters so much in practice, certainly not "most of the time" anyway.
- fulafel 6y agoSibling thread went into the nature of things in Clojure that are not "true" low level loop constructs, so just to point out, Clojure does also have loop/recur where you have more control on looping.