Eh, nevermind, I refactored things a bit, and I'm happier now. Sorry
for the noise.

;;;;;;;;;;;;;;;;; base ;;;;;;;;;;;;;;;;;;;;;;;;
(defrecord Entity [id asset location data])
(defrecord Farmer [entity])

(defn get-entity-by-key
  ([] (fn [this] (:entity this)))
  ([key] (fn [this] (key this))))

(defprotocol Inspectable
  (inspect [_])
  (get-entity [_]))

(defn base-inspect [this]
  (let [e (get-entity this)]
    (println "entity" (:id this) "@" (:location e) (:data e))))

(def base-behavior {
  :get-entity (fn [this] this)
  :inspect base-inspect
})

(extend Entity
  Inspectable
  base-behavior)

;;;;;;;;;;;;;;;;; survival ;;;;;;;;;;;;;;;;;;;;;;;;
(defprotocol Survive
  (find-food [_]))

(defn base-survive [this]
  (let [e (get-entity this)]
    (println "entity" (:id e) "looking for food")))

(def survival-behavior {
  :find-food base-survive
})

;;;;;;;;;;;;;;;;; farmer ;;;;;;;;;;;;;;;;;;;;;;;;
(extend Farmer
  Inspectable
  (merge base-behavior {:get-entity (get-entity-by-key)})
  Survive survival-behavior)


On Dec 6, 3:08 pm, tmountain <tinymount...@gmail.com> wrote:
> Hi, I'm playing around with protocols and records and trying to
> implement some ad-hoc type composition. I have a solution that works,
> but I want to make it more readable. Specifically, if you look at the
> code below, I'd like to come up with a macro or some other solution to
> eliminate all the calls to (get-this this). Ideally, I could just say
> something like (:id (self)) or something along those lines. The
> reasoning for having a get-this method should become evident as your
> read the code. It's basically an abstraction for calling derived
> behaviors.
>
> (defrecord Entity [id asset location data])
> (defrecord Farmer [entity])
>
> (defprotocol Inspectable
>   (inspect [_])
>   (get-this [_]))
>
> (defprotocol Survive
>   (find-food [_]))
>
> (defn base-inspect [this]
>   (println "entity" (:id this) "@" (:location (get-this this)) (:data
> (get-this this))))
>
> (def base-behavior {
>   :get-this (fn [this] this)
>   ;:inspect (fn [this] (println "entity" (:id this) "@" (:location
> (get-this this)) (:data (get-this this))))
>   :inspect base-inspect
>
> })
>
> (extend Entity
>   Inspectable
>   base-behavior)
>
> (def survival-behavior {
>   :find-food (fn [this] (println "entity" (:id (get-this this))
> "looking for food"))
>
> })
>
> (extend Farmer
>   Inspectable
>   (merge base-behavior {:get-this (fn [this] (:entity this))})
>   Survive survival-behavior)
>
> (def thing (Entity. 1 :foo [0, 0] {}))
> (inspect thing)
> (def farmer (Farmer. thing))
> (find-food farmer)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to