What does the ref *loaded-libs* do?

2018-01-29 Thread Raymond Huang
I was poking around `tools.namespace` and I found it interesting that the 
implementation of `remove-lib` is:

```(defn remove-lib
  "Remove lib's namespace and remove lib from the set of loaded libs."
  [lib]
  (remove-ns lib)
  (dosync (alter @#'clojure.core/*loaded-libs* disj lib)))
```


I’m wondering if someone can enlighten me to explain why `*loaded-libs*` 
needs to exist, as opposed to checking `clojure.lang.Namespace` directly?

This is a question carried over from 
slack: https://clojurians.slack.com/archives/C03S1KBA2/p151721185721

-- 
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.


Re: [ANN] kibit 0.1.6 - featuring namespaced keyword support!

2017-07-26 Thread Raymond Huang
That is awesome! Looking forward to giving it a spin!

Sent from my iPhone

> On Jul 26, 2017, at 4:18 PM, Daniel Compton  
> wrote:
> 
> Hi folks
> 
> I'm excited to announce that kibit 0.1.6-beta1 has been released.
> 
> Kibit is a static analysis tool that looks at your code and suggests ways it 
> could be more idiomatic.
> 
> In the most recent beta release, Kibit supports reading files with namespaced 
> keywords! A massive thanks to Alex Redington for putting this together, and 
> Reid McKenzie for providing feedback on this fix.
> 
> Up until now Kibit couldn't read namespaced keywords and would skip the rest 
> of the file, which meant that large portions of your codebase wouldn't be 
> checked. With the increasing use of namespaced keywords from clojure.spec, 
> this was becoming a larger and larger problem for people.
> 
> You can try it today by adding `[lein-kibit "0.1.6-beta1"]` to your Leiningen 
> :plugins, either in your user.clj, or in your project.clj.
> 
> Please report any wonkiness you find with this version. We're particularly 
> interested in people running this on projects which do funky things with 
> switching namespaces, or manually manipulating namespace aliases (in-ns, 
> alias, e.t.c.). A word of warning, as always don't blindly accept Kibit 
> suggestions. It is possible that it may get confused on files doing tricky 
> namespace stuff, and make suggestions with incorrect namespace aliases (but 
> we'd like to fix that if we can).
> 
> Thanks, Daniel.
> -- 
> 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.


Re: [ANN] CIDER 0.11 Released!

2016-03-03 Thread Raymond Huang
Congrats. This was a really awesome release. I really how jack-in
dynamically adds the dependencies & plugins.

No more out of sync issues :)

On Thu, Mar 3, 2016 at 4:05 AM Phillip Lord 
wrote:

>
> This is a really fantastic release. I thought after the debugger, you
> could probably just stop, but enlighten is a really nice addition.
>
>
>
> Bozhidar Batsov  writes:
>
> > Hey everyone,
> >
> > CIDER 0.11 (a.k.a. Bulgaria) is finally out!
> >
> > Today Bulgarians (like me) celebrate the country's Liberation Day and the
> > rest of the
> > world will get to celebrate the release of CIDER 0.11. :-)
> >
> > Once again we've got a ton of new features, refinements and bugfixes and
> I
> > hope you're going to love them!
> >
> > The changelog is here
> > https://github.com/clojure-emacs/cider/releases/tag/v0.11.0
> >
> > Enjoy!
>
> --
> Phillip Lord,   Phone: +44 (0) 191 208 7827
> Lecturer in Bioinformatics, Email:
> phillip.l...@newcastle.ac.uk
> School of Computing Science,
> http://homepages.cs.ncl.ac.uk/phillip.lord
> Room 914 Claremont Tower,   skype: russet_apples
> Newcastle University,   twitter: phillord
> NE1 7RU
>
> --
> 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.


Re: The middleware pattern

2015-10-02 Thread Raymond Huang
To follow up on middleware, this is a great picture to demonstrate it.

687474703a2f2f692e737461636b2e696d6775722e636f6d2f68623864422e706e67


On Fri, Oct 2, 2015 at 2:43 PM, Marc O'Morain  wrote:

> Could you use Russian Dolls as an analogy? To build a Russian doll (or to
> build middleware) you start out with the smallest doll, and put it inside
> the second smallest, which in turn goes inside the third smallest. When
> opening the doll (calling the function) you start with the largest doll,
> and open it to reveal the second largest, etc.
>
> Imagine the function as a marble, and Russian Dolls as middleware. To put
> the marble inside the dolls you wrap it in the smallest doll first. To call
> the function (retrieve the marble) you need to open the largest, outermost
> doll first.
>
>
>
> On Fri, Oct 2, 2015 at 8:10 PM, Jason Felice 
> wrote:
>
>> Why is it so hard to describe to new people?
>>
>> I mean, the questions I get are (I understand what's happening here, but
>> I can't describe it well):
>>
>> 1. If -> threads things first-to-last, why does the middleware run
>> last-to-first?
>> 2. Why is comp backwards?
>> 3. Wait, so how does each wrapper get a second pass at it?
>> 4. Why would you do this to me?
>>
>> I hope to write a blog or something on this, but I wanted to check in
>> here first.  Any ideas on how to talk about this?
>>
>> Thanks,
>> -Jason
>>
>> --
>> 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.
>

-- 
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.


Re: Stuart Sierra's Component: retries & restarts in production

2015-09-03 Thread Raymond Huang
Another way I can think of decomposing this is to buffer/queue
communication between your two components, i.e a core.async channel. This
will decouple the two components allowing your MessageQueue to manage it's
own reconnection.

Interesting question about whether `start` calling `stop` is blasphemy or
not. I hope someone else can provide some insight on that.


On Wed, Sep 2, 2015 at 4:03 PM,  wrote:

> TLDR: how do you use Component when the application logic involves
> retrying failed components?
>
> Background:
> I'm writing an app that consumes events from a streaming HTTP connection
> and writes those events to a message queue (see Code Illustration #1). It
> seems like that could be captured easily with three components —an HTTP
> stream, a message queue connection, and a "shoveler" that depends on the
> other two (see Code Illustration #2)— *but* the reconnection requirements
> complicate things…
> The HTTP connection may be closed at any time by the server; if that
> happens, the app should persistently attempt to reconnect using an
> exponential back-off pattern. In addition, if the app goes thirty seconds
> without receiving any data, it should close the connection and try to
> reconnect. (see Code Illustration #3) It's not clear to me how to best
> express these "retry" requirements in the component lifecycle. Like, is it
> blasphemous for a component to be calling stop and start on its injected
> dependencies?
>
> Some possible approaches:
>
>- Throw different kinds of exceptions to indicate what should happen
>(using namespaced keywords, perhaps?), handled by whoever calls
>component/start on the system-map.
>- The exception provides the component and system at the time of the
>   exception, enabling a sort of "resume" capability.
>   - I'm under the impression that relying on exceptions for control
>   flow is an anti-pattern.
>- Create a sort of custom system implementation, one that goes beyond
>calling start on its components in dependency order to monitor
>failures and direct retries "appropriately".
>   - "A system is a component which knows how to start and stop other
>   components." (from the README)
>   So the fact that we want the shoveler component to be capable of
>   restarting the HTTP component indicates that the shoveler should 
> actually
>   be considered a system. (right?)
>  - If the HTTP stream is *injected* into the shoveler as a
>  dependency, how is it possible for the shoveler to stop the HTTP
>  stream and then start it again *with* any dependencies the
>  stream may have?
>   - Ensure that every component/Lifecycle method implementation is
>idempotent, so that I can get good-enough "restart" semantics by just
>calling start-system again.
>   - I know that idempotence is generally a Good Thing anyway, but
>   using start-system as a panacea strikes me as crude.
>
>
> Code Illustrations:
>
> 1. Rough sketch of app without timeout/retry logic or component:
> (defn -main []
>   (let [mq-conn (connect-to-queue mq-config)
> {event-stream :body} (http/get endpoint {:as :stream})]
> (with-open [rdr (java.io/reader event-stream)]
>   (doseq [entity (line-seq rdr)]
> (write mq-conn entity)
>
> 2. Rough sketch of app with component but still without timeout/retry
> logic:
> (defrecord EventStream [endpoint
> http-config
> stream]
>   component/Lifecycle
>   (start [this]
> (let [response (http/get endpoint (merge {:as :stream} http-config))]
>   (assoc this :http-response response, :stream (:body response)))
>   (stop [this]
> (.close stream)
> (-> this (dissoc :http-response) (assoc :stream nil
>
> (defrecord MessageQueue [config
>  connection]
>   component/Lifecycle
>   (start [this]
> (assoc this :connection (connect-to-queue config)))
>   (stop [this]
> (.close connection)
> (assoc this :connection nil)))
>
> (defrecord Shoveler [source sink
>  worker]
>   component/Lifecycle
>   (start [this]
> ;; To avoid blocking indefinitely, we put the processing in a future.
> (assoc this :worker (future
>  (with-open [rdr (java.io/reader (:stream source)]
>(doseq [entity (line-seq rdr)]
>  (write sink entity)
>   (stop [this]
> (future-cancel worker)
> (assoc this :worker nil)))
>
> (defn -main []
>   (-> (component/system-map :config (read-config)
> :events (map->EventStream {:endpoint endpoint
> })
> :mq-client (map->MessageQueue {})
> :shoveler (map->Shoveler {}))
>   (component/using {:events {:http-config :config}
> :mq-client {:config :config}
> :shoveler 

Re: Filter predicates and side-effects

2015-09-02 Thread Raymond Huang
I believe the reason it's not recommended is because it returns a lazy
chunked sequence. This means that it's not guaranteed to eagerly perform
your side-effects, unless you wrap it in `doall`.

On Wed, Sep 2, 2015 at 8:48 AM, James Elliott  wrote:

> I notice that the documentation for filter and filterv are emphatic that
> the predicate you are using be free of side effects. Why is that so? For
> example, I would like to use filterv to collect a list of lighting
> effects which respond false to a protocol method which asks whether they
> have finished. In the implementation of that method, the effects are free
> to update their internal state based on the current show state and time,
> when deciding whether or not they are finished, and so I can’t guarantee
> there will be no side effects while filtering the effects. Does that mean I
> can’t use filterv? If not, why not? Looking at the source, I see no
> obvious problems.
>
> --
> 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.


Boot-CLJ: How to daemonize a run script?

2015-08-23 Thread Raymond Huang
I've been checking out boot lately, and I want to run my application using 
a boot script.

I have an aleph HTTP server started, but the main thread exits so my 
application never starts. 

What's the idiomatic way of preventing my main thread from exiting? How 
does generating an uberjar with leiningen do this?

-- 
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.


Re: What Counted interface is for?

2015-08-04 Thread Raymond Huang
That sounds about right.

See
https://github.com/clojure/clojure/blob/41af6b24dd5be8bd62dc2b463bc53b55e18cd1e5/src/jvm/clojure/lang/Counted.java

On Tue, Aug 4, 2015 at 11:06 AM, Gary Verhaegen gary.verhae...@gmail.com
wrote:

 I don't know of it is correct, but I also remember reading that Counted
 was a marker interface, i.e. it does not actually add any method but it
 implies that the count operation will be fast.


 On Tuesday, 4 August 2015, Laurent PETIT laurent.pe...@gmail.com wrote:

 If I'm remember correctly, the Counted interface must only be implemented
 by collection implementations for which it is guaranteed that count() is an
 O(~1) operation

 2015-08-04 17:07 GMT+02:00 Keisuke Fukuda keisukefuk...@gmail.com:

 Hello,

 I've been investigating the basic data structures and their underlying
 concepts in Clojure, particularly focusing on the definitions of coll, seq,
 map, vector, set, etc. and their inclusion relationships.

 I saw a Venn diagram in this page[1]. Although it is as of Clojure 1.3,
 I confirmed it is still correct. Counted interface has its only method
 count() and it implies that we can get the explicit size of a Counted
 collection.

 However, IPersistentCollection, which is actually the definition of
 collections, also has count() method. It's a bit surprising to me that even
 LazySeq supports count() (indirectly via ISeq).

 Questions:
 If IPersistentCollection has count() method, What is Counted for?
 Is it always reasonable for LazySeq to support count() method? Shouldn't
 there be an explicit CountedLazySeq,

 Thanks.
 Keisuke

 [1] http://www.brainonfire.net/files/seqs-and-colls/main.html


 --
 FUKUDA, Keisuke 福田圭祐
 Tokyo, Japan
 Email: keisukefuk...@gmail.com

 --
 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.




 --
 Laurent Petit

 --
 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.


-- 
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.


Re: add-watch and writing data into a core.async channel

2015-07-31 Thread Raymond Huang
Thanks everyone for the suggestions, I'll try it out later today

@leon Thanks. I wish this were documented in the API for how to write
Clojure/Script compatible code. Just saw your answer on stackoverflow
http://stackoverflow.com/questions/20927582/clojure-why-does-execution-hang-when-doing-blocking-insert-into-channel-core
which
was very insightful.

@timothy Interesting to know. I've seen that myself, but assumed it was
solely due to a logic flaw in my program. I'll have to think through this
problem more.

On Fri, Jul 31, 2015 at 6:02 AM Timothy Baldridge tbaldri...@gmail.com
wrote:

 One gotcha is that atoms add-watches do not always guarantee order
 semantics. So if you have a watch put [old-val new-val] on a channel, and
 your atom operation is something like (swap! a inc), you may see values in
 your channel like this:

 [0 1]
 [2 3]
 [1 2]
 [3 4]
 [6 7]
 [4 5]

 This is because the watches are dispatched in different threads. So just
 be careful when doing this.

 Timothy

 On Fri, Jul 31, 2015 at 6:53 AM, Stefan Kamphausen ska2...@gmail.com
 wrote:


 On Friday, July 31, 2015 at 8:21:18 AM UTC+2, Raymond Huang wrote:

 I'd like to use `add-watch` on an atom which writes the data to a
 core.async channel. So far, I've come up with this, but it seems bad
 because I create a new go-routine everytime something happens.


 Makes me think, one might want to have an add-channel function on ARef in
 general.


 stefan


 --

 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.




 --
 “One of the main causes of the fall of the Roman Empire was that–lacking
 zero–they had no way to indicate successful termination of their C
 programs.”
 (Robert Firth)

 --
 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.


add-watch and writing data into a core.async channel

2015-07-31 Thread Raymond Huang
I'd like to use `add-watch` on an atom which writes the data to a 
core.async channel. So far, I've come up with this, but it seems bad 
because I create a new go-routine everytime something happens.

(add-watch ref watch-id #(go (a/! user-changes %)))

This seems like a bad idea to me because I am creating a new go routine 
everytime. Furthermore, I'd like this to be portable between Clojure  
Clojurescript.

I can't think of how I'd be able to solve this.

-- 
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.


Re: [BUG] : clojure.data/diff handles nested empty collections incorrectly

2015-02-22 Thread Raymond Huang
Not trying to hijack this thread, @andy check out Differential Sync.

On Sat, Feb 21, 2015, 4:36 PM Andy Fingerhut andy.finger...@gmail.com
wrote:

 Sorry if you've already explained this and I'm missing it, but for
 example, suppose the current state on both sides is {:x {:y 1}}, and the
 'sender' wants to change to one of these states:

 (a) {:x nil}
 (b) {:x {}}
 (b) {:x []}
 (c) {:x {:y nil}}

 Do you plan to support sending a different 'diff' in each of these cases,
 such that the 'receiver' can end up in the same final state, for each of
 these case?

 Or perhaps the idea is that some of those are not supported?

 Thanks,
 Andy

 On Fri, Feb 20, 2015 at 8:13 PM, Timothy Pratley timothyprat...@gmail.com
  wrote:

 Hi Andy,


 On Fri, Feb 20, 2015 at 5:51 PM, Andy Fingerhut andy.finger...@gmail.com
  wrote:

 The goal with your library is to transmit deltas between two systems,
 and then apply those deltas to the other system to make them match, yes?


 Correct, it works well for what I need it to do. :)


 How would you use the diff return value ({:x {:y 1}} nil nil) to cause a
 system that currently has {:x {:y 1}} to change to {:x {}}, as opposed to
 some other state?  That is, how would it know it needs to change the value
 associated with :x to {} as opposed to removing the key :x and its value
 entirely?


 The short answer is (update-in state [:x] dissoc :y).
 Which is identical in result to (assoc state :x {}).
 So either representation could be used to accomplish the goal, and can be
 interchanged.

 As such I think either solution would be great! (and am happy to provide
 a patch either way).


 Below digresses from clojure.core/diff concerns, but I'm including it to
 more fully answer your question.

 I'll expand a little on the way patchin currently works. The second
 clojure.data/diff return value is used as replacements. The first item
 returned from clojure.data/diff is used as the keys to dissoc, excluding
 things that would be replaced anyway. If the patch size is greater than the
 target, just the target is sent. So in the end it constructs the same patch
 you described (as it is smaller). Valid patches look like either:
 [x]
 [diss replace]
 So the patch sent is
 [{:x {}}]
 Which means replace the state with {:x {}}
 but for {:x {:y foo, z bar, w baz}} - {:x {:z bar, w baz, q
 bonza}} the patch sent is
 [{:x {:y 1}} {:x {:q bonza}}]
 Which means replace in state [:x :q] bonza, and strip out [:x :y].
 Plus some minor tricks to handle sets, and treat sequences as values.
 There are good resources for sequence diff compression but haven't
 thought of a good way to represent them in the same patch as a structural
 diff, and haven't had the need.

 I do not think clojure.data/diff need concern itself with optimization,
 as it currently serves the purpose of identifying differences very well,
 and optimization comes with calculation/size tradeoffs specific to the
 usage.


 Regards,
 Timothy

  --
 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.


-- 
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