I wrote some fairly simple code to demonstrate use of StructMaps and Refs. It's 80 lines including comments. I'd appreciate it if someone could look it over and let me know if I've done anything that isn't very idiomatic.
The program models sports teams and players. The main functionality is the ability to trade sets of players between teams. Both teams and players are held by Refs. Players have a reference to their team. Teams have references to their players. The output from the code follows: Before trade: Oilers roster: Wayne Gretzky Mike Krushelnyski Marty McSorley Kings roster: Jimmy Carson Martin Gelinas After trade: Oilers roster: Martin Gelinas Jimmy Carson Kings roster: Wayne Gretzky Mike Krushelnyski Marty McSorley Here's the code: ; A player knows his team, if any. (defstruct player-struct :name :team-ref) ; A team knows its players. (defstruct team-struct :name :player-refs) ; Makes a new Ref to a player-struct that isn't on any team. (defn make-player [name] (ref (struct player-struct name))) ; Makes a new Ref to a team-struct that contains no players. (defn make-team [name] (ref (struct team-struct name []))) (defn assign-player-to-team [player-ref new-team-ref] (dosync ; If the player has a former team, remove them from it. (if-let [old-team-ref (@player-ref :team-ref)] (let [old-player-refs (@old-team-ref :player-refs) new-player-refs (remove #(= % player-ref) old-player-refs)] (alter old-team-ref assoc :player-refs new-player-refs))) ; Add the player to their new team. (let [old-player-refs (@new-team-ref :player-refs) new-player-refs (conj old-player-refs player-ref)] (alter player-ref assoc :team-ref new-team-ref) (alter new-team-ref assoc :player-refs new-player-refs)))) ; Returns a string describing a given player. (defn player-to-string [player-ref] (dosync (str (@player-ref :name) " plays for " (if-let [team-ref (@player-ref :team-ref)] (str "the " (@team-ref :name)) "nobody") "."))) ; Returns a string describing a given team. (defn team-to-string [team-ref] (dosync (apply str (@team-ref :name) " roster:" (map (fn [player-ref] (str "\n " (@player-ref :name))) (@team-ref :player-refs))))) ; players1 and players2 are collections of Refs to player StructMaps. ; Neither can be empty. ; All players in a collection must be on the same team. (defn trade [players1 players2] (dosync (let [team1 ((first players1) :team-ref) team2 ((first players2) :team-ref)] (doseq [p players1] (assign-player-to-team p team2)) (doseq [p players2] (assign-player-to-team p team1))))) (let [oilers (make-team "Oilers") kings (make-team "Kings") p1 (make-player "Wayne Gretzky") p2 (make-player "Mike Krushelnyski") p3 (make-player "Marty McSorley") p4 (make-player "Jimmy Carson") p5 (make-player "Martin Gelinas")] (doseq [p [p1 p2 p3]] (assign-player-to-team p oilers)) (doseq [p [p4 p5]] (assign-player-to-team p kings)) (println "Before trade:") (println (team-to-string oilers)) (println (team-to-string kings)) (trade [p1 p2 p3] [p4 p5]) (println "\nAfter trade:") (println (team-to-string oilers)) (println (team-to-string kings))) -- R. Mark Volkmann Object Computing, Inc. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---