Hi All,

I have been watching Clojure for about 6 months.  I finally sat down
and tried to code a non-trivial task with it.  I come from Java and
have dabbled in LISP but never for something significant.

So I am asking if you would look at the following code and provide
feedback on how it can be made less "Java" and more "Clojure" in terms
of style and approach.

The code is basically a translation of the code in the first chapter
of _Beautiful Code_.  It is a simple regexp matcher that matches ^,
$, .(dot), *, and literal characters.  I didn't change much of the
structure because the structure made sense to my Java sensibilities.
I learned a lot in getting it to work.  I had to figure out how to
iterate over a string, use loop...recur, etc.  But the style of coding
can't be gotten from the API docs.  So is this way off?  Or are there
different ways of thinking about the solution that would be more in
line with a "Clojure way"?

I must confess that the result here doesn't make me happy.  The C code
from the article looked very clear and extension (+, ?, character
classes) looked like it would be fairly straightforward.  I'm not sure
that is true with my code here.

Finally, this is just an exercise.  If I needed regexp in another
problem, I would use the clojure tools.

Thanks in advance,
Matthew

P.S. There must be some libraries for testing that would be better
than what I've done, but I didn't find anything I could get to work.

(declare matchhere)

(defn match
  "search for regexp anywhere in text"
  [regexp text]
  (if (= (first regexp) \^)
    (matchhere (rest regexp) (seq text))
    (loop [re (seq regexp) t (seq text)]
      (if (matchhere re t)  ; always search even if text is empty
        true
        (if (seq (rest t))
          (recur re (rest t))
          false)))))

(defn matchstar
  "search for [char]*regexp at beginning of text"
  [char regexp text]
  (loop [c char re regexp t text]
    (if (matchhere re t) ; a * matches zero or more instances
      true
      (if (and (seq t)
               (or (= (first t) c) (= c \.)))
        (recur c re (rest t))
        false))))

(defn matchhere
  "search for regexp at beginning of text"
  [regexp text]
  (loop [re regexp t text]
    (if (nil? re)
      true
      (if (and (= (first re) \$) (nil? (rest re)))
        (nil? t)
        (if (= (nth re 1 ()) \*)
          (matchstar (first re) (rest (rest re)) t)
          (if (and (seq t)
                   (or (= (first re) \.) (= (first re) (first t))))
            (recur (rest re) (rest t))
            false))))))

;;  some of my tests that show usage
(= true (match "a" "a"))
(= false (match "b" "a"))
(= true (match "b" "ab"))

(= true (match "^a" "ab"))
(= false (match "^b" "ab"))

(= true (match "b$" "aaaab"))
(= true (match "a$b" "aaa$bBB"))
(= false (match "ab$" "ab$"))

(= false (match "a.*b" "aaaaa"))
(= true (match "a.*b" "aaab"))
(= true (match "a.*b" "aabb"))

;; etc. etc.

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