2

Why do you have to use "first" in get-word-ids, and what's the right way to do this?

(defn parts-of-speech []
  (lazy-seq (. POS values)))

(defn index-words [pos]
  (iterator-seq (. dict getIndexWordIterator pos)))

(defn word-ids [word]
  (lazy-seq (. word getWordIDs)))

(defn get-word [word-id]
  (. dict getWord word-id))

(defn get-index-words []
  (lazy-seq (map index-words (parts-of-speech))))

(defn get-word-ids []
  (lazy-seq (map word-ids (first (get-index-words)))))

;; this works, but why do you have to use "first" in get-word-ids?
(doseq [word-id (get-word-ids)]
  (println word-id))
espeed
  • 4,754
  • 2
  • 39
  • 51
  • You are using `lazy-seq` wrong, there's a whole idiom you must respect. But mainly, this is low-level stuff and the "right way" would be to combine the existing core functions like `map`, `filter`, `for` etc. to achieve what you want. – Marko Topolnik Apr 20 '12 at 10:19
  • Take a look at [this SO question.](http://stackoverflow.com/questions/4992298/clojure-lazy-sequence-usage) – Marko Topolnik Apr 20 '12 at 10:24

2 Answers2

4

The short answer: remove all the references to lazy-seq.

as for your original question, it is worth explaining even if it's not a idomatic use of lazy-seq. you have to use first because the get-word-ids function is returning a lazy sequence with one entry. that entry is the lazy sequences you are looking for.

looks like this

( (word1 word2 word3) )

so first returns the sequence you want:

(word1 word2 word3)


It is very likely that the only time you will use lazy-seq will be in this pattern:
(lazy-seq (cons :something (function-call :produces :the :next :element)))

I have never seen lazy-seq used in any other pattern. The purpose of lazy-seq is to generate new sequences of original data. If code exists to produce the data then it's almost always better to use something like iterate map, or for to produce your lazy sequence.

Arthur Ulfeldt
  • 90,827
  • 27
  • 201
  • 284
  • Thank you, Arthur. Well then is iterator-seq being used right in index-words since the Java method is returning an iterator? – espeed Apr 21 '12 at 09:46
1

This seems wrong:

(defn get-index-words []
  (lazy-seq (map index-words (parts-of-speech))))

(index-words pos) returns a seq. which is why you need a (first) in get-word-ids.

also map is already lazy, so there's no need to wrap a (map ...) in a lazy-seq, and it would be almost pointless to use lazy-seq around map if map wasn't lazy. it would probably be useful if you'd read up a bit more on (lazy) sequences in clojure.

Joost Diepenmaat
  • 17,633
  • 3
  • 44
  • 53