Re: Proper way to write EDN file, after production bug
Yes we will set print-dup, print-meta, print-level and print-length to have a properly formatted edn file. Le vendredi 30 mars 2018 05:55:50 UTC+2, Didier a écrit : > > Ya, I'd write a wrapping fn, like ->edn which internally binds everything > to what it should be, maybe even declares some extra print defmethod if you > need custom edn serialization, and returns the edn. -- 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.
Re: Proper way to write EDN file, after production bug
I mean just print-dup and print-meta should be enough ! Le vendredi 30 mars 2018 14:31:04 UTC+2, LaurentJ a écrit : > > Yes we will set print-dup, print-meta, print-level and print-length to > have a properly formatted edn file. > > Le vendredi 30 mars 2018 05:55:50 UTC+2, Didier a écrit : >> >> Ya, I'd write a wrapping fn, like ->edn which internally binds everything >> to what it should be, maybe even declares some extra print defmethod if you >> need custom edn serialization, and returns the edn. > > -- 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.
Re: Writing a text adventure in Clojure
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 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 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. > -- 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.
Re: Writing a text adventure in Clojure
Hi Will, Welcome to the wide world of functional programming, where data flows, and functions transmute without destroying their inputs. As some others in this thread have already suggested, a general approach to viewing any problem space from a functional perspective is to imagine your problem as a pipeline of data transformations from start to finish. To the greatest extent possible, try to represent your data transformations as pure functions over immutable arguments rather than holding any global state in a var and mutating it at each time step. In the context of a game program, consider depicting all of your game state as a single hierarchical map. Then thread this map through each function and return a new derived map as each output result. ```clojure (def world-state {:flags #{} :location :fancy-room :inventory #{:sledgehammer :car-keys :lamp} :rooms {:creepy-corridor {:name "Creepy Corridor" :description "Whoa! Spooky..." :items #{:halloween-mask :monkeys-paw :troll-doll}} :fancy-room {:name "Fancy Room" :description "The fanciest!" :items #{:chandelier :toy-poodle :looking-glass}} ...}}) ``` Let's imagine this is the initial world state. When your application starts up, it enters into the game loop (which would be a nice, friendly recursion, of course). In each round of the game loop, you call a sequence of functions to get the description of the current room, print it out, ask the user for the next command, process that command, and then recurse back to the top of the next iteration of the game loop. Although printing to stdout and reading from stdin are obviously side effecting functions, you should be able to keep your functions for retrieving the room description and processing the user's command as pure functions of the current world-state. Just make sure that the functions that process a user's command always return a new copy of the world-state value. When you want to save the game, just write out the world-state to an EDN file. By reading it back in again later, you can restore the game to exactly the same state it was in before. In response to your specific question about having a different room description after some event has happened, consider this approach: ```clojure (defn do-important-plot-changing-action [world-state] (-> world-state (update :flags conj :major-plot-point-reached) (assoc-in [:rooms :fancy-room :description] "Gosh! This room isn't nearly as fancy anymore!"))) ``` That is, the function just uses assoc, assoc-in, update, and update-in to modify the values in the new map and return it for use in future iterations of the game loop. And that's pretty much all there is to it. You just pass the changing world state down through the stack rather than mutating it in place on the heap. (Ultimately, the world-state data structure is, of course, actually stored on the heap, and you are just passing references to it through the stack, but I hope you get my meaning here.) Good luck and happy hacking! -- 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.
Re: Writing a text adventure in Clojure
Hi Will, have a look at this workshop repository, in which we developed a simple text adventure framework: https://github.com/learn-postspectacular/resonate-workshop-2014 Hth! K. On 30 March 2018 at 16:01, Gary Johnson wrote: > Hi Will, > > Welcome to the wide world of functional programming, where data flows, and > functions transmute without destroying their inputs. > > As some others in this thread have already suggested, a general approach to > viewing any problem space from a functional perspective is to imagine your > problem as a pipeline of data transformations from start to finish. To the > greatest extent possible, try to represent your data transformations as pure > functions over immutable arguments rather than holding any global state in a > var and mutating it at each time step. > > In the context of a game program, consider depicting all of your game state > as a single hierarchical map. Then thread this map through each function and > return a new derived map as each output result. > > ```clojure > (def world-state {:flags #{} > :location :fancy-room > :inventory #{:sledgehammer :car-keys :lamp} > :rooms {:creepy-corridor {:name "Creepy Corridor" > :description "Whoa! Spooky..." :items #{:halloween-mask :monkeys-paw > :troll-doll}} > :fancy-room {:name "Fancy Room" > :description "The fanciest!" :items #{:chandelier :toy-poodle > :looking-glass}} > ...}}) > > ``` > Let's imagine this is the initial world state. When your application starts > up, it enters into the game loop (which would be a nice, friendly recursion, > of course). In each round of the game loop, you call a sequence of functions > to get the description of the current room, print it out, ask the user for > the next command, process that command, and then recurse back to the top of > the next iteration of the game loop. Although printing to stdout and reading > from stdin are obviously side effecting functions, you should be able to > keep your functions for retrieving the room description and processing the > user's command as pure functions of the current world-state. Just make sure > that the functions that process a user's command always return a new copy of > the world-state value. When you want to save the game, just write out the > world-state to an EDN file. By reading it back in again later, you can > restore the game to exactly the same state it was in before. > > In response to your specific question about having a different room > description after some event has happened, consider this approach: > > ```clojure > (defn do-important-plot-changing-action [world-state] > (-> world-state > (update :flags conj :major-plot-point-reached) > (assoc-in [:rooms :fancy-room :description] "Gosh! This room isn't > nearly as fancy anymore!"))) > ``` > > That is, the function just uses assoc, assoc-in, update, and update-in to > modify the values in the new map and return it for use in future iterations > of the game loop. And that's pretty much all there is to it. You just pass > the changing world state down through the stack rather than mutating it in > place on the heap. (Ultimately, the world-state data structure is, of > course, actually stored on the heap, and you are just passing references to > it through the stack, but I hope you get my meaning here.) > > Good luck and happy hacking! > > -- > 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. -- Karsten Schmidt http://postspectacular.com | http://thi.ng | http://toxiclibs.org On 30 March 2018 at 16:01, Gary Johnson wrote: > Hi Will, > > Welcome to the wide world of functional programming, where data flows, and > functions transmute without destroying their inputs. > > As some others in this thread have already suggested, a general approach to > viewing any problem space from a functional perspective is to imagine your > problem as a pipeline of data transformations from start to finish. To the > greatest extent possible, try to represent your data transformations as pure > functions over immutable arguments rather than holding any global state in a > var and mutating it at each time step. > > In the context of a game program, consider depicting all
[ANN] com.walmartlabs/schematic 1.1.0
Schematic is a Clojure library which aids in assembling Component systems from configuration data. * Expects components to implement the Component/Lifecycle protocol * Prefers pure data for declaring dependencies * Provides a simple mechanism for assembling/starting just a subset of Components * Avoids the pattern of passing a large bag of config data through down through levels of Component creation functions https://github.com/walmartlabs/schematic This is the first public release of this library, but we've been using it in production systems at WalmartLabs for more than a year. -- 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.
Re: [ANN] com.walmartlabs/schematic 1.1.0
... and some notes on how we got there: https://medium.com/@hlship/schematic-92b0b6ffdb26 On Fri, Mar 30, 2018 at 12:30 PM, Steve Ashton wrote: > Schematic is a Clojure library which aids in assembling Component systems > from configuration data. > > * Expects components to implement the Component/Lifecycle protocol > * Prefers pure data for declaring dependencies > * Provides a simple mechanism for assembling/starting just a subset of > Components > * Avoids the pattern of passing a large bag of config data through down > through levels of Component creation functions > > https://github.com/walmartlabs/schematic > > This is the first public release of this library, but we've been using it > in production systems at WalmartLabs for more than a year. > > -- > 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. > -- Howard M. Lewis Ship Senior Mobile Developer at Walmart Labs Creator of Apache Tapestry (971) 678-5210 http://howardlewisship.com @hlship -- 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.
[ANN] A couple of libraries for functional reactive web programming - Ulmus & Recurrent
Hey everybody, I've been hacking on these for about two years, but I only recently got around to documenting them to a place where they're semi-presentable. First up in Ulmus, a library for doing frp style programming in Clojurescript. I apes the Elm API to some degree. Really just higher-level core.async, but I've found it pretty great to work with. https://github.com/jeremykross/ulmus Second is Recurrent, a library for building functionally reactive web components. It's inspired most directly by cycle.js but I think there's good bit of novelty there as well. Can't say that it's for everybody, but the way my mind works, it's been real joy to develop and use. https://github.com/jeremykross/recurrent Hope somebody else will find these cool as well. -- 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.