Thanks! I've glanced at Land of Lisp, actually, some while back. I might even have a copy.
To be clear, it isn't LISP that's giving me problems. I've been dabbling with LISP on-and-off since the '80's, and I've read a couple of Paul Graham's books. I understand code-as-data, and lambdas, and I even grok macros. It's specifically Clojure's functional programming model that I need to wrap my head around. On Friday, March 30, 2018 at 5:41:27 AM UTC-7, Tim Visher wrote: > > http://landoflisp.com/ is specifically about coding games in Lisp, in > case you're into books. :) > > On Thu, Mar 29, 2018 at 6:45 PM, Will Duquette <wi...@wjduquette.com > <javascript:>> wrote: > >> I'm an experienced programmer, but a Clojure newbie; as a beginner >> project, I'm looking into how one would idiomatically write a text >> adventure of sorts in Clojure. I'm less interested in producing a playable >> game than I am in learning how to do such a thing in a proper functional >> style. >> >> Suppose in this game I have a room whose description changes based on a >> global flag. For example, there's something in the Fancy Room that you >> won't notice until you've reached the major plot point. >> >> The world map is (for the sake of argument) a hash-map whose keys are the >> room IDs and whose values are room records, where each record is a hash-map. >> >> (def world {:fancy-room {:name "Fancy Room" :description "This is a fancy >> room." ...}}) >> >> I'm aware that I could use a (defstruct) or (defrecord); I'm keeping it >> simple for now. Then, the flags are saved in a ref; the intent is that >> mutable set is segregated, so that it can more easily be written to a save >> file. >> >> ;; Global set of flags >> (def flags (ref #{}) >> >> (defn flag-set [flag] >> (dosync (alter flags conj flag)) >> >> ;; When the major plot point is reached >> (flag-set :major-plot-point-reached) >> >> Normally, to describe a room you just return its :description. >> >> (defn describe [room] (:description (world get room))) >> >> But for the :fancy-room, the returned description depends on the global >> flag, and it will be specific to :fancy-room. I could add this logic >> directly to the (describe) function's body, but that would be ugly. What >> I'd like to do is attach a lambda to the :fancy-room in some way. The >> (describe) function looks for a :describer, and if it's there it calls it; >> and if not it just returns the :description: >> >> (defn describe [entity] >> (if (:describer entity) >> ((:describer entity) entity) >> (:description entity))) >> >> *Question 1*: this works, but it looks ugly to me; I figure there's a >> better, more idiomatic way to do this kind of thing that's probably obvious >> to anyone with any real experience. Multimethods, maybe? Define a Room >> protocol, then let most rooms be NormalRoom records, but let :fancy-room be >> a FancyRoom record? >> >> *Question 2*: Whatever code actually computes the description, it will >> need access to the :major-plot-point-reached flag. What's the cleanest way >> to give the description code access to the flags ref? It could simply >> access "@flags" directly: >> >> (if (:major-plot-point-reached @flags) >> "This is a fancy room. Hey, that light sconce looks movable!" >> "This is a fancy room.") >> >> But that doesn't seem properly functional. Would it be better to pass >> the game state into each method? >> >> (defn describe [entity state] >> (if (:describer entity) >> ((:describer entity) entity state) >> (:description entity))) >> >> Any ideas? >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clo...@googlegroups.com >> <javascript:> >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+u...@googlegroups.com <javascript:> >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+u...@googlegroups.com <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > > -- 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 --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.