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.

Reply via email to