espeed
espeed

Reputation: 4814

What's the right way to create a Clojure function that returns a new sequence based on another sequence?

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))

Upvotes: 2

Views: 212

Answers (2)

Arthur Ulfeldt
Arthur Ulfeldt

Reputation: 91534

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.

Upvotes: 4

Joost Diepenmaat
Joost Diepenmaat

Reputation: 17773

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.

Upvotes: 1

Related Questions