Hi, I'm writing a turn-based game and one of the biggest functions is the one which handles player moves. It receives the current game state (a map) and the index of the cell that the player clicked on (an integer).
It has to make a couple of decisions based on the game state. So far I just used -> and cond->. The code looks more or less like this, I removed a bunch of function calls for brevity. (-> game-state ; This stuff happens on each move. (reveal-cell cell-index) ; And this stuff happens only under certain conditions. (cond-> (zero? (:surrounding-power cell)) (reveal-safe-cells cell-index))) The code looks clear IMHO. But then I wanted to add another feature which requires me to make decisions based on the updated value of game-state (the one that is being threaded inside cond->). I thought about cond-> a bit and came to the conclusion that the reason you can't access the currently threaded value is to keep you from writing order-dependent statements. But in my case, I sometimes do want to write order-dependent code. For example, I want to give player exp for killing a monster and then if the exp is above certain threshold, I want to level up his character. So the problem is that I have to check the current value being threaded, but cond-> doesn't allow me to do that. As I understand, I can solve it in two different ways. For both of them I have a couple of questions as I'm fairly new to Clojure. 1. Use a custom macro like condas-> <https://juxt.pro/blog/posts/condas.html> which let's you access the current value. In fact, there have been several threads about such macros on this group (example <https://groups.google.com/d/msg/clojure/0VXc57SFa0s/vR_4NJD4BwAJ>). My problem with this solution is that I'm going to depend in my code on a new macro. If somebody else looks at this code, they'll first have to understand condas-> and perhaps the reason it was brought to the project. I think that a brand new macro for such a simple problem is a bit too much. *Is it usual within the Clojure community to resort to custom macros so early?* 2. Remove cond-> and use functions which check a predicate on game-state: if it's false, the function returns the current game-state, if it's true the function updates the game state. The main body will look like this: (-> game-state (reveal-cell cell-index) (reveal-safe-cells cell-index)) Here I have two problems: a) All predicate-checking functions in the main body will have to be rewritten to the following form: (if pred (update-state game-state) game-state) That's the best case scenario, because I guess some of the more complicated functions may look like this: (if-let [foo (:bar game-state)] (if (and (baz? foo) (fizz? foo)) (update-state game-state foo) game-state) game-state) Now this is not a dealbreaker. I can certainly cope with that. *Maybe there are better ways to express that? *I don't know. But, the second problem is a bit more complex for me. b) The functions will have to be renamed. Let's look at reveal-safe-cells. The function does what the name says. The ( zero? (:surrounding-power cell)) predicate could be put into a function called safe-cell?. Now I would really like to have two separate functions – one that checks if it's okay to do the thing and one that does the thing. *How do I call the function which combines the two?* If you look at the main body, by removing cond-> I just hid the fact that certain actions will be performed only under certain conditions. reveal-safe-cells needs to combine the action and the predicate, so it'd be good if its name revealed the intention. That's it. Since I'm still learning Clojure, I'd like to get some feedback on what things are okay or not for other Clojure developers. I'm looking forward to the "Elements of Clojure" release, as it already answered many of my questions. -- Cheers, Rafał -- 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.