1

Lets say I have a for loop in Java:

 for(Foo foo : foos){ do_something() }

Now lets say I want to translate this list iteration to idiomatic clojure. Whats the best way? I want to return something I can use like an iterator over the foos collection.

2 Answers 2

5
(doseq [foo foos]
  (do-something))

is the idiomatic Clojure equivalent of your Java snippet.

As for returning an iterator, Clojure's collections are all Iterable and seqable, so you can iterate over them in the idiomatic way in both Clojure and Java.

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

3 Comments

This is great thanks. One more question, Im used to higher order Perl function closures, where I would wrap the iterator in something like this: my $func = _build_iterator(); while( my $next_val = $func->() ) { do_something( $next_val) } what is the clojure way to do this?
Idea is to close over the calls to the results of an hbase scan in some convenient processing before giving the result back to the user: (defmethod scan [java.lang.String java.lang.String] [table start-key end-key] (let [scan (Scan. (Bytes/toBytes start-key) (Bytes/toBytes end-key))] (let [scanner (.getScanner table scan)] (doseq [result scanner] (prn (Bytes/toString (.getRow result)) (get-to-map result)))))) I want to return an iterator that unwraps the row key and return a suitable value like nil when exhausted
I see you posted a new question; I'll answer over there. (stackoverflow.com/q/16328566 for the interested.)
0

This is wrong. I'm keeping this around so that it provides useful information for others though

(dorun (map (constantly (do-something)) foos))

Here's the definition of map and here's the definition of constantly.

In summary, this will call do-something for each element in foos. constantly will ignore anything you pass in and just do what you tell it to.

5 Comments

map is lazy -- you'd have to wrap it in dorun to ensure the effects actually take place. doall is another possibility, but it will hold onto the head of the sequence, which is undesirable here.
@MichałMarczyk changed, but I'm not necessarily sure if I should have. Depending on what he does next, the original thing I posted could be equivalent, right?
There's actually another more important problem -- (map (constantly (do-something)) ...) will only (do-something) once, before the iteration even begins. You'd need something like (map (fn [_] (do-something)) ...) instead.
Ah, interesting. Yeah I'm way off. I'm going to keep this around (unless it gets downvotes) because your comments have useful info in it.
As for equivalence of the snippets (with (fn [_] ...)), it's certainly possible to force the lazy seq in the caller of map, but why do it if the whole point of iterating is to produce some effects while throwing away the result? That delegates the responsibility for making sure the effects happen in a timely manner -- in fact, that they happen at all -- to the caller, which feels a bit fragile. Plus doseq is likely to perform somewhat better, since it does away with the lazy seq allocation altogether (whereas map will always construct it; dorun then throws it away piece by piece).

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.