Search code examples
clojureplay-clj

"order of calls" inside another function


Trying to teach myself some clojure, am using play-clj. I dont understand why this works:

(defn add-shape
  [x y entities]
  (write-state [x y])
  (conj entities (o-shape x y)))

While this doesnt:

(defn add-shape
  [x y entities]
  (conj entities (o-shape x y)
  (write-state [x y]))

Exception in thread "LWJGL Application" java.lang.IllegalArgumentException:No implementation of method: :draw-entity! of protocol: #'play-clj.entities/Entity found for class: java.lang.Long

These are the two related functions:

(defn x-shape
  [x y] 
  (shape :line 
         :line (- x 100) (- 600 100 y) (+ x 100) (- (+ 600 100) y)
         :line (- x 100) (- (+ 600 100) y) (+ x 100) (- 600 100 y)))

(defn write-state
  [arg]
  (dosync (alter state conj arg)))

Solution

  • Pretty sure you have a misplaced paren in the second. Try this:

    (defn add-shape
      [x y entities]
      (conj entities (o-shape x y)) ;; This is effectively a no-op, results are not used.
      (write-state [x y]))  ;; returns the results of write-state, 
                            ;; ie the result of conj-ing [x y] onto the value in ref state 
    

    However, I now think the root of your problem is the two versions have different return values. Here's what the first returns:

    (defn add-shape
      [x y entities]
      (write-state [x y])
      (conj entities (o-shape x y))) ;; returns the results of conj-ing the results of (o-shape x y)
                                     ;; onto the passed-in value of entities
    

    TLDR: the functions return different values, your program probably only works with the results of your first.