Quil claiming my draw function has 0 arguments - clojure

I'm trying to write my first simple graphics app using Quil. Right now, I'm just trying to draw a dot that moves diagonally across the screen.
(ns quil-test.quil-first
(:require [quil.core :as q])
(:gen-class))
(defn setup-state []
(q/frame-rate 60)
{:x 0})
(defn update-state [s]
(assoc s :x (q/frame-count)))
(defn draw-state [state]
(let [x (:x state)]
(q/stroke-weight 100)
(q/point x x)))
(q/defsketch quil-first
:size [500 500]
:setup setup-state
:update update-state
:draw draw-state)
The problem is, running this doesn't show a dot, and the following error is repeatedly printed to the console:
Exception in :draw function: #error {
:cause Wrong number of args (0) passed to: quil-first/draw-state
:via
[{:type clojure.lang.ArityException
:message Wrong number of args (0) passed to: quil-first/draw-state
:at [clojure.lang.AFn throwArity AFn.java 429]}]
:trace
[[clojure.lang.AFn throwArity AFn.java 429]
[clojure.lang.AFn invoke AFn.java 28]
[clojure.lang.Var invoke Var.java 375]
[quil.middlewares.safe_fns$wrap_fn$fn__114 invoke safe_fns.clj 9]
[quil.middlewares.bind_output$bind_output$iter__148__152$fn__153$fn__164 invoke bind_output.clj 21]
[quil.applet$_draw invoke applet.clj 220]
[quil.Applet draw nil -1]
[processing.core.PApplet handleDraw PApplet.java 2402]
[quil.Applet handleDraw nil -1]
[processing.awt.PSurfaceAWT$12 callDraw PSurfaceAWT.java 1527]
[processing.core.PSurfaceNone$AnimationThread run PSurfaceNone.java 316]]}
stacktrace: clojure.lang.ArityException: Wrong number of args (0) passed to: quil-first/draw-state
at clojure.lang.AFn.throwArity (AFn.java:429)
clojure.lang.AFn.invoke (AFn.java:28)
clojure.lang.Var.invoke (Var.java:375)
quil.middlewares.safe_fns$wrap_fn$fn__114.invoke (safe_fns.clj:9)
quil.middlewares.bind_output$bind_output$iter__148__152$fn__153$fn__164.invoke (bind_output.clj:21)
quil.applet$_draw.invoke (applet.clj:220)
quil.Applet.draw (:-1)
processing.core.PApplet.handleDraw (PApplet.java:2402)
quil.Applet.handleDraw (:-1)
processing.awt.PSurfaceAWT$12.callDraw (PSurfaceAWT.java:1527)
processing.core.PSurfaceNone$AnimationThread.run (PSurfaceNone.java:316)
It's saying that my draw-state function takes 0 arguments, when it should take 1. draw-state clearly takes 1 argument though.
I don't understand why draw-state is somehow being "converted" into a 0-arity function.

The problem is I didn't activate "fun(ctional) mode", so the draw function expected to take 0 arguments, since by default state is managed globally.
This works:
(ns quil-test.quil-first
(:require [helpers.general-helpers :as g]
[quil.core :as q]
[quil.middleware :as m])
(:gen-class))
(defn setup-state []
(q/frame-rate 60)
{:x 0})
(defn update-state [s]
(g/update-with s :x (fn [_] (q/frame-count))))
(defn draw-state [state]
(let [x (:x state)]
(q/stroke-weight 100)
(q/point x x)))
(q/defsketch quil-first
:size [500 500]
:setup setup-state
:update update-state
:draw draw-state
:middleware [m/fun-mode]) ; Activate functional mode

Related

How to test a function created with intern in clojure?

I use "intern" function for generate runtime funtions, but I can't test generted function.
In core.clj I defined functions that generate runtime functions like this.
(ns cftf.core)
(defn- generation-function [function-name ratio]
(let [function-symbol (symbol function-name)]
(intern 'cftf.core function-symbol (fn [input] (cftf.core/convert ratio input)))))
...
(defn generate-function-by-units [units]
(->> units
(units->function-name-and-ratio)
(map #(generation-function (first %) (second %)))))
I wrote the following test code.
(ns cftf.core-test
(:require [clojure.test :refer :all]
[cftf.core :as c]))
(defn amount-of-alcohol-per-one-bottle [bottle-size abv]
(* bottle-size (/ abv 100)))
(def alcohol-units
{:soju (amount-of-alcohol-per-one-bottle 360 16.5)
:beer (amount-of-alcohol-per-one-bottle 500 5)
:whisky (amount-of-alcohol-per-one-bottle 700 40)
})
(c/generate-function-by-units alcohol-units)
(deftest a-test
(testing "soju->beer test"
(is (= (int (c/soju->beer 1)) 2))))
After calling "generate-function-by-units" in the repl, you can use the "soju->beer" function.
But in the test I get the error "No such var: c/soju->beer".
I've tried using a fixture or calling " generate-function-by-units" the top in test.clj, but I'm still getting the error.

How to schedule a list of functions `n` seconds apart with Clojure Core Async

In my Clojure project I'm trying to make a list of http calls to an API that has a rate limiter that only allows n calls per minute. I want each of the responses to be returned once all the http calls are finished for further processing. I am new to Clojure's Core Async, but thought it would be a good fit, but because I need to run each call n seconds apart I am also trying to use the Chime library. In Chime's library it has examples using Core Async, but the examples all call the same function at each time interval which won't work for this use case.
While there is probably a way to use chime-async that better serves this use case, all of my attempts at that have failed so I've tried simply wrapping Chime calls with core async, but I am probably more baffled by Core Async than Chime.
This is an example of my name space.
(ns mp.util.schedule
(:require [chime.core :as chime]
[clojure.core.async :as a]
[tick.alpha.api :as tick]))
(defn schedule-fns
"Takes a list of functions and a duration in seconds then runs each function in the list `sec` seconds apart
optionally provide an inst to start from"
[fs sec & [{:keys [inst] :or {inst (tick/now)}}]]
(let [ch (a/chan (count fs))
chime-times (map-indexed
(fn mapped-fn [i f]
(a/put! ch (chime/chime-at [(.plusSeconds inst (* i sec))]
(fn wrapped-fn [_] (f)))))
fs)]
(doseq [chi chime-times]
(a/<!! chi))))
; === Test Code ===
; simple test function
(defn sim-fn
"simple function that prints a message and value, then returns the value"
[v m]
(println m :at (tick/now))
v)
; list of test functions
(def fns [#(sim-fn 1 :one)
#(sim-fn 2 :two)
#(sim-fn 3 :three)])
What I want to happen when calling (schedule-fns fns 2) is for each function in fns to run n seconds from each other and for schedule-fns to return (1 2 3) (the return values of the functions), but this isn't what it is doing. It is calling each of the functions at the correct times (which I can see from the log statements) but it isn't returning anything and there's an error I don't understand. I'm getting:
(schedule-fns fns 2)
:one :at #time/instant "2021-03-05T23:31:52.565Z"
Execution error (IllegalArgumentException) at clojure.core.async.impl.protocols/eval11496$fn$G (protocols.clj:15).
No implementation of method: :take! of protocol: #'clojure.core.async.impl.protocols/ReadPort found for class: java.lang.Boolean
:two :at #time/instant "2021-03-05T23:31:54.568Z"
:three :at #time/instant "2021-03-05T23:31:56.569Z"
If I could get help getting my code to use Core Async properly (with or without Chime) I'd really appreciate it. Thanks.
Try this:
(defn sim-fn
"simple function that prints a message and value, then returns the value"
[v m]
(println m)
v)
; list of test functions
(def fns [#(sim-fn 1 :one)
#(sim-fn 2 :two)
#(sim-fn 3 :three)])
(defn schedule-fns [fns sec]
(let [program (interpose #(Thread/sleep (* sec 1000))
fns)]
(remove #(= % nil)
(for [p program]
(p)))))
Then call:
> (schedule-fns fns 2)
:one
:two
:three
=> (1 2 3)
I came up with a way to get what I want...with some caveats.
(def results (atom []))
(defn schedule-fns
"Takes a list of functions and a duration in seconds then runs each function in the list `sec` seconds apart
optionally provide an inst to start from"
[fs sec]
(let [ch (chan (count fs))]
(go-loop []
(swap! results conj (<! ch))
(recur))
(map-indexed (fn [i f]
(println :waiting (* i sec) :seconds)
(go (<! (timeout (* i sec 1000)))
(>! ch (f))))
fs)))
This code has the timing and behavior that I want, but I have to use an atom to store the responses. While I can add a watcher to determine when all the results are in, I still feel like I shouldn't have to do that.
I guess I'll use this for now, but at some point I'll keep working on this and if anyone has something better than this approach I'd love to see it.
I had a couple friends look at this and they each came up with different answers. These are certainly better than what I was doing.
(defn schedule-fns [fs secs]
(let [ret (atom {})
sink (a/chan)]
(doseq [[n f] (map-indexed vector fs)]
(a/thread (a/<!! (a/timeout (* 1000 n secs)))
(let [val (f)
this-ret (swap! ret assoc n val)]
(when (= (count fs) (count this-ret))
(a/>!! sink (mapv (fn [i] (get this-ret i)) (range (count fs))))))))
(a/<!! sink)))
and
(defn schedule-fns
[fns sec]
(let [concurrent (count fns)
output-chan (a/chan)
timedout-coll (map-indexed (fn [i f]
#(do (println "Waiting")
(a/<!! (a/timeout (* 1000 i sec)))
(f))) fns)]
(a/pipeline-blocking concurrent
output-chan
(map (fn [f] (f)))
(a/to-chan timedout-coll))
(a/<!! (a/into [] output-chan))))
If your objective is to work around the rate limiter, you can consider implementing it in the async channel. Below is one sample implementation - the function takes a channel, throttled its input with a token based limiter and pipe it to an output channel.
(require '[clojure.core.async :as async])
(defn rate-limiting-ch [input xf rate]
(let [tokens (numerator rate)
period (denominator rate)
ans (async/chan tokens xf)
next (fn [] (+ period (System/currentTimeMillis)))]
(async/go-loop [c tokens
t (next)]
(if (zero? c)
(do
(async/<! (async/timeout (- t (System/currentTimeMillis))))
(recur tokens (next)))
(when-let [x (async/<! input)]
(async/>! ans x)
(recur (dec c) t))))
ans))
And here is a sample usage:
(let [start (System/currentTimeMillis)
input (async/to-chan (range 10))
output (rate-limiting-ch input
;; simulate an api call with roundtrip time of ~300ms
(map #(let [wait (rand-int 300)
ans {:time (- (System/currentTimeMillis) start)
:wait wait
:input %}]
(Thread/sleep wait)
ans))
;; rate limited to 2 calls per 1000ms
2/1000)]
;; consume the output
(async/go-loop []
(when-let [x (async/<! output)]
(println x)
(recur))))
Output:
{:time 4, :wait 63, :input 0}
{:time 68, :wait 160, :input 1}
{:time 1003, :wait 74, :input 2}
{:time 1079, :wait 151, :input 3}
{:time 2003, :wait 165, :input 4}
{:time 2169, :wait 182, :input 5}
{:time 3003, :wait 5, :input 6}
{:time 3009, :wait 18, :input 7}
{:time 4007, :wait 138, :input 8}
{:time 4149, :wait 229, :input 9}

Dispatching function calls on different formats of maps

I'm writing an agar.io clone. I've lately seen a lot of suggestions to limit use of records (like here), so I'm trying to do the whole project only using basic maps.*
I ended up creating constructors for different "types" of bacteria like
(defn new-bacterium [starting-position]
{:mass 0,
:position starting-position})
(defn new-directed-bacterium [starting-position starting-directions]
(-> (new-bacterium starting-position)
(assoc :direction starting-directions)))
The "directed bacterium" has a new entry added to it. The :direction entry will be used to remember what direction it was heading in.
Here's the problem: I want to have one function take-turn that accepts the bacterium and the current state of the world, and returns a vector of [x, y] indicating the offset from the current position to move the bacterium to. I want to have a single function that's called because I can think right now of at least three kinds of bacteria that I'll want to have, and would like to have the ability to add new types later that each define their own take-turn.
A Can-Take-Turn protocol is out the window since I'm just using plain maps.
A take-turn multimethod seemed like it would work at first, but then I realized that I'd have no dispatch values to use in my current setup that would be extensible. I could have :direction be the dispatch function, and then dispatch on nil to use the "directed bacterium"'s take-turn, or default to get the base aimless behavior, but that doesn't give me a way of even having a third "player bacterium" type.
The only solution I can think of it to require that all bacterium have a :type field, and to dispatch on it, like:
(defn new-bacterium [starting-position]
{:type :aimless
:mass 0,
:position starting-position})
(defn new-directed-bacterium [starting-position starting-directions]
(-> (new-bacterium starting-position)
(assoc :type :directed,
:direction starting-directions)))
(defmulti take-turn (fn [b _] (:type b)))
(defmethod take-turn :aimless [this world]
(println "Aimless turn!"))
(defmethod take-turn :directed [this world]
(println "Directed turn!"))
(take-turn (new-bacterium [0 0]) nil)
Aimless turn!
=> nil
(take-turn (new-directed-bacterium [0 0] nil) nil)
Directed turn!
=> nil
But now I'm back to basically dispatching on type, using a slower method than protocols. Is this a legitimate case to use records and protocols, or is there something about mutlimethods that I'm missing? I don't have a lot of practice with them.
* I also decided to try this because I was in the situation where I had a Bacterium record and wanted to create a new "directed" version of the record that had a single field direction added to it (inheritance basically). The original record implemented protocols though, and I didn't want to have to do something like nesting the original record in the new one, and routing all behavior to the nested instance. Every time I created a new type or changed a protocol, I would have to change all the routing, which was a lot of work.
You can use example-based multiple dispatch for this, as explained in this blog post. It is certainly not the most performant way to solve this problem, but arguably more flexible than multi-methods as it does not require you to declare a dispatch-method upfront. So it is open for extension to any data representation, even other things than maps. If you need performance, then multi-methods or protocols as you suggest, is probably the way to go.
First, you need to add a dependency on [bluebell/utils "1.5.0"] and require [bluebell.utils.ebmd :as ebmd]. Then you declare constructors for your data structures (copied from your question) and functions to test those data strucutres:
(defn new-bacterium [starting-position]
{:mass 0
:position starting-position})
(defn new-directed-bacterium [starting-position starting-directions]
(-> (new-bacterium starting-position)
(assoc :direction starting-directions)))
(defn bacterium? [x]
(and (map? x)
(contains? x :position)))
(defn directed-bacterium? [x]
(and (bacterium? x)
(contains? x :direction)))
Now we are going to register those datastructures as so called arg-specs so that we can use them for dispatch:
(ebmd/def-arg-spec ::bacterium {:pred bacterium?
:pos [(new-bacterium [9 8])]
:neg [3 4]})
(ebmd/def-arg-spec ::directed-bacterium {:pred directed-bacterium?
:pos [(new-directed-bacterium [9 8] [3 4])]
:neg [(new-bacterium [3 4])]})
For each arg-spec, we need to declare a few example values under the :pos key, and a few non-examples under the :neg key. Those values are used to resolve the fact that a directed-bacterium is more specific than just a bacterium in order for the dispatch to work properly.
Finally, we are going to define a polymorphic take-turn function. We first declare it, using declare-poly:
(ebmd/declare-poly take-turn)
And then, we can provide different implementations for specific arguments:
(ebmd/def-poly take-turn [::bacterium x
::ebmd/any-arg world]
:aimless)
(ebmd/def-poly take-turn [::directed-bacterium x
::ebmd/any-arg world]
:directed)
Here, the ::ebmd/any-arg is an arg-spec that matches any argument. The above approach is open to extension just like multi-methods, but does not require you to declare a :type field upfront and is thus more flexible. But, as I said, it is also going to be slower than both multimethods and protocols, so ultimately this is a trade-off.
Here is the full solution: https://github.com/jonasseglare/bluebell-utils/blob/archive/2018-11-16-002/test/bluebell/utils/ebmd/bacteria_test.clj
Dispatching a multimethod by a :type field is indeed polymorphic dispatch that could be done with a protocol, but using multimethods allows you to dispatch on different fields. You can add a second multimethod that dispatches on something other than :type, which might be tricky to accomplish with a protocol (or even multiple protocols).
Since a multimethod can dispatch on anything, you could use a set as the dispatch value. Here's an alternative approach. It's not fully extensible, since the keys to select are determined within the dispatch function, but it might give you an idea for a better solution:
(defmulti take-turn (fn [b _] (clojure.set/intersection #{:direction} (set (keys b)))))
(defmethod take-turn #{} [this world]
(println "Aimless turn!"))
(defmethod take-turn #{:direction} [this world]
(println "Directed turn!"))
Fast paths exist for a reason, but Clojure doesn't stop you from doing anything you want to do, per say, including ad hoc predicate dispatch. The world is definitely your oyster. Observe this super quick and dirty example below.
First, we'll start off with an atom to store all of our polymorphic functions:
(def polies (atom {}))
In usage, the internal structure of the polies would look something like this:
{foo ; <- function name
{:dispatch [[pred0 fn0 1 ()] ; <- if (pred0 args) do (fn0 args)
[pred1 fn1 1 ()]
[pred2 fn2 2 '&]]
:prefer {:this-pred #{:that-pred :other-pred}}}
bar
{:dispatch [[pred0 fn0 1 ()]
[pred1 fn1 3 ()]]
:prefer {:some-pred #{:any-pred}}}}
Now, let's make it so that we can prefer predicates (like prefer-method):
(defn- get-parent [pfn x] (->> (parents x) (filter pfn) first))
(defn- in-this-or-parent-prefs? [poly v1 v2 f1 f2]
(if-let [p (-> #polies (get-in [poly :prefer v1]))]
(or (contains? p v2) (get-parent f1 v2) (get-parent f2 v1))))
(defn- default-sort [v1 v2]
(if (= v1 :poly/default)
1
(if (= v2 :poly/default)
-1
0)))
(defn- pref [poly v1 v2]
(if (-> poly (in-this-or-parent-prefs? v1 v2 #(pref poly v1 %) #(pref poly % v2)))
-1
(default-sort v1 v2)))
(defn- sort-disp [poly]
(swap! polies update-in [poly :dispatch] #(->> % (sort-by first (partial pref poly)) vec)))
(defn prefer [poly v1 v2]
(swap! polies update-in [poly :prefer v1] #(-> % (or #{}) (conj v2)))
(sort-disp poly)
nil)
Now, let's create our dispatch lookup system:
(defn- get-disp [poly filter-fn]
(-> #polies (get-in [poly :dispatch]) (->> (filter filter-fn)) first))
(defn- pred->disp [poly pred]
(get-disp poly #(-> % first (= pred))))
(defn- pred->poly-fn [poly pred]
(-> poly (pred->disp pred) second))
(defn- check-args-length [disp args]
((if (= '& (-> disp (nth 3) first)) >= =) (count args) (nth disp 2)))
(defn- args-are? [disp args]
(or (isa? (vec args) (first disp)) (isa? (mapv class args) (first disp))))
(defn- check-dispatch-on-args [disp args]
(if (-> disp first vector?)
(-> disp (args-are? args))
(-> disp first (apply args))))
(defn- disp*args? [disp args]
(and (check-args-length disp args)
(check-dispatch-on-args disp args)))
(defn- args->poly-fn [poly args]
(-> poly (get-disp #(disp*args? % args)) second))
Next, let's prepare our define macro with some initialization and setup functions:
(defn- poly-impl [poly args]
(if-let [poly-fn (-> poly (args->poly-fn args))]
(-> poly-fn (apply args))
(if-let [default-poly-fn (-> poly (pred->poly-fn :poly/default))]
(-> default-poly-fn (apply args))
(throw (ex-info (str "No poly for " poly " with " args) {})))))
(defn- remove-disp [poly pred]
(when-let [disp (pred->disp poly pred)]
(swap! polies update-in [poly :dispatch] #(->> % (remove #{disp}) vec))))
(defn- til& [args]
(count (take-while (partial not= '&) args)))
(defn- add-disp [poly poly-fn pred params]
(swap! polies update-in [poly :dispatch]
#(-> % (or []) (conj [pred poly-fn (til& params) (filter #{'&} params)]))))
(defn- setup-poly [poly poly-fn pred params]
(remove-disp poly pred)
(add-disp poly poly-fn pred params)
(sort-disp poly))
With that, we can finally build our polies by rubbing some macro juice on there:
(defmacro defpoly [poly-name pred params body]
`(do (when-not (-> ~poly-name quote resolve bound?)
(defn ~poly-name [& args#] (poly-impl ~poly-name args#)))
(let [poly-fn# (fn ~(symbol (str poly-name "-poly")) ~params ~body)]
(setup-poly ~poly-name poly-fn# ~pred (quote ~params)))
~poly-name))
Now you can build arbitrary predicate dispatch:
;; use defpoly like defmethod, but without a defmulti declaration
;; unlike defmethods, all params are passed to defpoly's predicate function
(defpoly myinc number? [x] (inc x))
(myinc 1)
;#_=> 2
(myinc "1")
;#_=> Execution error (ExceptionInfo) at user$poly_impl/invokeStatic (REPL:6).
;No poly for user$eval187$myinc__188#5c8eee0f with ("1")
(defpoly myinc :poly/default [x] (inc x))
(myinc "1")
;#_=> Execution error (ClassCastException) at user$eval245$fn__246/invoke (REPL:1).
;java.lang.String cannot be cast to java.lang.Number
(defpoly myinc string? [x] (inc (read-string x)))
(myinc "1")
;#_=> 2
(defpoly myinc
#(and (number? %1) (number? %2) (->> %& (filter (complement number?)) empty?))
[x y & z]
(inc (apply + x y z)))
(myinc 1 2 3)
;#_=> 7
(myinc 1 2 3 "4")
;#_=> Execution error (ArityException) at user$poly_impl/invokeStatic (REPL:5).
;Wrong number of args (4) passed to: user/eval523/fn--524
; ^ took the :poly/default path
And when using your example, we can see:
(defn new-bacterium [starting-position]
{:mass 0,
:position starting-position})
(defn new-directed-bacterium [starting-position starting-directions]
(-> (new-bacterium starting-position)
(assoc :direction starting-directions)))
(defpoly take-turn (fn [b _] (-> b keys set (contains? :direction)))
[this world]
(println "Directed turn!"))
;; or, if you'd rather use spec
(defpoly take-turn (fn [b _] (->> b (s/valid? (s/keys :req-un [::direction])))
[this world]
(println "Directed turn!"))
(take-turn (new-directed-bacterium [0 0] nil) nil)
;#_=> Directed turn!
;nil
(defpoly take-turn :poly/default [this world]
(println "Aimless turn!"))
(take-turn (new-bacterium [0 0]) nil)
;#_=> Aimless turn!
;nil
(defpoly take-turn #(-> %& first :show) [this world]
(println :this this :world world))
(take-turn (assoc (new-bacterium [0 0]) :show true) nil)
;#_=> :this {:mass 0, :position [0 0], :show true} :world nil
;nil
Now, let's try using isa? relationships, a la defmulti:
(derive java.util.Map ::collection)
(derive java.util.Collection ::collection)
;; always wrap classes in a vector to dispatch off of isa? relationships
(defpoly foo [::collection] [c] :a-collection)
(defpoly foo [String] [s] :a-string)
(foo [])
;#_=> :a-collection
(foo "bob")
;#_=> :a-string
And of course we can use prefer to disambiguate relationships:
(derive ::rect ::shape)
(defpoly bar [::rect ::shape] [x y] :rect-shape)
(defpoly bar [::shape ::rect] [x y] :shape-rect)
(bar ::rect ::rect)
;#_=> :rect-shape
(prefer bar [::shape ::rect] [::rect ::shape])
(bar ::rect ::rect)
;#_=> :shape-rect
Again, the world's your oyster! There's nothing stopping you from extending the language in any direction you want.

How can I use with-redefs to mock multiple calls to the same function?

I would like to be able to mock MyFunction however I need the mock to return different values when MyFunction is called.
Is it possible to use with-redefs to return different values based on the call order of a function?
(testing "POST /foo/bar and return ok"
(with-redefs [->Baz (fn [_]
(reify MyProtocol (MyFunction [_] [{:something 1}]))
(reify MyProtocol (MyFunction [_] [{:something 2}])))]
(let [response (routes/foo {:request-method :post
:uri "/foo/bar"
:query-params {}
})]
(is (= (:status response) 200)))))
You could use a mutable collection of the return values, then return/remove values from it on each call.
(defn foo [x] (inc x)) ;; example fn to be mocked
If you wanted to mock three calls to foo returning 1, 2, and 3 respectively:
(with-redefs [foo (let [results (atom [1 2 3])]
(fn [_] (ffirst (swap-vals! results rest))))]
(prn (foo 0))
(prn (foo 0))
(prn (foo 0))
;; additional calls would return nil
(prn (foo 0)))
;; 1
;; 2
;; 3
;; nil
That uses swap-vals! to get the old/new values of the atom, but requires Clojure 1.9 or greater.
If you don't have swap-vals! you could do it (less atomically) like this:
(with-redefs [foo (let [results (atom [1 2 3])]
(fn [_]
(let [result (first #results)]
(swap! results rest)
result)))]
...)
We use Picomock for this, and to assert on the parameters for each call, and to assert on the number of calls. Recommended!

Update state with if on Quil

I am trying to make 10 PRINT code with Quil. I try to transform this code from the twitter post https://twitter.com/ACharLuk/status/913094845505445890 which is using luna
This is my code for it
(ns tenprint.core
(:require [quil.core :as q]
[quil.middleware :as m]))
(defn setup []
(q/frame-rate 30)
(q/color-mode :hsb)
{:x 0
:y 0
:scale 20
}
)
(defn update-state [state]
(let [x (:x state) y (:y state) s (:scale state)]
{
:x (do (+ x s) ((if (>= x q/width) 0)))
:y (do (if (>= x q/width) (+ y s)) (if (>= x q/height) (+ y s)))
:scale (+ s 0)
}
)
)
(defn draw-state [state]
(q/background 0)
(q/stroke 255)
;(q/line 0 10 10 0)
(let [x (:x state) y (:y state) s (:scale state)]
(if (> (rand) 0.5)
(q/line x y (+ x s) (+ y s))
(q/line x (+ y s) (+ x s) y)
)
)
)
(q/defsketch tenprint
:title "10PRINT"
:size [500 500]
:setup setup
:update update-state
:draw draw-state
:settings #(q/smooth 2)
:features [:keep-on-top]
:middleware [m/fun-mode]
)
And it just appears like this. I was trying to split the update of states, but it says that you must not have duplicated variables to be updated
Thank you.
Your code is in the right direction and you managed to draw the first line. It crashed when update-state was called. To fix the code I did the following things:
Clojure works with pure functions where you cannot "set" values as you seem to wanted to do in update-state (with do only the last expression is returned, not two values). To update-state you need to return a whole new state.
q/height and q/widths are functions that return the height and width, so call them (surround them by parentheses) to get the number out.
When you redraw the background in update-state the older lines are gone, so put (q/background 0) in setup.
Move (q/no-loop) from update-state to the draw-state entry-point of the program.
And stylistically I changed this:
Use associative destructuring in function parameter instead of getting values of keys in let.
Place trailing parentheses on the same line (see Clojure style guide).
Below the working version:
(ns tenprint.core
(:require [quil.core :as q]
[quil.middleware :as m]))
(defn setup []
(q/background 0) ; move setting background to setup, otherwise the state is overwritten
(q/frame-rate 30)
(q/stroke 255)
(q/color-mode :hsb)
{:x 0
:y 0
:scale 20})
(defn update-state [{:keys [x y scale] :as state}] ; destructure
;; height and width are functions you need to `(call)` to get the value
{:x (if (>= x (q/width)) 0 (+ x scale)) ; fix if-statements
:y (if (>= x (q/width)) (+ y scale) y) ; 'do' does something different than you think
:scale scale}) ; no need to add 0
(defn draw-state [{:keys [x y scale] :as state}] ; destructure
(if (>= y (q/height))
(q/no-loop)
(if (> (rand) 0.5)
(q/line x y (+ x scale) (+ y scale))
(q/line x (+ y scale) (+ x scale) y))))
(q/defsketch tenprint
:title "10 PRINT"
:size [500 500]
:setup setup
:draw draw-state
:update update-state
:features [:keep-on-top]
:middleware [m/fun-mode])