On 16 February 2011 10:01, Michael Sanders <bluelamp...@gmail.com> wrote:
> I think I've worked out a better solution (hope this post renders properly):
>
> (ns topic (require [clojure.string :as s]))
>
> (defn load-block
>
> "TOPIC database: prints associated blocks to stdout"
>
>     ([tag]
>         (let [STATE (atom 0)
>                rx (re-pattern (str "(?i)" tag "[[:space:]]*(,|$)"))]
>             (loop [line (read-line)]
>                 (when line
>                     (when (and (not= "" (s/trim line))
>                             (not= "\t" (subs line 0 1)))
>                         (if (re-find  rx line)
>                             (reset! STATE 1)
>                             (reset! STATE 0)))
>                     (if (= @STATE 1)
>                         (println line))
>             (recur (read-line)))))))

This is better than using defs, but it's still not very idiomatic.

Start by factoring out the bit that updates the state:

  (defn update-state [state line]
    (if (or (s/blank? line) (.startsWith line "\t"))
      state
      (if (re-find rx line)
        :print
        :skip))

Then in the looping logic, pass the state through the loop/recur:

  (loop [state :skip]
    (when-let [line (read-line)]
      (let [state (update-state state line)]
        (when (= state :print) (println line))
        (recur state))))

There are probably more functional ways of doing this (e.g. using
line-seq and reduce), but this a step in the right direction.

- James

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to