24
Clojure> (doc foreach)
Unable to resolve var: foreach in this context

Clojure> (doc map)
-------------------------
clojure.core/map
([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls])

Of course, i can use the "map" to mimic "foreach" but the map always return nil, which makes the output ugly in the following function:

(defn div618 [p1 p2]
    (let [ratio [0.,0.191,0.236,0.382,0.5,0.618,0.809,1.]
          price (fn [r] (if (<= p1 p2) (+ p1 (* (- p2 p1) r)) (- p1 (* (- p1 p2) r))))]

    (if (<= p1 p2)
        (**map** #(println (format "-------%.3f   %.2f-------" %1 (price %1))) (reverse ratio))
        (**map** #(println (format "-------%.3f   %.2f-------" %1 (price %1)))  ratio))))

Sincerely!

1
  • What is **map**? Did you mean to set that name in bold? Also, you know that you can use newlines anywhere between tokens, right? Commented Sep 6, 2011 at 7:18

6 Answers 6

74

I think doseq might be what you're looking for:

(doseq [i [0 1 2 3]] (println i))

However this will still return nil - all forms in Clojure will evaluate to some value; there's no equivalent to Common Lisp's (values).

Sign up to request clarification or add additional context in comments.

1 Comment

@z_axis: Tick the check mark on the left to accept an answer. Also, you might want to upvote it.
13

As of Clojure 1.7 you can use run!:

user=> (run! println (range 10))

0
1
2
3
4
5
6
7
8
9
=> nil  ; returns nil

See this answer to How to print each item of list on separate line clojure?

1 Comment

Exactly what I was looking for. Works like Julia's foreach
3

map is used to apply a function f to every element of the seq, in your case your applying print which returns nil, so you get a intermediate seq of nils which you then throw away. When you want side effects like printing you use doseq.

Clojure does not have a single foreach form map, reduce filter etc. technically these are all foreach forms they all do something to each element in the seq. Also map is lazy your example will only print in the repl cause repl forces lazy seq to realize them selfs say if you pack this in a jar it won't do anything.

Comments

3

You could use doseq or doall. Following is the example using doall.

(defn div618 [p1 p2]
    (let [ratio [0.,0.191,0.236,0.382,0.5,0.618,0.809,1.]
          price (fn [r] (if (<= p1 p2) (+ p1 (* (- p2 p1) r)) (- p1 (* (- p1 p2) r))))]

    (doall (map #(println (format "-------%.3f   %.2f-------" %1 (price %1))) (if (<= p1 p2) (reverse ratio) ratio)))))

You could also separate the printing from the function calculation like this,

(defn div618 [p1 p2]
    (let [ratio [0.,0.191,0.236,0.382,0.5,0.618,0.809,1.]
          price (fn [r] (if (<= p1 p2) (+ p1 (* (- p2 p1) r)) (- p1 (* (- p1 p2) r))))]

    (map (fn [x] [x (price x)]) (if (<= p1 p2) (reverse ratio) ratio))))

(doall (map #(println (format "-------%.3f   %.2f-------" (first %1) (last %1))) (div618 1 2)))

Comments

2

I think you want clojure's list comprehension, see: http://en.wikibooks.org/wiki/Clojure_Programming/Concepts#List_Comprehension

1 Comment

Clojure> (for [x (range 10)] (inc x)) (1 2 3 4 5 6 7 8 9 10) Clojure> (for [x (range 10)] (println x)) (nil nil nil nil nil nil nil nil nil nil)
1
(defn div618 [p1 p2]
  (let [ratio [0.000 0.191 0.236 0.382 0.500 0.618 0.809 1.000]            
        price #(if (<= p1 p2)
                 (-> p2 (- p1) (* %) (+ p1))
                 (-> p1 (- p2) (* %) (- p1)))
        print-all #(doseq [item %]
                     (printf "-------%.3f   %.2f-------\n" item (price item)))]
    (if (<= p1 p2)
      (print-all (reverse ratio))
      (print-all ratio))))

1 Comment

Note: no commas, ad-hoc left-to-right math syntax using thread-first (->), and doseq which is essentially Clojure's foreach.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.