Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I would not use <code>ref-set</code> but <code>alter</code> because you don't reset the state to a completely new value, but update it to a new value which is obtained from the old one.</p> <pre><code>(defn block-scanner [trigger-string] (let [curr (ref trigger-string) trig trigger-string] (fn [data] (doseq [c data] (when (seq @curr) (dosync (alter curr #(if (-> % first (= c)) (rest %) trig))))) (empty? @curr)))) </code></pre> <p>Then it is not necessary to use refs since you don't have to coordinate changes. Here an atom is a better fit, since it can be changed without all the STM ceremony.</p> <pre><code>(defn block-scanner [trigger-string] (let [curr (atom trigger-string) trig trigger-string] (fn [data] (doseq [c data] (when (seq @curr) (swap! curr #(if (-> % first (= c)) (rest %) trig)))) (empty? @curr)))) </code></pre> <p>Next I would get rid of the imperative style.</p> <ul> <li>it does more than it should: it traverses all data - even if we found a match already. We should stop early.</li> <li>it is not thread-safe, since we access the atom multiple times - it might change in between. So we must touch the atom only once. <em>(Although this is probably not interesting in this case, but it's good to make it a habit.)</em></li> <li>it's ugly. We can do all the work functionally and just save the state, when we come to a result.</li> </ul> <pre><code>(defn block-scanner [trigger-string] (let [state (atom trigger-string) advance (fn [trigger d] (when trigger (condp = d (first trigger) (next trigger) ; This is maybe a bug in the book. The book code ; matches "foojihad", but not "jijihad". (first trigger-string) (next trigger-string) trigger-string))) update (fn [trigger data] (if-let [data (seq data)] (when-let [trigger (advance trigger (first data))] (recur trigger (rest data))) trigger))] (fn [data] (nil? (swap! state update data))))) </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload