clojure icon indicating copy to clipboard operation
clojure copied to clipboard

clojure.core/for examples

Open practicalli-johnny opened this issue 5 years ago • 0 comments

for is lazy and can be terminated

I'm iterating an integer vector twice checking for specific sum, but would like to stop once I find a first match. How would one do that?

(defn find-all-sums-to-2020 [expenses]
  (for [x expenses, y (rest expenses)
        :let [sum (+ x y)]
        :when (= sum 2020)]
    [x y]))(defn find-sum-to-2020 [expenses]
  (first (find-all-sums-to-2020 expenses)))

for is not a loop, but it is lazy, you can just stop consuming it there's also the :while arg (edited) what you are doing there is the normal way to stop it early

So (first) function will evaluate only the first result and therefore stop the inner for from continuing, is that what you are saying?

right, more precisely it never asks the inner for another value, so the value isn't calculated that's how laziness works - you don't stop it from the outside, you just never force it to execute, so it doesn't

the distinction becomes important when you have chunking (so asking for one item might make it decide to calculate 32 items) - you aren't forcing it to stop, you're asking it to calculate

practicalli-johnny avatar Jan 06 '21 10:01 practicalli-johnny