The function map> takes a channel and a function, and returns a new channel; every time an element is sent through that new channel, it first goes through the given function (and it is the result of that function that is actually sent through the original channel).
The function map< is similar, except it applies the given function to each element that exits the channel. So in my function, (as/map< (fn [x] (swap! at pop) x) chan) creates a new channel that will remove an element from the sequence referenced by the atom at every time a value is sent through it. The result of the function is thus a new channel that conjes all of its input to the atom, and pops an element from the atom every time someone takes from it. But from an external point of view, thanks to both functions returning the element unchanged, it acts exactly like a normal channel. Note that it essentially wraps the original channel within two other channels, so the original channel is unchanged and should therefore not be used anymore. I have to leave now; if you still have any question after playing with the following code, I'll be glad to answer them when I come back (in ~10 hours or so) ;; project.clj (defproject async "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.6.0"] [org.clojure/core.async "0.1.303.0-886421-alpha"]] :main ^:skip-aot async.core :target-path "target/%s" :profiles {:uberjar {:aot :all}}) ;; src/async/core.clj (ns async.core (:require [clojure.core.async :as as :refer [go <! >! chan]])) (defn decorate-channel [chan at] (as/map> (fn [x] (swap! at conj x) x) (as/map< (fn [x] (swap! at pop) x) chan))) (defn some-fn-using-a-channel [ch] (go (dotimes [_ 10] (<! (as/timeout 50)) (>! ch 1))) (go (dotimes [_ 10] (<! (as/timeout 100)) (<! ch)))) (defn continuously-print-atom [at] (dotimes [_ 20] (Thread/sleep 100) (println @at))) (defn -main [] (let [at (atom []) thread (Thread. #(continuously-print-atom at)) raw-chan (chan 10)] (.start thread) (some-fn-using-a-channel (decorate-channel raw-chan at)))) (-main) On 14 May 2014 03:36, gamma235 <jesus.diama...@gmail.com> wrote: > Hi Gary, > > Your function looks interesting and succinct, but I am still new to this > subject so am not sure how it would be used. Could you give some examples? > > Jesse > > > On Wednesday, May 14, 2014 3:34:17 AM UTC+9, Gary Verhaegen wrote: >> >> What about the following? (as is bound to clojure.core.async ns) >> >> (defn decorate-channel >> [chan at] >> (as/map> (fn [x] (swap! at conj x) x) >> (as/map< (fn [x] (swap! at pop) x) >> chan))) >> >> As far as I can tell, it should do what you want, without introducing >> global vars. It also returns a "normal" async channel that can be used >> anywhere a channel is expected, without special handling. This could >> be very handy for debugging. >> >> >> On 13 May 2014 06:02, gamma235 <jesus.d...@gmail.com> wrote: >> > >> > Hey guys, I took your suggestions and just wanna deliver the finished >> > product. I included the macro in there for practice, but agree it is >> > probably not necessary. Thanks for all your help. >> > >> > p is for pretty :) >> > >> >> >> >> (defn pchan [ch] >> >> >> >> {:channel ch, :buffer (atom [])}) >> > >> > >> >> >> >> (defn pbuff [{:keys [ch buffer]}] >> >> (println @buffer)) >> > >> > >> >> >> >> (defn pput [{:keys [channel buffer]} v] >> >> (do >> >> (go >> >> (>! channel v)) >> >> (swap! buffer conj v) >> >> (println "put " v))) >> > >> > >> >> >> >> (defn ptake [{:keys [channel buffer]}] >> >> (go >> >> (let [v (<! channel)] >> >> (if-not (empty? @buffer) >> >> (do >> >> (swap! buffer pop) >> >> (println "took " v))))) >> >> (println "take pending ...")) >> > >> > >> >> >> >> (defmacro def-pchan >> >> ([name] >> >> `(def ~name (pchan (chan)))) >> >> ([name buff] >> >> `(def ~name (pchan (chan ~buff))))) >> > >> > >> >> >> >> (defn clear-buffer [{:keys [buffer]}] >> >> (reset! buffer [])) >> >> >> > it works! >> >> >> >> (def-pchan pc) >> >> (:buffer pc) >> >> (pbuff pc) >> >> (ptake pc) >> >> (pput pc 42) >> >> (clear-buffer pc) >> > >> > -- >> > 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 >> > 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 >> > 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. >> > 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. -- 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.