Thank you Alex and abp! Your posts certainly contains valuable information. But I have questions still. One might say that you explained how to use protocols, but the questions I have left are: Why protocols (and records)? What benefits do I get? Alex mentioned polymorphism; how is this different from/related to multimethods?
Let's take the game example again. Say I have (which I do) a map of characters in my game that contains both monsters and players. A monster: {:type :mob :pos [x y] :hp 30 :max-hp 30 :dmg 5 :name "an orc pawn" :attacking false :last-attack 0 :attack-delay 1500 :target nil :path nil :speed 2.5 :ai ai/attack-nearest} A player: {:type :player :name "Bill" :pos [0 0] :hp 100 :max-hp 100 :dmg 10 :attacking false :last-attack 0 :attack-delay 1500 :target nil} And I have a few things I want to do to them. Like attack, draw them, take damage, die and respawn, etc. Right now all those things work exactly the same way for both types. Partly because they are so similar, but also because the game is not nearly done yet. For example, I might want to draw them differently, or have them take damage differently, or whatever. I use the type mostly to filter the map, for example monsters can only attack players. Is it a good idea to use protocols (and records?) for me in this situation (now or in the future when I might want them to behave differently)? How can I benefit from them? On Jul 28, 1:46 pm, Alex Osborne <a...@meshy.org> wrote: > 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