Al23
Al23

Reputation: 1

Clojure - sequence of objects

I have a Clojure function:

(def obseq
  (fn []
    (let [a 0
          b 1
          c 2]
      (println (seq '(a b c))))))

It outputs :

(a b c)

I want it to output a sequence containing the values of a, b, and c, not their names.

Desired output:

(1 2 3)

How do I implement this?

Upvotes: 0

Views: 69

Answers (1)

Alan Thompson
Alan Thompson

Reputation: 29958

Short answer:

clj.core=> (defn obseq [] 
             (let [a 0 
                   b 1 
                   c 2]
               (println [a b c])))
#'clj.core/obseq
clj.core=> (obseq)
[0 1 2]
nil

Long answer:

Quoting a form like '(a b c) recursively prevents any evaluation inside the quoted form. So, the values for your 3 symbols a, b, and c aren't substituted. It is much easier to use a vector (square brackets), which never needs to be quoted (unlike a list). Since the vector is unquoted, the 3 symbols are evaluated and replaced by their values.

If you wanted it to stay a list for some reason, the easiest way is to type:

clj.core=> (defn obseq [] (let [a 0 b 1 c 2] (println (list a b c))))
#'clj.core/obseq
clj.core=> (obseq)
(0 1 2)
nil

This version also has no quoting, so the 3 symbols are replaced with their values. Then the function (list ...) puts them into a list data structure.

Note that I also converted your (def obseq (fn [] ...)) into the preferred form (defn obseq [] ...), which has the identical result but is shorter and (usually) clearer.

Upvotes: 5

Related Questions