Вопрос

I'm reading Programming Clojure 2nd edition, and on page 49 it covers Clojure's for loop construct, which it says is actually a sequence comprehension.

The authors suggest the following code:

(defn indexed [coll] (map-indexed vector coll))

(defn index-filter [pred col]
  (when pred
    (for [[idx elt] (indexed col) :when (pred elt)] idx)))

(index-filter #{\a} "aba")
(0 2)

...is preferable to a Java-based imperative example, and the evidence given is that it "by using higher-order functions...the functional index-of-any avoids all need for variables."

What are "idx", "elt" if they are not variables? Do they mean variables besides the accumulators?

Also, why #{\a} instead of "a"?

Это было полезно?

Решение

  1. There are no variables in functional languages. Actually, you need distinguish variable and value. idx it's just a name bound to concrete value, and you can not reassign it (but you can rebound it to another value).

  2. First parameter of function index-filter is predicate, that means function that return true or false. #{\a} it's a data structure set, but it also can be treated like a function. If you pass element as argument to set function it returns this argument (like true) if element exists and nil (like false) otherwise. So you can think about this set predicate as anonymous function written in more understandable way #(contains? #{\a} %)

Другие советы

pred is a function - #{\a} is a set containing the character a. In Clojure, a set is a function which returns true if its argument \a is contained by it. You could also use #(= % \a) or (fn [x] (= \a x)).

As the other answer implies, "no state was created in the making of this example." idx and elt function like variables, but are local only to the for sequence comprehension, so the code is more compact, not stateful, and arguably clearer (once you're used to sequence comprehensions, at least :-) ) -- perhaps the text is not optimally clear on this point.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top