Hacker News new | ask | show | jobs
by prollyignored 4745 days ago
An offtopic clojure question.

Today I was seeing this -- https://en.wikipedia.org/wiki/Knuth-Morris-Pratt_algorithm

How can I begin to implement it in clojure ?

Specifically, how do I _ingeneral_ deal with assignments and while loops.

In common-lisp, for example I would use the `loop` macro and defvar-sefq combo, (beginning lisper).

In ruby, = and while itself.

1 comments

Clojure has most of the semantics you're used to in other languages.

http://clojuredocs.org/clojure_core/clojure.core/let

    (let [username "prollyignored"
          karma 7]
      (println username "has" karma "karma points."))

    ; prollyignored has 7 karma points.
http://clojuredocs.org/clojure_core/1.2.0/clojure.core/loop

    (loop [n 0]
      (when (< n 10)
        (print n)
        (recur (inc n))))

    ;=> 0123456789
http://clojuredocs.org/clojure_core/clojure.core/for

    (for [x [0 1 2 3 4 5]
          :let [y (* x 3)]
          :when (even? y)]
      y)

    ;=> (0 6 12)
Or just:

    (filter even? (map #(* % 3) [0 1 2 3 4 5]))

    ;=> (0 6 12)
Browse the Clojure cheatsheet: http://clojure.org/cheatsheet
Aha !

Now in,

    while m+i is less than the length of S, do:
        if W[i] = S[m + i],
            if i equals the (length of W)-1,
                return m
            let i ← i + 1
            ....
How would I implement the `return m` part ?
There is no explicit return value because the functions aren't functions: they are values, thus the result of the algorithm is bound to the value that is bound to the function.

When you write:

(defn square [x]

     (* x x))
You are really writing:

(def square

    (fn [x]

        (* x x)))
and x * x is bound to the value of square. There would be no logical reason to have an explicit return value here.
It's pretty much the same as this:

    (loop [n 0]
      (if (= n 10)
        n                 ; true case: return n
        (recur (inc n)))) ; false case: loop with n++

    ;=> 10