working my way up learning Clojure I arrived at the following problem:
setup: A class for a graph data structure, created with deftype
and definterface
which has a addNode [id data] member function. Works as expected when called directly, like (.addNode graph "anItem" 14)
idea: Since string tokenizing and updating the graph both consume considerable amounts of time (at least for millions of lines), I would like to read and tokenize the file serially and push the token lists to an agent which will execute the `(.addNode graph id data) part.
problem: I can't seem to find the right syntax to make the agent accept a class instance's member function as update function.
Simplified code (dropped namespaces here, may contain typos!):
; from graph.clj
(definterface IGraph
(addNode [id data])
(addNode2 [_ id data]))
(deftype Graph [^:volatile-mutable nodes] ; expects an empty map, else further calls fail horribly
IGraph
(addNode [this id data] (set! nodes (assoc nodes id data)) this)
(addNode2 [this _ id data] (.addNode this id data) this))
; core.clj
(def g (Graph. {}))
(def smith (agent g)) ; agent smith shall do the dirty work
(send smith .addNode "x" 42) ; unable to resolve symbol
(send smith (.addNode @smith) "x" 42) ; IllegalArgumentException (arity?)
(send smith (.addNode2 @smith) "x" 42) ; same as above. Not arity after all?
(send smith #(.addNode @smith) "x" 42) ; ArityException of eval (3)
(send smith (partial #(.addNode @smith)) "x" 42) ; the same
; agent smith, the president is ashamed...
The five lines won't work for various reasons, while a simple
(def jones (agent 0))
(send jones + 1)
; agent jones, this nation is in your debt
successfully executes. This should be possible, so what am I doing wrong?