Welcome! Please see the About page for a little more info on how this works.

0 votes
in Clojure by

I am beginner programmer & have been playing around with Clojure and experimenting alot.
Can someone tell me what the "for" operator does in this context and the other args relationship ? ty in advance

(def xbox {:bushido ["only on PS" {:country :notavailable}]
:parappa "only on PS" :oni "only on PS"})

(def playstation {:bushido ["available" {:country :japan}]
:parappa "classic" :oni "need to play"})

(for [{[_ x] :bushido} [xbox playstation]] x)

2 Answers

+1 vote
by

Running this at the repl:

user> (def xbox {:bushido ["only on PS" {:country :notavailable}] 
                 :parappa "only on PS" :oni "only on PS"})
;; => #'user/xbox
user> (def playstation {:bushido ["available" {:country :japan}] 
                        :parappa "classic" :oni "need to play"})
;; => #'user/playstation
user> (for [{[_ x] :bushido} [xbox playstation]]
          x)
;; => ({:country :notavailable} {:country :japan})
user> 

We can see what this actually does. And yes, as mentioned in the other answer, this is a no-op because for generates a lazy sequence, so no work is actually done before it's needed. The reason the work gets done here is because the REPL wants to print the result, and thus the lazy sequence is realized.

As for what the for loop actually does. We make a vector of the two maps xbox and playstation. for will loop over that vector and assign each value to the var in the binding vector here ({[_ x] :bushido}) which in this case is a also a destructuring.

This destructuring takes a map and extracts the value under the key :bushido which it then expected to be a vector of two elements, where it assigned the first element to a symbol _ and the second element to the symbol x.

The for loop then returns x for each of the elements.

This could also have been written as:

user> (map (comp second :bushido) [xbox playstation])
;; => ({:country :notavailable} {:country :japan})
user> 

Note that the games in you xbox and playstation doesn't have the same shape, because :parappa does not contain a vector as its value.

by
very helpful and clear explanation ! i apreciate your answer, ty !!!
0 votes
by

It's better to format code not as a quote but as proper code blocks - there's a separate button for that.

That for form does exactly nothing useful because it creates a lazy sequence that in this case isn't consumed by anything. You can read more about for in its docstring (easily available by running (doc for) in your REPL) and online with examples here on ClojureDocs.

by
nice, ty for the (doc for) bit !
...