P5.js con Clojurescript

Las funciones de p5.js se llaman con el prefijo de javascript. Esto es, aunque al declarar el ns hagamos el require

(ns app
  (:require [p5]))

no llamamos a las funciones con p5 como prefijo

(p5/background 0)

sino con js

(js/background 0)

Si lo pensamos bien, esto es lo lógico, lo contrario sería incorrecto. En javascript haríamos background(0) sin importar nada, porque al cargar p5 se meten todas sus funciones en el objeto window. Y en clojurescript para llamar a esas funciones necesitamos especificar js a modo de ns, que es lo que estamos haciendo aquí.

Para poder llamar a estas funciones, hemos de estar dentro de alguna función. Esto es, si tengo un estado global, no puedo hacer

(def state (volatile! {:a (js/random 10 20)}))

Porque en ese punto en el nivel raíz del módulo sin haberse ejecutado aún setup no se han incluido las funciones de p5.js. Tendríamos que hacer

(def state (volatile! {:a nil}))

(defn setup []
  (vreset! state {:a (js/random 10 20)})) ;; Podríamos hacer vswap! del atributo `:a` del map

Variables globales

Para gestionar las variables globales lo que me ha venido mejor es

volatile!

Similar a atom pero más ligero, no pueden añadírsele centinelas/vigías.

^:dynamic

Variables a las que puedo modificar el valor en ciertos ámbitos con binding:

(def ^:dynamic *value*)

(defn bar []
  (println *value*))

(defn foo []
  (binding [*value* lala]
    (bar)))

Cualquier uso puede modificarse pasando el parámetro a la función realmente, pero viene bien en ciertos casos.