LightTable Clojure Watches not Updating on Atom - clojure

When I add a watch to a variable in clojure and rebind it, the watch is updated dynamically.
(def x "jlkfds")
x
In the above example x will always reflect its value.
However, when I try and do this using an atom, I have no luck. I have to execute the whole thing again to get the changes to reflect in either the instarepl or the watch.
(defonce y (atom 10))
#y *38*
(swap! y inc) *80*
In the above example I have executed the swap without executing the deref, and they have thus become out of sync.
What confuses me is that I saw a Javascript demo where someone (Chris) was able to watch the coordinates of a mouse pointer dynamically change. I really like the idea of having this functionality. Is there a way to do the same thing in Clojure?
Like this?
http://youtube.com/watch?v=d8-b6QEN-rk
Thank you

Watches are only updated when the thing they are watching is eval'd. Just make sure that you are watching somewhere the watch macro can be eval'd. Try this.
(defonce y (atom 10))
(do //Eval this sexp
(swap! y inc)
#y) //watch this j
I think you are also running into issues with the insta-repl (live mode), periodically it will evaluate the entire page and that is where you are seeing the watches get out of sync. For example, line 1 is evaluated and the atom is created. You add a watch to line 2, evaluating it. You increment the watch with line 3 28 times, then do something that forces line 2 to eval again. This updates the watch to the new value of y. Re-evaluating line 3 doesn't change the watch on line two but it changes the value of y.

Related

Clojure Quil slow key input

Been learning some Clojure lately. Just making a simple game with the Quil library where I can move around using the arrow keys, but I ran into a minor (but annoying) problem -- when I hold down an arrow key, my character moves on the screen, but after the first slight movement, there's a delay until the character starts moving again. Once the character starts moving again, the movement is continuous with no problems. Basically what it feels like is that the key being held down isn't being registered by the program for almost a second after the first slight movement. This seems like such a tiny problem but it's very noticeable and annoying. Also I'd like to learn why this happens simply to learn.
By slight movement I mean the key press is instantly registered and the character moves a bit. Also if I keep tapping on the key fast, all the presses are instantly registered and the character moves as you'd expect. The problem only occurs when I hold the key down. Any ideas what could be causing this and how to fix it? Here's the sketch with the :key-pressed handler. Thanks.
(q/defsketch hello-quil
:title "Game"
:size [800 500]
; setup function called only once, during sketch initialization.
:setup setup
; update-state is called on each iteration before draw-state.
:update update-state
:draw draw-state
:key-pressed
(fn [state { :keys [key key-code] }]
(case key
(:up) (if (> (state :p-left) 5) (assoc state :p-left (- (state :p-left) 15)) state)
(:down) (if (< (state :p-left) 395) (assoc state :p-left (+ (state :p-left) 15)) state)
state))
:features [:keep-on-top]
; This sketch uses functional-mode middleware.
; Check quil wiki for more info about middlewares and particularly
; fun-mode.
:middleware [m/fun-mode])
Don't rely on the key event being repeated for you when the key is held down. Use key-released and time in the update functions. Put key-down into your state, set it to true in key-pressed and to false in key-released, then update your character position in update-state when key-down is true.

Atom update hangs inside of Clojure watch call

I've got a situation where I watch a specific directory for filesystem changes. If a certain file in that directory is changed, I re-read it, attach some existing cached information, and store it in an atom.
The relevant code looks like
(def posts (atom []))
(defn load-posts! []
(swap!
posts
(fn [old]
(vec
(map #(let [raw (json/parse-string % (fn [k] (keyword (.toLowerCase k))))]
(<snip some processing of raw, including getting some pieces from old>))
(line-seq (io/reader "watched.json")))))))
;; elsewhere, inside of -main
(watch/start-watch
[{:path "resources/"
:event-types [:modify]
:callback (fn [event filename]
(when (and (= :modify event) (= "watched.json" filename))
(println "Reloading posts.json ...")
(posts/load-posts!)))}
...])
This ends up working fine locally, but when I deploy it to my server, the swap! call hangs about half-way through.
I've tried debugging it via println, which told me
The filesystem trigger is being fired.
swap! is not running the function more than once
The watched file is being opened and parsed
Some entries from the file are being processed, but that processing stops at entry 111 (which doesn't seem to be significantly different from any preceding entries).
The update does not complete, and the old value of that atom is therefore preserved
No filesystem events are fired after this one hangs.
I suspect that this is either a memory issue somewhere, or possibly a bug in Clojure-Watch (or the underlying FS-watching library).
Any ideas how I might go about fixing it or diagnosing it further?
The hang is caused by an error being thrown inside of the function passed as a :callback to watch/start.
The root cause in this case is that the modified file is being copied to the server by scp (which is not atomic, and the first event therefore triggers before the copy is complete, which is what causes the JSON parse error to be thrown).
This is exacerbated by the fact that watch/start fails silently if its :callback throws any kind of error.
The solutions here are
Use rsync to copy files. It does copy atomically but it will not generate any :modify events on the target file, only related temp-files. Because of the way its atomic copy works, it will only signal :create events.
Wrap the :callback in a try/catch, and have the catch clause return the old value of the atom. This will cause load-posts! to run multiple times, but the last time will be on file copy completion, which should finally do the right thing.
(I've done both, but either would have realistically solved the problem).
A third option would be using an FS-watching library that reports errors, such as Hawk or dirwatch (or possibly hara.io.watch? I haven't used any of these, so I can't comment).
Diagnosing this involved wrapping the :callback body with
(try
<body>
(catch Exception e
(println "ERROR IN SWAP!" e)
old))
to see what was actually being thrown. Once that printed a JSON parsing error, it was pretty easy to gain a theory of what was going wrong.

Managing and finding variables in Clojure REPL

I was looking at https://github.com/juxt/dirwatch library. The example from the front page is:
(require '[juxt.dirwatch :refer (watch-dir)])
(watch-dir println (clojure.java.io/file "/tmp"))
That works fine. Let's say the above is executed in REPL:
user=> (watch-dir println (clojure.java.io/file "/tmp"))
#<Agent#16824c93: #<LinuxWatchService sun.nio.fs.LinuxWatchService#17ece9ac>>
Now, I have an agent that will print events when I modify files in /tmp:
{:file #<File /tmp/1>, :count 1, :action :modify}
so all is fine.
I know I can reference the agent by using previous expression references (*1, *2 and *3). However, I don't know how to, without restarting the REPL itself:
Unbind an implicit var created like this - i.e. how to remove the binding completely, so that agent gets GCed and stops working
Access it in case I lost it in cases where I did not bind it, such as the above. If I'm not mistaken, in REPL only the last three results are available (*3 is, but *4 and further are not), at least per http://clojure.org/repl_and_main
Any suggestions?
Did you take a look at the code? The documentation to watch-dir has this: "The watcher returned by this function is a resource which
should be closed with close-watcher."
Looking at the code, it watch-dir uses send-off, which "Dispatch a potentially blocking action to an agent. Returns the agent immediately.". In other words, to address your first question, there is no implicit var created. If you want to get rid of the agent, you should bind the returned agent to some var and call close-watcher on it afterwards.
To address the second question, take a look at the canonical documentation for agents. Specifically, you can call shutdown-agents, which will shut-down the thread pool (potentially killing other agents as well).

What's the meaning of :key parameter in add-watch function

My problem is that with the doc and examples providede i can't understand the meaning of :key parameter or its possible values
This is the official doc page of the function that I'm referring:
http://clojuredocs.org/clojure_core/clojure.core/add-watch
add-watch clojure.core
(add-watch reference key fn)
Adds a watch function to an agent/atom/var/ref reference. The watch fn
must be a fn of 4 args: a key, the reference, its old-state, its
new-state. Whenever the reference's state might have been changed, any
registered watches will have their functions called. The watch fn will
be called synchronously, on the agent's thread if an agent, before any
pending sends if agent or ref. Note that an atom's or ref's state may
have changed again prior to the fn call, so use old/new-state rather
than derefing the reference. Note also that watch fns may be called
from multiple threads simultaneously. Var watchers are triggered only
by root binding changes, not thread-local set!s. Keys must be unique
per reference, and can be used to remove the watch with remove-watch,
but are otherwise considered opaque by the watch mechanism.
Thanks
It's basically just an identifier that you can use in calling code to identify the watch, in case you have more than one watches per reference. It's something that should have significance to your application code, but will be passed through by Clojure.
For instance:
user> (def a (atom 0))
#'user/a
user> (add-watch a
:count-to-3
(fn [k r old-state new-state]
(println "changed from" old-state "to" new-state)
(when (>= new-state 3)
(remove-watch a :count-to-3))))
#<Atom#3287a10: 0>
user> (dotimes [_ 5] (swap! a inc))
changed from 0 to 1
changed from 1 to 2
changed from 2 to 3
nil
user> #a
5
The answer's right there:
Keys must be unique per reference, and can be used to remove
the watch with remove-watch, but are otherwise considered opaque by
the watch mechanism.
In other words, the actual watch mechanism doesn't care what you set the key to (as long as it's unique among the handlers set on the given ref), but you'll need to hang on to it if you ever want to call remove-watch to get rid of your handler

A possible solution to avoid limitation in go macro: Must be called inside a (go ...) block

Perhaps a possible solution to use (<! c) outside go macro could be done with macro and its macro expansion time :
This is my example:
(ns fourclojure.asynco
(require [clojure.core.async :as async :refer :all]))
(defmacro runtime--fn [the-fn the-value]
`(~the-fn ~the-value)
)
(defmacro call-fn [ the-fn]
`(runtime--fn ~the-fn (<! my-chan))
)
(def my-chan (chan))
(defn read-channel [the-fn]
(go
(loop []
(call-fn the-fn)
(recur)
)
))
(defn paint []
(put! my-chan "paint!")
)
And to test it:
(read-channel print)
(repeatedly 50 paint)
I've tried this solution in a nested go and also works. But I'm not sure if it could be a correct path
The reason about this question is releated to this other question Isn't core.async contrary to Clojure principles?, #aeuhuea comment that "It seems to me that this prevents simplicity and composability. Why is it not a problem?" and #cgrand response "The limitation of the go macro (its locality) is also a feature: it enforces source code locality of stateful operations."
But force to localize your code is not the same as "complect"?
Regarding the title of your question:
>!must be called in a go block because it's designed to. If you are interested in the go-block state-machine mechanics, I can highly recommend Timothy Baldridges Youtube videos on that http://www.youtube.com/channel/UCLxWPHbkxjR-G-y6CVoEHOw
Remember that there is always blocking take and put >!! and <!!. I don't know which part of your code is supposed to provide a "solution" for not being able to use <! and >! outside of a go block, however looping around events dispatched from a single channel is common practice. Here is a modified version of read-channel
(defn do-channel [f ch]
(go-loop []
(when-let [v (<! ch)]
(f v)
(recur))))
put! puts asynchronously, an effect that you usually don't intend. In your example, to put the string "paint" into the channel 50 times, I'd recommend a one-liner like this one:
(do-channel println (to-chan (repeat 50 "print")))
Here is a comment as an answer to your edit:
Channels are not designed to be used as mutable data-structures, period. They have a buffer and that buffer can be thought of as a mutable queue. However we don't use channels to store a value in there, just to take it out a few lines later again.
We use channels as helping construct that may be used to bring execution of two or more different pieces of source-code in two or more different places in line. E.g. a go-block here does not continue to execute until it has received a value produced by another go-block. >! and >!! help us to distinguish whether they are used in a thread-blocking context or in a go-block (blocking a spawned process).
Also, please refer to this answer: Clojure - Why does execution hang when doing blocking insert into channel? (core.async)
You should not use >!! or <!! inside of a go-block, neither transparently or nested in a function call. Rich Hickey himself has commented on that in a recent bug report (http://dev.clojure.org/jira/browse/ASYNC-29?focusedCommentId=32414&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-32414).
Looking at the source-code of >! you will see that it only throws an exception. As a matter of fact, go will replace >! with different source-code. go spawns a state-machine controlled process. Depending on the context you may want to make this explicitly known or nest the go block inside of a macro or function (like in the code examples that you have provided).
Regarding David Nolens (swannodettes) helpers: They have been implemented by Rich Hickey and Nolen himself into the core.async library. Nolen said himself that they are superseded in this presentation (http://www.youtube.com/watch?v=AhxcGGeh5ho). Notice that go-loop has been implemented since after Nolens commit.