I'm learning Clojure to use it with Quil to make generative art and I would like to try to understand a bit more about let function and reader macro probably.
I tried reading about reader macros from the docs but I couldn't find a clear answer to it.
I currently have this piece of code:
(let [dabs (take 10 (repeatedly #(make-watercolor
(mkpt
(randomNormal 0.1 0.9)
(randomNormal 0.1 0.9))
(w (randomNormal 0.4 0.7)))))]
(draw-multiple-watercolor dabs 3))
Which is pretty ugly and not really readable. I would like to slim down the repeated function splitting it into smaller pieces, but since those pieces will be evaluated multiple times and has random inside them I cannot store their result inside a variable and use that, instead I need to evaluate those when needed.
My question is: is there a way to do something like this
(let [randCoord (randomNormal 0.1 0.9) ;This..
randPoint (mkpt randCoord randCoord) ;..and this doesn't should be evaluated here, but on the repeatedly function calls
dabs (take 10 (repeatedly #(make-watercolor
randPoint ;Evaluation here
(w (randomNormal 0.4 0.7)))))]
(draw-multiple-watercolor dabs 3))
One option is to use the same approach you've used with the function you pass to
repeatedly: just wrap the expressions in functions that take no arguments (or only the args you want to change), then they'll be evaluated each time you invoke the function.Also take a look at
letfnfor defining functions in a non-top-level/namespace scope.You might also find threading macros like
->,->>,as->,some->,cond->, etc. can make some code more readable. For example, if you changeddraw-multiple-watercolorto take its sequence of dabs last (which is fairly common practice for functions that operate on sequences in Clojure) then you could do something like this: