Oskar <oskar.kv...@gmail.com> writes: > I have not heard much about records and protocols. What is a typical > use case in idiomatic Clojure code for them? Is it a good idea, for > example, to make a "Character" protocol and "Player" and "Monster" > records or something in a game. It feels a bit too much like OOP for > me to be comfortable with it, but I can't immediately see why that > would be bad. I just don't know how they are supposed to be used.
The primary purpose of protocols is efficient, extensible polymorphism: handling different data types using a uniform interface. Rather than a composite idea like "Character" it is preferable to use many fine-grained protocols that each cover a single indivisible concept. Depending on the mechanics in your game you might have protocols like Damagable, Listener, Throwable, Describable, Capturable, Clickable, Edible, Castable and Container. (defprotocol Damagable (alive? [damagable]) (damage [damagable weapon])) (defprotocol Describable (describe [describable])) (defrecord Monster [strength color] Damagable (alive? [m] (pos? health) (damage [m weapon] (update-in m [:health] - (weapon :power)))) Describable (describe [m] (str (if (> health 90) "a healthy " "an injured ") (if (> strength 50) "powerful " "weak ") color " monster"))) (defrecord Tree [age species] Describable (describe [t] (str (when (> age 100) "an ancient " "a ") species " tree"))) One of the lovely things about protocols is that they are very extensible. Suppose you want to write some graphics code for drawing different game entities. You can define a rendering protocol and extend it to your entities all in a different file. You don't have to clutter up your game logic files with the ugly drawing code. ;; gfx.clj (ns game.gfx (:require [game.enemies :as enemies] [game.scenary :as scenary])) (defprotocol Renderable (paint [x canvas]) (pixel-width [x])) (extend-protocol Renderable scenary/Rock (paint [tree canvas] (blit canvas "rock.png")) (pixel-width [tree] 30) scenary/Tree (paint [tree canvas] (blit canvas "tree.png")) (pixel-width [tree] 150) enemies/Monster (paint [m canvas] (blit canvas (get icons (:activity m)))) (pixel-width [m] 70)) -- 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