Search code examples
clojure

How to keep a list of objects in Clojure?


I'm trying to use java interop, to create a list of objects.

I have tried for and doseq, and they both have problems.

for is lazy, and I need to create all the objects, as they interact with each other internally.

(def master-object (MasterObject.))

(for [x [1 10 50 99]]
  (let [child (.createChildObject master-object)]
    (.setCoefficient child x)
    child))

doseq creates all, but don't return a list.

(doseq [x [1 10 50 99]]
  (let [child (.createChildObject master-object)]
    (.setCoefficient child x)
    child))

I was thinking about using loop and recur, but was wondering if could be a more idiomatic way of doing that.

Thanks


Solution

  • If you need to create all the objects then I think it would be idiomatic to return a vector rather than a list, for example:

    (vec (for [x (range 3)]
           x))
    

    There are a few different ways to force all the output from a for. The above is one of them. vec is just short for into []. So if you definitely need a realised list you could instead:

    (into '() (for [x (range 3)]
                x))
    

    For creating a list of objects doseq will not help you as it is only about 'side effects'.

    Really you could look at using map for what you want to accomplish. Make a separate mapping function and map over it:

    (defn make-child [x]
      (let [child (.createChildObject master-object)]
          (.setCoefficient child x)
          child))
    
    (map make-child [1 10 50 99])