A set might be better to hold the player-refs, then you can just call
(disj player-refs player-ref) without doing any extra checking.

Also you can access ref values without needing to be in a dosync.
Things being immutable, the value you get from, say, @team-ref won't
change once you have it.

On Jul 5, 5:12 pm, Mark Volkmann <r.mark.volkm...@gmail.com> wrote:
> 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
-~----------~----~----~----~------~----~------~--~---

Reply via email to