scape
scape

Reputation: 707

In Clojure, how can I terminate this loop properly

I am just getting in to Clojure and wanted to do some simple functions to get my feet wet and try and get away from my Imperative programming background.

This below simply searches a string for repeating elements, however the loop seems to spin it out of control; what have I done wrong? And yes, this probably looks imperative; I'm still trying to wrap my head around functional programming and non-state changes. And yes the html is not validated, I'm simply using it as an example.

(def src "
  <html>
  <head>
  <title>Astronomy
  </title>
  <title>Science
  </title>
  </head>
  </html>
")


(defn findit [ele body i]
  (let [n (.indexOf body (clojure.string/join ["<" ele ">"]) i)]
    (if (> n -1)
      (let [n2 (.indexOf body (clojure.string/join ["</" ele ">"]) (+ n 1))] ;if we found opening element, then find closing element
        (if (> n2 -1) ;found both open and close of element?
          [(subs body (+ n (.length ele) 2) n2) (+ n2 1)]))))
  )

; (let [[r i] (findit "title" src 69)] (println i) (if r (println r,i)))

(defn findthem [ele body]
  (loop [x 0]
    (let [[r i] (findit ele body 0)]
      (println r,i)
      (if i
        (recur i)))
    )
  )

(findthem "title" src)

Upvotes: 0

Views: 218

Answers (1)

Beyamor
Beyamor

Reputation: 3378

In the let statement, which occurs every iteration of the loop, findit is called with the index as 0, not x (or, i).

(defn findthem [ele body]
  (loop [i 0]
    (let [[r i] (findit ele body i)]
      (println r i)
      (when i
        (recur i)))))

Upvotes: 2

Related Questions