Sorry, I just realized that you were referring to the exact same
examples Jay Fields uses...so you must already know about that article! ;-)

(2014/05/12 23:07), Dave Della Costa wrote:
>> The x is referring to the map that is to be
>> added in as a parameter, right?
> 
> So, taking one example from James's code:
> 
> (defn transparent-put [{:keys [channel buffer]} x]
>   (go
>     (>! channel x)
>     (swap! buffer conj x)))
> 
> The x is the second argument to the function--it's the message you put
> into the channel, in this case.
> 
> The contrast with the let form you used as an example is that the let
> form is assigning the right value to the left destructuring form.  But
> in the case of a function, the value that is passed in is what is
> getting destructured.  Contrast this:
> 
> (let [{:keys [a b]} {:a 1 :b 2}]
>   (println "a: " a ", b: " b))
> 
> with this:
> 
> (defn destruct
>   [{:keys [a b]}]
>   (println "a: " a ", b: " b))
> 
> (destruct {:a 1 :b 2})
> 
> Does that help?
> 
> If you haven't read this great article about destructuring by Jay Fields
> yet, I highly recommend you do:
> 
> http://blog.jayfields.com/2010/07/clojure-destructuring.html
> 
>> Like you said, I also feel like I'm *starting* to get it and it is
>> really exciting :) Thanks for your advice.
> 
> Great! You're very welcome--good luck.
> 
> DD
> 
> (2014/05/12 21:43), gamma235 wrote:
>> Your description of what is going on with my macro was really helpful.
>> In my head I was imagining recursive evals running over the code, saying
>> first, then, etc. I didn't really think about  compile time vs. run-time. 
>>
>> I am impressed with James' code as well, but I am having trouble fully
>> understanding it and getting it to run. From the transparent put
>> definition, it doesn't seem like it is possible to pass a channel value
>> as a parameter in the call. The x is referring to the map that is to be
>> added in as a parameter, right? at least that is why I learned, when I
>> studied destructuring: 
>>
>>     (def point {:x 5 :y 7})
>>
>>  
>>
>>     (let [{:keys [x y]} point]
>>       (println "x:" x "y:" y))
>>
>>  
>>
>>     => :x 5 :y 7
>>
>>
>> Does it work different different for defining function parameters? I
>> posted more under his comment above, please have a look. 
>>
>> Like you said, I also feel like I'm *starting* to get it and it is
>> really exciting :) Thanks for your advice. 
>>
>> Jesse
>>
>> On Monday, May 12, 2014 7:46:34 PM UTC+9, David Della Costa wrote:
>>
>>     > to reason about and can be dangerous. I would suggest putting
>>     > dynamically created channels in a collection inside an atom if you
>>     > need to create them like this.
>>
>>     P.S. I just read James's response and I see he said something similar
>>     regarding this--it's better to structure this as a hash-map or other
>>     data structure, and use an atom if it needs to be updated dynamically.
>>     Notice that his code is far simpler and easier to reason about, and
>>     avoids the use of macros.
>>
>>     DD
>>
>>     (2014/05/12 19:40), Dave Della Costa wrote:
>>     >> I think I am confused about how to distinguish between a symbol
>>     and a
>>     >> variable, as I thought that the symbol being derefed pointed to the
>>     >> atom that it was made to define when transparent-chan was called.
>>     >
>>     > I think it's not so much that, as being mistaken about what is
>>     going at
>>     > compile-time vs. run-time in your macros.  Going back to your
>>     original
>>     > code, your log-name function is just fine:
>>     >
>>     > (defn log-name [ch] (symbol (str ch '-log)))
>>     >
>>     > It returns a symbol, which is what you want for the second arg to
>>     def.
>>     >
>>     > However, keep in mind that this is going to return a list which will
>>     > then get evaluated, but it will only be the last value returned
>>     from 'do':
>>     >
>>     > (defmacro transparent-chan [ch]
>>     >   (do
>>     >     `(def ~ch (chan))
>>     >     `(def (log-name ~ch) (atom []))
>>     >     `(println "new transparent channel created!")))
>>     >
>>     > that is, a list like this:
>>     >
>>     > `(println "new transparent channel created!")
>>     >
>>     > ...which will then get evaluated at run-time.  So your def calls will
>>     > never run!  If we know that we can adjust it--
>>     >
>>     > (defmacro transparent-chan [ch]
>>     >   `(do (def ~ch (async/chan))
>>     >        (def (log-name ~ch) (atom []))
>>     >        (println "new transparent channel created!")))
>>     >
>>     > ...but then we get:
>>     >
>>     > user=> (transparent-chan my-chan)
>>     >
>>     > CompilerException java.lang.RuntimeException: First argument to
>>     def must
>>     > be a Symbol, compiling... ; etc.
>>     > user=>
>>     >
>>     > Hmm...still a problem.  Let's see, when is the 'log-name' function
>>     > getting run?  Oh, at *run-time*...but we want it run at compile-time.
>>     > So, knowing that, we can adjust it again:
>>     >
>>     > (defmacro transparent-chan [ch]
>>     >   `(do (def ~ch (async/chan))
>>     >        (def ~(log-name ch) (atom []))
>>     >        (println "new transparent channel created!")))
>>     >
>>     > Now we see:
>>     >
>>     > user=> (transparent-chan my-chan)
>>     > new transparent channel created!
>>     > nil
>>     > user=> my-chan
>>     > #<ManyToManyChannel
>>     > clojure.core.async.impl.channels.ManyToManyChannel@7b3287a>
>>     > user=> my-chan-log
>>     > #<Atom@49d869e7: []>
>>     > user=> my-chan-log
>>     >
>>     > Etc. I think that you need to keep playing with it and you'll get
>>     it; it
>>     > doesn't seem too far off.
>>     >
>>     > That said, if I were you I'd still try it the simpler way I proposed
>>     > before--this seems like a lot of work for not a lot of payoff,
>>     when you
>>     > can just dump out logging information at the time you send or
>>     receive a
>>     > message. And in general creating vars like this dynamically is not
>>     easy
>>     > to reason about and can be dangerous. I would suggest putting
>>     > dynamically created channels in a collection inside an atom if you
>>     need
>>     > to create them like this.
>>     >
>>     >> Later I was thinking about incorporating it into a gui to see
>>     >> if it's possible to design an asynchronous message passing system
>>     >> using drag and drop icons that represent pubs and subs, channels
>>     with
>>     >> a drop-down contents tab, and running listening processes.
>>     >> I know this is probably out of my league, but I was just asking
>>     >> myself how something like that might be implemented.
>>     >
>>     > I think it's totally possible and there's no reason it would be
>>     out of
>>     > your league. Just keep trying and asking questions here (and on
>>     IRC too
>>     > if you want to jump on, plenty of folks there willing to help out).
>>     >
>>     > DD
>>     >
>>     > (2014/05/12 17:26), gamma235 wrote:
>>     >> Thank you for your answer David.
>>     >>
>>     >> I think I am confused about how to distinguish between a symbol
>>     and a
>>     >> variable, as I thought that the symbol being derefed pointed to
>>     the atom
>>     >> that it was made to define when transparent-chan was called.
>>     >>
>>     >> Also, I am trying to specifically solve the logging problem  to
>>     >> understand how I might use stored values or state outside the
>>     scope of
>>     >> the channel as a means of creating the illusion of referencing its
>>     >> contents. Later I was thinking about incorporating it into a gui
>>     to see
>>     >> if it's possible to design an asynchronous message passing system
>>     using
>>     >> drag and drop icons that represent pubs and subs, channels with a
>>     >> drop-down contents tab, and running listening processes. I know
>>     this is
>>     >> probably out of my league, but I was just asking myself how
>>     something
>>     >> like that might be implemented. I will of course continue to
>>     learn and
>>     >> reinforce the basics though on my own.
>>     >>
>>     >> Jesse
>>     >>
>>     >> On Monday, May 12, 2014 1:26:57 PM UTC+9, David Della Costa wrote:
>>     >>
>>     >>     I apologize, apparently you can't use go-loop how I did below,
>>     >>
>>     >>     => (def my-go-loop (async/go-loop [msg (async/<! c)] (println
>>     "got
>>     >>     msg "
>>     >>     msg " from channel " 'c)))
>>     >>
>>     >>     ...try this instead:
>>     >>
>>     >>     (def my-go-loop (async/go-loop [] (let [msg (async/<! c)]
>>     (println "got
>>     >>     msg " msg " from channel " 'c))))
>>     >>
>>     >>     Sorry about that!
>>     >>
>>     >>     DD
>>     >>
>>     >>     (2014/05/12 13:21), Dave Della Costa wrote:
>>     >>     >
>>     >>     >> 1) I feel like it is a redundant to define bindings multiple
>>     >>     times in
>>     >>     >> my go's let exprs when the params have already been passed
>>     in as
>>     >>     >> arguments. Is there a more idiomatic way to do this?
>>     >>     >
>>     >>     > I think the fact that you are re-binding in a let should
>>     show you
>>     >>     that
>>     >>     > these variables are already in scope: that let is wholly
>>     >>     redundant, just
>>     >>     > remove it.
>>     >>     >
>>     >>     >
>>     >>     >> 2) Whenever I try to create a generic process to
>>     automatically
>>     >>     >> generate a log-name for each channel and then call update,
>>     I get a
>>     >>     >> 'symbol cannot be cast to atom' error. How can I get
>>     around this? It
>>     >>     >> seems to happen even if I don't use the log-name function.
>>     >>     >
>>     >>     > It's simple: a symbol is not an atom.  It's telling you
>>     exactly
>>     >>     what you
>>     >>     > need to know: you cannot call swap! on a symbol.  Make sure
>>     your
>>     >>     atom is
>>     >>     > the first argument to swap! wherever you use it.
>>     >>     >
>>     >>     >
>>     >>     >> 3) Is there a better way to keep track of what's on a
>>     channel that
>>     >>     >> doesn't use macros?
>>     >>     >
>>     >>     > You cannot look inside of a channel, but to do what you
>>     want and
>>     >>     get a
>>     >>     > sense of how core.async works, I think you are on the right
>>     track by
>>     >>     > logging as you put stuff in and take it out.
>>     >>     >
>>     >>     > That said, I would start by getting rid of the log and the
>>     >>     macro--these
>>     >>     > are unnecessary complications--and do things very simply:
>>     >>     >
>>     >>     > => (require '[clojure.core.async :as async])
>>     >>     > nil
>>     >>     > => (def c (async/chan))
>>     >>     > #'user/c
>>     >>     > => (def my-go-loop (async/go-loop [msg (async/<! c)]
>>     (println "got
>>     >>     msg "
>>     >>     > msg " from channel " 'c)))
>>     >>     > #'user/my-go-loop
>>     >>     > => (defn put-and-print! [c msg] (println "putting msg " msg
>>     " onto
>>     >>     > channel " 'c) (async/put! c msg))
>>     >>     > #'user/put-and-print!
>>     >>     > => (put-and-print! c "I am a message!")
>>     >>     > putting msg  I am a message!  onto channel  c
>>     >>     > got msg  I am a message!  from channel  c
>>     >>     > nil
>>     >>     > =>
>>     >>     >
>>     >>     > Printing out "channel c" is kind of silly since there is
>>     only one,
>>     >>     but
>>     >>     > it sounds like you may want to do this with multiple
>>     channels so
>>     >>     this is
>>     >>     > one way to print out the variable name--simply quote it.
>>     >>     >
>>     >>     > DD
>>     >>     >
>>     >>     > (2014/05/12 11:41), gamma235 wrote:
>>     >>     >> Hi everyone,
>>     >>     >>
>>     >>     >> I am getting my feet wet with core.async and am trying to
>>     attach
>>     >>     atoms
>>     >>     >> to channels that update automatically and print out to the
>>     >>     console as
>>     >>     >> you take and put. This is not for anything serious, just a
>>     way to
>>     >>     get
>>     >>     >> familiar with the behavior and functionality of the
>>     library and
>>     >>     practice
>>     >>     >> my Clojure skills. Thanks in advaan
>>     >>     >>
>>     >>     >> Here is my code:
>>     >>     >>
>>     >>     >>     (defn log-name [ch] (symbol (str ch '-log)))
>>     >>     >>      
>>     >>     >>      ;; Is this efficiently written?
>>     >>     >>     (defmacro transparent-chan [ch]  
>>     >>     >>       (do
>>     >>     >>         `(def ~ch (chan))
>>     >>     >>         `(def (log-name ~ch) (atom []))
>>     >>     >>         `(println "new transparent channel created!")))
>>     >>     >>      
>>     >>     >>     (defn- update [log v]
>>     >>     >>       (do
>>     >>     >>         (swap! log conj v)
>>     >>     >>         (println "log test passed: " v " has been logged")
>>     >>     >>         (println "channel contents: " @log)))
>>     >>     >>      
>>     >>     >>      (defn transparent-put [ch v]
>>     >>     >>        (let [log (log-name ch)]
>>     >>     >>          (go
>>     >>     >>           (let [ch ch
>>     >>     >>                 v v]
>>     >>     >>             (>! ch v)
>>     >>     >>             (println v " has been successfully moved
>>     through the
>>     >>     channel")))
>>     >>     >>          (update log v)
>>     >>     >>          (println "put test passed: " v " has been put on the
>>     >>     channel")
>>     >>     >>          (println " rechecking channel contents: " @log)))
>>     >>     >>      
>>     >>     >>     (defn transparent-take [ch]
>>     >>     >>       (go
>>     >>     >>        (let [v (<! ch)
>>     >>     >>              log-name (symbol (str ch '-log))]
>>     >>     >>          (swap! log-name #(remove #{v} %))
>>     >>     >>        (println v "has been removed from channel")))
>>     >>     >>       (println " removal pending"))
>>     >>     >>
>>     >>     >>  
>>     >>     >>
>>     >>     >>     ;; tests
>>     >>     >>     (transparent-chan c)
>>     >>     >>     c
>>     >>     >>     c-log
>>     >>     >>     @c-log
>>     >>     >>     (transparent-put c 42)
>>     >>     >>     (transparent-take c)
>>     >>     >>
>>     >>     >>
>>     >>     >>
>>     >>     >> My main questions are regarding variable scope:
>>     >>     >> 1) I feel like it is a redundant to define bindings multiple
>>     >>     times in my
>>     >>     >> go's let exprs when the params have already been passed in as
>>     >>     arguments.
>>     >>     >> Is there a more idiomatic way to do this?
>>     >>     >>
>>     >>     >> 2) Whenever I try to create a generic process to
>>     automatically
>>     >>     generate
>>     >>     >> a log-name for each channel and then call update, I get a
>>     'symbol
>>     >>     cannot
>>     >>     >> be cast to atom' error. How can I get around this? It
>>     seems to
>>     >>     happen
>>     >>     >> even if I don't use the log-name function.
>>     >>     >>
>>     >>     >> 3) Is there a better way to keep track of what's on a
>>     channel that
>>     >>     >> doesn't use macros?
>>     >>     >>
>>     >>     >> --
>>     >>     >> You received this message because you are subscribed to
>>     the Google
>>     >>     >> Groups "Clojure" group.
>>     >>     >> To post to this group, send email to [email protected]
>>     >>     <javascript:>
>>     >>     >> Note that posts from new members are moderated - please be
>>     >>     patient with
>>     >>     >> your first post.
>>     >>     >> To unsubscribe from this group, send email to
>>     >>     >> [email protected] <javascript:>
>>     >>     >> For more options, visit this group at
>>     >>     >> http://groups.google.com/group/clojure?hl=en
>>     <http://groups.google.com/group/clojure?hl=en>
>>     >>     <http://groups.google.com/group/clojure?hl=en
>>     <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 [email protected] <javascript:>
>>     >>     >> <mailto:[email protected] <javascript:>>.
>>     >>     >> For more options, visit https://groups.google.com/d/optout
>>     <https://groups.google.com/d/optout>
>>     >>     <https://groups.google.com/d/optout
>>     <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 [email protected]
>>     <javascript:>
>>     >> Note that posts from new members are moderated - please be
>>     patient with
>>     >> your first post.
>>     >> To unsubscribe from this group, send email to
>>     >> [email protected] <javascript:>
>>     >> For more options, visit this group at
>>     >> http://groups.google.com/group/clojure?hl=en
>>     <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 [email protected] <javascript:>
>>     >> <mailto:[email protected] <javascript:>>.
>>     >> For more options, visit https://groups.google.com/d/optout
>>     <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 [email protected]
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> [email protected]
>> 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 [email protected]
>> <mailto:[email protected]>.
>> 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 [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to