Clojure STM simple program - clojure

I am writing on a simple program to transform the values of two integers using Clojure's STM.
I am following the approch of Lewandowski (http://lewandowski.io/2016/01/clojure-summary/), using his function a06.
My code:
(defn trans [p1 p2]
(println "a")
(dosync
(let [newval1 (#p1 + 50)
newval2 (#p2 - 30)]
(do
(println "b")
(ref-set p1 newval1)
(ref-set p2 newval2)))))
(defn main []
(let [p1 (ref 20) p2 (ref 100)]
(do
(future (trans p1 p2))
(future (trans p1 p2))
(Thread/sleep 500))
(println #p1)
(println #p2)))
For some reason, my function main is not getting into the "do part" of the function trans. My output is hence only:
a
a
20
100
=> nil
I added "a" and "b" to show my problem.
I am sorry if this is a very simple mistake I made but I simply don't see what is missing in my code. Every answer is much apreciated! Thank you!

Compare to the following, which works correctly:
(defn trans [p1 p2]
(println "a")
(dosync
(let [newval1 (+ #p1 50)
newval2 (- #p2 30)]
(do
(println "b")
(ref-set p1 newval1)
(ref-set p2 newval2)))))
(defn main []
(let [p1 (ref 20) p2 (ref 100)]
(let [f1 (future (trans p1 p2))
f2 (future (trans p1 p2))]
(Thread/sleep 500))
(println (pr-str #p1))
(println (pr-str #p2))))
That said, futures aren't really the ideal tool for the job when your interest is in a side effect, rather than in later retrieval of the result of the calculation itself.

Related

Sleeping barber in Clojure

I'm implementing Sleeping barber using core.async. My current code is:
(def workingtime 10000)
(defn barber [in waiting-room]
(go-loop [served-customers 0]
(let [[v] (alts! [waiting-room in])]
(if (= v :close)
served-customers
(do (Thread/sleep 20)
(recur (inc served-customers)))))))
(defn customers [in waiting-room]
(go-loop [customers-overall 0]
(let [customer-arrival-interval (timeout (+ 10 (rand-int 20)))
[v] (alts! [in customer-arrival-interval])]
(if (= v :close)
customers-overall
(do (>! waiting-room :customer)
(recur (inc customers-overall)))))))
(defn -main [& args]
(let [in (chan)
waiting-room (chan (dropping-buffer 3))
barber-ch (barber in waiting-room)
customers-ch (customers in waiting-room)]
(println "opening the shop for 10 seconds...")
(Thread/sleep workingtime)
(>!! in :close)
(>!! in :close)
(println "closing the shop...")
(println (str "Served " (<!! barber-ch) " customers"))
(println (str "Overall " (<!! customers-ch) " customers came"))))
Is it a correct solution? Can it be improved to make it more Clojure-like?
I wanted to use alt! instead of alts! which makes code easier to read:
(defn barber [in]
(go-loop [served-customers 0]
(alt!
waiting-room (do (Thread/sleep 20)
(recur (inc served-customers)))
in served-customers)))
Runtime throws an exception: Can only recur from tail position. Can I still use alt!?
You could solve the alt!/recur problem by rewriting to:
(defn barber [in]
(go-loop [served-customers 0]
(if (= :waiting-room
(a/alt!
waiting-room ([result] :waiting-room) ;; you could also use result if needed
in ([result] :in))) ;; same here
(do (Thread/sleep 20)
(recur (inc served-customers)))
served-customers)))

conj not adding to end of vector when called via recur

Why does this keep asking Jack if he wants a cup of tea and not the other fathers.
(defn tea-anyone
"Ask 'fathers' if they would like some tea"
[fathers]
(loop [asks 0 to-ask fathers]
(let [[father & others] to-ask]
(println (str "Cup of tea " father "? "))
(if (> asks 6)
(println (str father ": All right then!"))
(recur (inc asks) (conj others father))))))
(tea-anyone ["Jack" "Ted" "Dougle"])
Because others isn't a vector. See for yourself:
(let [[f & o :as a] [1 2 3 4]]
(println f)
(println o)
(println a)
(println (type f))
(println (type o))
(println (type a))
(println (type (conj o 5)))
(println (type (conj a 5))))
To achieve the effect you want, you could use cycle.
Try this:
(recur (inc asks) (conj (vec others) father))

Setting a debug function from the command line in Clojure

I have a namespace like this:
(ns foo.core)
(def ^:dynamic *debug-fn*
"A function taking arguments [bar baz]"
nil)
(defn bar-info
[bar _]
(println bar))
(defn baz-info
[_ baz]
(println baz))
(defn do-stuff
[bar baz]
(when *debug-fn* (*debug-fn* bar baz)))
(defn -main
[& {:keys [debug-fn]}]
(binding [*debug-fn* (symbol debug-fn)] ;; THIS WON'T WORK!
(do-stuff 27 42)))
What I would like to do is allow a debug function to be specified from the command line like this: lein run bar-info or lein run baz-info.
I'm not sure how to take the string specified as a command-line argument and turn it into the namespace-qualified function to bind. Do I need a macro to do this?
Use ns-resolve, you will need to specify namespace where your function is defined though.
user=> (defn f [n] (* n n n))
#'user/f
user=> ((ns-resolve *ns* (symbol "f")) 10)
1000
Use alter-var-root:
user=> (doc alter-var-root)
-------------------------
clojure.core/alter-var-root
([v f & args])
Atomically alters the root binding of var v by applying f to its
current value plus any args
nil
user=> (alter-var-root #'*debug-fn* (fn [v] (fn [x] (println x) x)))
#<user$eval171$fn__172$fn__173 user$eval171$fn__172$fn__173#7c93d88e>
user=> (*debug-fn* 1)
1
1
Though I've accepted Guillermo's answer above, I figured that it might also be useful to add the solution I ended up going with:
(def debug-fns
{:bar-info (fn [bar _] (println bar))
:baz-info (fn [_ baz] (println baz))
(def active-debug-fns (atom []))
(defn activate-debug-fn!
[fn-key]
(let [f (debug-fns fn-key)]
(if f
(swap! active-debug-fns conj f)
(warn (str "Debug function " fn-key " not found! Available functions are: "
(join " " (map name (keys debug-fns))))))))
(defn debug-fn-keys
[args]
(if (args "--debug")
(split (or (args "--debug") "") #",")
[]))
(defn do-stuff
[bar baz]
(doseq [f #active-debug-fns]
(f bar baz)))
(defn -main
[& args]
(let [args (apply hash-map args)]
(doseq [f (debug-fn-keys args)]
(activate-debug-fn! (keyword k)))
(do-stuff 27 42)))
So now you can say something like lein run --debug bar-info to get info on bars, or lein run --debug bar,baz to get info on both bars and bazes.
Any suggestions to make this more idiomatic will be happily accepted and edited in. :)

How do I rewrite (def) out of this Clojure code?

I have written a game loop based on deWitter's game loop.
However, I am unsure how to transfer it to a more functional state. I realize that there may need to be some mutable state left within the code but are there any general principles for cleaning up extraneous defs?
(ns beepboop.core)
(def ticks-per-second 25)
(def skip-ticks (/ 1000 ticks-per-second))
(def max-frameskip 5)
(defn update []
(println "Updating."))
(defn display [delta]
(println "Displaying with delta: " delta))
(defn -main []
(def *next-tick* (System/currentTimeMillis))
(while true
(def *loops* 0)
(while (and
(> (System/currentTimeMillis)
*next-tick*)
(< *loops*
max-frameskip))
(update)
(def *next-tick* (+ *next-tick* skip-ticks))
(def *loops* (+ *loops* 1)))
(display
(/ (+ (System/currentTimeMillis) skip-ticks (* -1 *next-tick*))
skip-ticks))))
You should use loop and recur for updating your loop variables:
(defn -main []
(loop [next-tick (System/currentTimeMillis)]
(let [next-next
(loop [next-tick next-tick
loops 0]
(if (and (> (System/currentTimeMillis) next-tick)
(< loops max-frameskip))
(do (update)
(recur (+ next-tick skip-ticks) (+ loops 1)))
next-tick))]
(display (/ (+ (System/currentTimeMillis) skip-ticks (- next-next))
skip-ticks))
(recur next-next))))

How to launch two threads and wait for them

I can launch two threads and they work, but synchronously. What am I missing to get these threads independently launched?
main, thread, and output
(defn -main
[& args]
(do
(let [grid-dim-in [0 5]
mr1-pos [\N 2 4]
mr2-pos [\N 1 5]
mr1-movs "LMLMMRMM"
mr2-movs "RMRMMMLM"]
(reset! grid-dim grid-dim-in)
(reset! mr1-id {:mr1 mr1-pos})
(reset! mr2-id {:mr2 mr2-pos})
(.start (Thread. (rover-thread mr1-id mr1-movs update-work-block)))
(.start (Thread. (rover-thread mr2-id mr2-movs update-work-block))))))
(defn rover-thread [id movs update-ref]
(let [id-key (keys #id)
id-vals (vals #id)]
(doseq [mov movs]
(println "Rover " id-key " is moving ")
(let [new-mov (determine-rover-move (first id-vals) mov)]
(move-rover id new-mov update-ref)
(print "Rover ")
(print (first id-key))
(print " is at ")
(println new-mov)
(Thread/sleep (rand 1000)))))
Rover :mr1 is at [E 2 4]
Rover (:mr1) is moving
Rover :mr1 is at [N 2 5]
Rover (:mr1) is moving
Rover :mr1 is at [N 2 5]
Finished on Thread[main,5,main]
Rover (:mr2) is moving
Rover :mr2 is at [E 1 5]
Rover (:mr2) is moving
Rover :mr2 is at [N 1 6]
Take a close look at these two lines:
(.start (Thread. (rover-thread mr1-id mr1-movs update-work-block)))
(.start (Thread. (rover-thread mr2-id mr2-movs update-work-block))))))
This code evaluates the (rover-thread mr1-id mr1-movs update-work-block) first, and passes the result of that to the constructor of Thread, which is not what you want.
Here's a simple function to illustrate the principle. This doesn't work, because the (f ...) is evaluated before its result it passed to the Thread constructor:
(defn run-thread-thing-wrong []
(let [f (fn [n s]
(doseq [i (range n)]
(prn s i)
(Thread/sleep (rand 1000))))]
(.start (Thread. (f 10 "A")))
(.start (Thread. (f 10 "B"))))
nil)
Here's a version that does work. A function is passed to the Thread constructor instead:
(defn run-thread-thing []
(let [f (fn [n s]
(doseq [i (range n)]
(prn s i)
(Thread/sleep (rand 1000))))]
(.start (Thread. (fn [] (f 10 "A"))))
(.start (Thread. (fn [] (f 10 "B")))))
nil)
Note: instead of (fn [] ....) you can use the short form #(....) for anonymous functions.
Here's another version that does the same, but with a future instead of manually creating threads:
(defn run-thread-thing []
(let [f (fn [n s]
(doseq [i (range n)]
(prn s i)
(Thread/sleep (rand 1000))))]
(future (f 10 "A"))
(future (f 10 "B")))
nil)
Note that in this case, you pass a form to future instead of a function.
This seems like a really good place to use Clojure's agent feature. I am not qualified to fully explain how to use them, but a really good example of their usage can be found here. Starting threads using agents is dead-easy, and I think it is more idiomatic.
The code would look something like,
(def rover1 (agent [mr1-posn mr1-movs mr1-id]))
(def rover2 (agent [mr2-posn mr2-movs mr2-id]))
(defn rover-behave [[posn movs id]]
(send-off *agent* #'rover-behave)
(. Thread (sleep 1000))
(let [new-mov (determine-rover-move posn movs id)
new-posn (posn-after-move posn new-mov)]
;return value updates state of agent
[new-posn movs id]
)
)
(send-off rover1 rover-behave)
(send-off rover2 rover-behave)