I’m struggling to get all the pieces put together, partly because it’s my first time using deps instead of leiningen, and partly because I’m shaky on the differences between different types of REPLs (clojure.main vs nrepl, for example). The reason for this post is twofold:
- To get my own setup working
- To document how a Clojure beginner approaches this setup so that maybe some documentation can be tailored towards beginners
I went to the Reveal page, and under Give it a try there’s this configuration for deps.edn
:
:reveal {:extra-deps {vlaaad/reveal {:mvn/version "1.3.209"}}
:ns-default vlaaad.reveal
:exec-fn repl}
I put this in my ~/.clojure/deps.edn
because I thought it would be handy to use in multiple projects. At this point my user-level deps.edn
file looks like this:
{
:deps {org.clojure/clojure {:mvn/version "1.10.3"}}
:aliases {
:reveal {:extra-deps {vlaaad/reveal {:mvn/version "1.3.209"}}
:ns-default vlaaad.reveal
:exec-fn repl}}
}
Next I went to the Cursive integration page, and followed the instructions. At first I didn’t understand, and ended up leaving the “Aliases” field blank and put -m vlaaad/reveal repl
in the “Params” field. Eventually I figured out that I was doing something wrong and set up a run configuration like this:
At this point I think I’m ready to go, so I fire up my new “Reveal” run configuration, and try to load my project into the REPL. My directory structure looks like this:
src/
sketch/
sketch/
core.clj
dynamic.clj
deps.edn
The weird sketch/sketch
directory structure is a result of converting this from a Leiningen project and just accepting Cursive’s suggestion for how to move the files around. Not ideal, but not my main concern at the moment.
It’s a pretty simple project so far, here are the file contents:
deps.edn
{:paths ["src/sketch"]
:deps {quil/quil {:mvn/version "3.1.0"}}}
core.clj
(ns sketch.core
(:require [quil.core :as q]
[sketch.dynamic :as dynamic]))
(q/defsketch the-sketch
:title "Sketch"
:size [dynamic/d dynamic/d]
:setup dynamic/setup
:draw dynamic/draw
:settings #(do
(q/smooth)
(q/pixel-density 2)))
(defn refresh []
(use :reload 'sketch.dynamic)
(.loop the-sketch))
dynamic.clj
(ns sketch.dynamic
(:require [quil.core :as q]))
(def d 500)
(def win-rad (* 0.99 (/ d 2)))
(defn size
([] (size 1.0))
([x] (* x d)))
(defn noise-path
[]
(let [divs 100
nscale 0.01
mean-rad (q/random (* 0.1 win-rad) (* 0.95 win-rad))]
(reduce
(fn
[acc div]
(let [{:keys [last-x last-y]} acc
noise (q/noise
(* nscale last-x)
(* nscale last-y))
max-rad (* 1.25 mean-rad)
min-rad (* 0.75 mean-rad)
new-rad (q/map-range noise 0 1 min-rad max-rad)
angle (* q/TWO-PI (/ div divs))
new-x (* new-rad (q/cos angle))
new-y (* new-rad (q/sin angle))]
(-> acc
(assoc :last-x new-x)
(assoc :last-y new-y)
(update :vertices
(fn [vs] (cons [new-x new-y] vs))))
))
{:last-x (q/random 0 d)
:last-y (q/random 0 d)
:vertices nil}
(range divs))))
(defn render-path
[{:keys [vertices]}]
(let [vs (cons (last vertices)
(concat vertices
[(first vertices)]))]
(q/with-translation
[(/ d 2) (/ d 2)]
(q/with-rotation
[
;(q/random q/TWO-PI)
0
]
(q/begin-shape)
(doseq [[x y] vs]
(q/curve-vertex x y)
(if (> (q/random 1) 0.99)
(do
(q/no-stroke)
;(q/fill 9 26 100 0.5)
(q/fill 358 34 90 0.75)
(q/ellipse x y (/ d 50) (/ d 50))
(q/no-fill)
(q/stroke 9 26 100 0.3)))))
(q/end-shape :close))))
(defn setup []
(q/color-mode :hsb 360 100 100 1.0))
(defn draw []
(q/no-loop)
(q/random-seed 0)
(q/noise-seed 0)
(q/background 263 11 46)
(q/fill 9 26 100)
(q/ellipse (/ d 2) (/ d 2) (/ d 25) (/ d 25))
(q/stroke-weight (/ d 500))
(q/stroke 9 26 100 0.5)
(q/no-fill)
(doall
(repeatedly
1
#(render-path (noise-path))))
(q/save "sketch.png"))
When I run this configuration and load core.clj
, I see this error and no Reveal window, but the sketch does appear:
(load-file "/Users/zmitchell/code/generative_art/peony/sketch/src/sketch/sketch/core.clj")
Error evaluating - class java.lang.NullPointerException:
#'sketch.core/refresh
I see the same error when I try loading dynamic.clj
, at which point I realize it just hasn’t loaded either file. This error message doesn’t give me any information to go on, so I’m not sure where to go from here.