Re: About determinism of async

2017-10-11 Thread JokkeB
Thanks. I'm not interested in reading the messages as pairs, I just need to 
make sure nothing gets in between them. I think I'll choose some way to 
merge the messages, for example just a vector like you suggested, and then 
have the end consumer recognise and split the vector. I guess splitting the 
vector into two messages somewhere before the end consumer can't be made 
deterministic.

keskiviikko 11. lokakuuta 2017 8.02.40 UTC+3 Rangel Spasov kirjoitti:
>
> I think simply wrapping the two values in a vector is the only thing 
> that's needed in this case. Simply do a put like (>!! ch [my-val-1 
> my-val-2]) and take from the channel from another place. If my-val-1 and 
> my-val-2 are not immediately available, you can have a separate mechanism 
> (atoms, (loop [...] (recur ...)) or another set of core.async channels 
> perhaps) that "collects" them until they are ready to be sent together as 
> one value.  
>
> partition-all on its own does not really help with the ordering here. For 
> example:
>
> (let [ch (chan 42 (partition-all 2))]
>   (>!! ch :x')
>   (thread   ;in another 
> thread far, far away
> ( for random 0-99ms 
> ;put value on ch
> (>!! ch :y'))
>
>   ( for random 0-99ms 
>   (>!! ch :x'')
>
>   ;take from ch
>   (
>
> This will non-deterministically output either 
> => [:x' :x'']
>
> or 
>
> => [:x' :y']
>
> But again as I said, you can employ partition-all separately as a 
> "collecting" mechanism before doing the (>!! ch [my-val-1 my-val-2]). 
> Didn't write an example for that but let me know if that's not clear and I 
> can put together a few lines.
>
> On Tuesday, October 10, 2017 at 7:50:20 AM UTC-7, Gary Trakhman wrote:
>>
>> So, at the point where you need 2 things to be consecutive, wrap them up 
>> in a vector so they're one thing. `(partition-all 2)` will return a 
>> transducer xform that chunks up your message stream by 2 
>> https://clojuredocs.org/clojure.core/partition-all, and if you need to 
>> undo it you can do so with the `cat` transducer 
>> https://clojuredocs.org/clojure.core/cat .  
>>
>> On Tue, Oct 10, 2017 at 10:42 AM JokkeB  wrote:
>>
>>> Thanks for the response. That's what I suspected.
>>>
>>> How does partition help me in this case? I can't see any way of using it.
>>>
>>> How about onto-chan, would that be deterministic? Or any other function?
>>>
>>>
>>> tiistai 10. lokakuuta 2017 17.33.22 UTC+3 Gary Trakhman kirjoitti:
>>>
 I think a core assumption is that all writes can yield control at any 
 time to other worker go processes.  I wouldn't rely on the consecutive 
 behavior even if it were true, nondeterminism is a good assumption with 
 core.async.  If you need that particular guarantee, consider a call to 
 partition?

 On Tue, Oct 10, 2017 at 10:30 AM JokkeB  wrote:

>>> I'm wondering about a case when using async:
>
> I have a channel where I write from multiple threads. One of the 
> sources is a go-loop with a timeout, so each second I write something to 
> the channel. If I do two consecutive writes inside the go block, can 
> another thread write between the two writes? Or can I rely on the two 
> messages being consecutive in the channel?
>
> -- 
> 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 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@goo

Re: Is the Learning Guide in Order?

2017-10-11 Thread Matching Socks
There are some books that give a cohesive and well-ordered introduction. 
 If you can still find a copy of "Clojure Programming", by Emerick, Carper, 
and Grand, that's the one that I found most thoroughly helpful with the 
standard library.  Also, it has a pretty good index and I made frequent 
reference back to it for a while.  After "a while", of course, you get the 
picture and fling all books aside (until the next one comes out).  

-- 
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: About determinism of async

2017-10-11 Thread Gary Trakhman
If you don't want to split at the consumer I would recommend adding another
channel, and piping it with a cat xform as mentioned above.

On Oct 11, 2017 3:28 AM, "JokkeB"  wrote:

> Thanks. I'm not interested in reading the messages as pairs, I just need
> to make sure nothing gets in between them. I think I'll choose some way to
> merge the messages, for example just a vector like you suggested, and then
> have the end consumer recognise and split the vector. I guess splitting the
> vector into two messages somewhere before the end consumer can't be made
> deterministic.
>
> keskiviikko 11. lokakuuta 2017 8.02.40 UTC+3 Rangel Spasov kirjoitti:
>>
>> I think simply wrapping the two values in a vector is the only thing
>> that's needed in this case. Simply do a put like (>!! ch [my-val-1
>> my-val-2]) and take from the channel from another place. If my-val-1 and
>> my-val-2 are not immediately available, you can have a separate mechanism
>> (atoms, (loop [...] (recur ...)) or another set of core.async channels
>> perhaps) that "collects" them until they are ready to be sent together as
>> one value.
>>
>> partition-all on its own does not really help with the ordering here. For
>> example:
>>
>> (let [ch (chan 42 (partition-all 2))]
>>   (>!! ch :x')
>>   (thread   ;in another 
>> thread far, far away
>> (> for random 0-99ms
>> ;put value on ch
>> (>!! ch :y'))
>>
>>   (> for random 0-99ms
>>   (>!! ch :x'')
>>
>>   ;take from ch
>>   (>
>>
>> This will non-deterministically output either
>> => [:x' :x'']
>>
>> or
>>
>> => [:x' :y']
>>
>> But again as I said, you can employ partition-all separately as a
>> "collecting" mechanism before doing the (>!! ch [my-val-1 my-val-2]).
>> Didn't write an example for that but let me know if that's not clear and
>> I can put together a few lines.
>>
>> On Tuesday, October 10, 2017 at 7:50:20 AM UTC-7, Gary Trakhman wrote:
>>>
>>> So, at the point where you need 2 things to be consecutive, wrap them up
>>> in a vector so they're one thing. `(partition-all 2)` will return a
>>> transducer xform that chunks up your message stream by 2
>>> https://clojuredocs.org/clojure.core/partition-all, and if you need to
>>> undo it you can do so with the `cat` transducer
>>> https://clojuredocs.org/clojure.core/cat .
>>>
>>> On Tue, Oct 10, 2017 at 10:42 AM JokkeB  wrote:
>>>
 Thanks for the response. That's what I suspected.

 How does partition help me in this case? I can't see any way of using
 it.

 How about onto-chan, would that be deterministic? Or any other function?


 tiistai 10. lokakuuta 2017 17.33.22 UTC+3 Gary Trakhman kirjoitti:

> I think a core assumption is that all writes can yield control at any
> time to other worker go processes.  I wouldn't rely on the consecutive
> behavior even if it were true, nondeterminism is a good assumption with
> core.async.  If you need that particular guarantee, consider a call to
> partition?
>
> On Tue, Oct 10, 2017 at 10:30 AM JokkeB  wrote:
>
 I'm wondering about a case when using async:
>>
>> I have a channel where I write from multiple threads. One of the
>> sources is a go-loop with a timeout, so each second I write something to
>> the channel. If I do two consecutive writes inside the go block, can
>> another thread write between the two writes? Or can I rely on the two
>> messages being consecutive in the channel?
>>
>> --
>> 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 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 

Re: About determinism of async

2017-10-11 Thread Timothy Baldridge
If you want to simply keep some messages in order, then a cat transducer
will do the trick just fine:


;; need a buffer or buffer size to get to the transducer param
(def c (chan 20 cat))

(async/onto-chan c [1])

(async/>!! c [2 3 4])
(async/close! c)

(
wrote:

> If you don't want to split at the consumer I would recommend adding
> another channel, and piping it with a cat xform as mentioned above.
>
> On Oct 11, 2017 3:28 AM, "JokkeB"  wrote:
>
>> Thanks. I'm not interested in reading the messages as pairs, I just need
>> to make sure nothing gets in between them. I think I'll choose some way to
>> merge the messages, for example just a vector like you suggested, and then
>> have the end consumer recognise and split the vector. I guess splitting the
>> vector into two messages somewhere before the end consumer can't be made
>> deterministic.
>>
>> keskiviikko 11. lokakuuta 2017 8.02.40 UTC+3 Rangel Spasov kirjoitti:
>>>
>>> I think simply wrapping the two values in a vector is the only thing
>>> that's needed in this case. Simply do a put like (>!! ch [my-val-1
>>> my-val-2]) and take from the channel from another place. If my-val-1 and
>>> my-val-2 are not immediately available, you can have a separate mechanism
>>> (atoms, (loop [...] (recur ...)) or another set of core.async channels
>>> perhaps) that "collects" them until they are ready to be sent together as
>>> one value.
>>>
>>> partition-all on its own does not really help with the ordering here.
>>> For example:
>>>
>>> (let [ch (chan 42 (partition-all 2))]
>>>   (>!! ch :x')
>>>   (thread   ;in another 
>>> thread far, far away
>>> (>> for random 0-99ms
>>> ;put value on ch
>>> (>!! ch :y'))
>>>
>>>   (>> for random 0-99ms
>>>   (>!! ch :x'')
>>>
>>>   ;take from ch
>>>   (>>
>>>
>>> This will non-deterministically output either
>>> => [:x' :x'']
>>>
>>> or
>>>
>>> => [:x' :y']
>>>
>>> But again as I said, you can employ partition-all separately as a
>>> "collecting" mechanism before doing the (>!! ch [my-val-1 my-val-2]).
>>> Didn't write an example for that but let me know if that's not clear and
>>> I can put together a few lines.
>>>
>>> On Tuesday, October 10, 2017 at 7:50:20 AM UTC-7, Gary Trakhman wrote:

 So, at the point where you need 2 things to be consecutive, wrap them
 up in a vector so they're one thing. `(partition-all 2)` will return a
 transducer xform that chunks up your message stream by 2
 https://clojuredocs.org/clojure.core/partition-all, and if you need to
 undo it you can do so with the `cat` transducer
 https://clojuredocs.org/clojure.core/cat .

 On Tue, Oct 10, 2017 at 10:42 AM JokkeB  wrote:

> Thanks for the response. That's what I suspected.
>
> How does partition help me in this case? I can't see any way of using
> it.
>
> How about onto-chan, would that be deterministic? Or any other
> function?
>
>
> tiistai 10. lokakuuta 2017 17.33.22 UTC+3 Gary Trakhman kirjoitti:
>
>> I think a core assumption is that all writes can yield control at any
>> time to other worker go processes.  I wouldn't rely on the consecutive
>> behavior even if it were true, nondeterminism is a good assumption with
>> core.async.  If you need that particular guarantee, consider a call to
>> partition?
>>
>> On Tue, Oct 10, 2017 at 10:30 AM JokkeB  wrote:
>>
> I'm wondering about a case when using async:
>>>
>>> I have a channel where I write from multiple threads. One of the
>>> sources is a go-loop with a timeout, so each second I write something to
>>> the channel. If I do two consecutive writes inside the go block, can
>>> another thread write between the two writes? Or can I rely on the two
>>> messages being consecutive in the channel?
>>>
>>> --
>>> 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 clo...@googlegroups.com
> Note that posts from new members are moderated - pleas

Re: Is the Learning Guide in Order?

2017-10-11 Thread Mark Nutter
See also https://www.braveclojure.com/.

On Tue, Oct 10, 2017 at 9:11 PM, Tomiwa Ademidun 
wrote:

> Hey guys,
>
> I Finally started learning Lisp/Clojure thanks to inspiration from the
> great Paul Graham's essays . First, I
> wanted to say I appreciate your work in putting together the tutorial and
> clojure-docs website, its very helpful and I really appreciate all your
> efforts.
>
> After working through the introduction
> , I'm about
> to start the language guide
> . I was
> just wondering if there is a recommended order in which to work through the
> guide (or should I do a tutorial and then use the guide as a reference?).
> I'm assuming I should start with functions, if so, what comes after that as
> I am a bit overwhelmed by all the things I don't know :)
>
>
> Thanks,
> Tomiwa
>
> --
> 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: Is there a better way to get to `Classname[].class` ?

2017-10-11 Thread pericles macedo
Thanks Peter,
Yeah, I didn't find that reference before. It would have saved me a couple 
hours. I found something similar in a few places, but it only had the 
primitive types. It missed the class specific element type.

On Tuesday, October 10, 2017 at 3:22:38 AM UTC-7, Peter Hull wrote:
>
> I actually preferred your solution, pericles, because it doesn't require 
> memorising the "[L...;" syntax, and works if you don't know the class at 
> compile time. By the way you can use make-array to create a zero size array 
> which might be (ever so slightly) more efficient.
>
> For reference (apologies if you already knew this), the class name syntax 
> is outlined here:
> https://docs.oracle.com/javase/9/docs/api/java/lang/Class.html#getName-- 
> 
> and for the full details
> https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.9.1
>
>

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


beginners' puzzle

2017-10-11 Thread googolglesucks
how these keywords in clojure  implemented  
could  anyone anwer me ?

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


How to add a java servlet into a clojure ring project

2017-10-11 Thread 'Alexandra Strekalova' via Clojure


I am integrating Togglz library into a Clojure Ring project to support 
feature toggles and would like to activate the Togglz admin console. 
According to the Togglz documentation it is necessary to add a servlet in 
the /WEB-INF/web.xml file for projects that don't support Servlet 3.0. I 
used the :uberjar-merge-with leiningen plugin to merge the file with the 
Togglz servlet configuration with the web.xml file autogenerated by 
leiningen. However, this was not sufficient to activate the admin console. 
I could not find much information on how to integrate a servlet from an 
external library into a Ring application. What would be the best way to do 
it?

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


Does (into) ever combine 2 numbers into 1?

2017-10-11 Thread lawrence . krubner
I seem unable to figure out where I made a mistake, though this should be 
simple.

I have two SQL calls that bring back 5 fields:

 SELECT company_profile_id ,  reference_id,  reference_source   FROM   
company_reference_idlimit 1  ;

++--+--+
| company_profile_id | reference_id | reference_source |
++--+--+
|  2 | 331089191| EIN  |
++--+--+

 SELECT company_profile_id, urlFROM company_website limit 1 
  ;

++--+
| company_profile_id | url  |
++--+
|  2 | mikeshawauto.com |
++--+

This brings back a total of 5 values. I need to have a document that has 5 
values, though if values have the same field-name, then I want to 
consolidate them into one vector. There are 4 unique field names, so I 
expect to end up with 4 vectors, holding 5 values. Instead, I get this: 

({:company_profile_id ["2"], :topic :company, 
:how-many-rows-and-fields-from-database 13, :url ["mikeshawauto.com"], 
:reference_id ["331089191"], :reference_source ["ein"]})

I expect: 

{:company_profile_id ["2" "2"]

but I get: 

{:company_profile_id ["2"]

The documents are combined in a map in an atom, with this function: 


(def documents (atom {}))


(defn update-documents
  [denormalized-id field-name field-value 
how-many-rows-and-fields-from-database topic]
  {:pre [
 (not (nil? denormalized-id))
 (not (nil? field-name))
 (vector? field-value)
 ]}
  (swap! documents
 (fn [old-documents]
   (slingshot/try+
(let [
  document (get old-documents denormalized-id {})
  old-field-value (get old-documents field-name [])
  new-field-value (into old-field-value field-value)
  document (assoc document field-name new-field-value)

  previous-how-many-rows-and-fields-from-database (get 
document :how-many-rows-and-fields-from-database 0)
  new-how-many-rows-and-fields-from-database (+ 
previous-how-many-rows-and-fields-from-database 
how-many-rows-and-fields-from-database)
  document (assoc document :topic topic)
  document (assoc document 
:how-many-rows-and-fields-from-database 
new-how-many-rows-and-fields-from-database)
  new-documents (assoc old-documents denormalized-id 
document)
  ]
  new-documents)
(catch Object o
  (errors/log o) 
  (slingshot/throw+ {
 :type ::update-documents
 :error o
 }
))

Can I assume that this always gives me 2 values in a vector? 

  old-field-value (get old-documents field-name [])
  new-field-value (into old-field-value field-value)
  document (assoc document field-name new-field-value)

I'm going to guess that the bug is somewhere else in my code. But if anyone 
sees a flaw in this function, I'd be grateful if you could point it out to 
me. 



-- 
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: Does (into) ever combine 2 numbers into 1?

2017-10-11 Thread lawrence . krubner
Nevermind. Something about my reasoning is off on this one. I notice that 
even if I use conj, the same problem happens, I get 4 values in 4 vectors 
instead of 5 values in 4 vectors. So there must be some earlier step that 
I've gotten wrong. 


On Wednesday, October 11, 2017 at 11:44:40 AM UTC-4, lawrence...@gmail.com 
wrote:
>
> I seem unable to figure out where I made a mistake, though this should be 
> simple.
>
> I have two SQL calls that bring back 5 fields:
>
>  SELECT company_profile_id ,  reference_id,  reference_source   FROM   
> company_reference_idlimit 1  ;
>
> ++--+--+
> | company_profile_id | reference_id | reference_source |
> ++--+--+
> |  2 | 331089191| EIN  |
> ++--+--+
>
>  SELECT company_profile_id, urlFROM company_website limit 
> 1   ;
>
> ++--+
> | company_profile_id | url  |
> ++--+
> |  2 | mikeshawauto.com |
> ++--+
>
> This brings back a total of 5 values. I need to have a document that has 5 
> values, though if values have the same field-name, then I want to 
> consolidate them into one vector. There are 4 unique field names, so I 
> expect to end up with 4 vectors, holding 5 values. Instead, I get this: 
>
> ({:company_profile_id ["2"], :topic :company, 
> :how-many-rows-and-fields-from-database 13, :url ["mikeshawauto.com"], 
> :reference_id ["331089191"], :reference_source ["ein"]})
>
> I expect: 
>
> {:company_profile_id ["2" "2"]
>
> but I get: 
>
> {:company_profile_id ["2"]
>
> The documents are combined in a map in an atom, with this function: 
>
>
> (def documents (atom {}))
>
>
> (defn update-documents
>   [denormalized-id field-name field-value 
> how-many-rows-and-fields-from-database topic]
>   {:pre [
>  (not (nil? denormalized-id))
>  (not (nil? field-name))
>  (vector? field-value)
>  ]}
>   (swap! documents
>  (fn [old-documents]
>(slingshot/try+
> (let [
>   document (get old-documents denormalized-id {})
>   old-field-value (get old-documents field-name [])
>   new-field-value (into old-field-value field-value)
>   document (assoc document field-name new-field-value)
>
>   previous-how-many-rows-and-fields-from-database (get 
> document :how-many-rows-and-fields-from-database 0)
>   new-how-many-rows-and-fields-from-database (+ 
> previous-how-many-rows-and-fields-from-database 
> how-many-rows-and-fields-from-database)
>   document (assoc document :topic topic)
>   document (assoc document 
> :how-many-rows-and-fields-from-database 
> new-how-many-rows-and-fields-from-database)
>   new-documents (assoc old-documents denormalized-id 
> document)
>   ]
>   new-documents)
> (catch Object o
>   (errors/log o) 
>   (slingshot/throw+ {
>  :type ::update-documents
>  :error o
>  }
> ))
>
> Can I assume that this always gives me 2 values in a vector? 
>
>   old-field-value (get old-documents field-name [])
>   new-field-value (into old-field-value field-value)
>   document (assoc document field-name new-field-value)
>
> I'm going to guess that the bug is somewhere else in my code. But if 
> anyone sees a flaw in this function, I'd be grateful if you could point it 
> out to me. 
>
>
>
>

-- 
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: beginners' puzzle

2017-10-11 Thread Timothy Baldridge
Best answer for that is probably the source code itself:
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Keyword.java

On Wed, Oct 11, 2017 at 9:07 AM,  wrote:

> how these keywords in clojure  implemented
> could  anyone anwer me ?
>
> --
> 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.


Re: Does (into) ever combine 2 numbers into 1?

2017-10-11 Thread lawrence . krubner
Using conj instead of into, for no particular reason, except debugging. The 
document is slowly built-up: 

({:company_profile_id [["2"]], :topic :company, :url 
[["mikeshawauto.com"]]})

({:company_profile_id [["2"]], :topic :company, :url 
[["mikeshawauto.com"]]})

({:company_profile_id [["2"]], :topic :company, :url 
[["mikeshawauto.com"]], :reference_id [["331089191"]]})

In the transition from row 1 to row 2, I assume the field being added is 
company_profile_id. Why is there no change? Why isn't a new value added to 
the vector? I must be missing something obvious. 







On Wednesday, October 11, 2017 at 11:44:40 AM UTC-4, lawrence...@gmail.com 
wrote:
>
> I seem unable to figure out where I made a mistake, though this should be 
> simple.
>
> I have two SQL calls that bring back 5 fields:
>
>  SELECT company_profile_id ,  reference_id,  reference_source   FROM   
> company_reference_idlimit 1  ;
>
> ++--+--+
> | company_profile_id | reference_id | reference_source |
> ++--+--+
> |  2 | 331089191| EIN  |
> ++--+--+
>
>  SELECT company_profile_id, urlFROM company_website limit 
> 1   ;
>
> ++--+
> | company_profile_id | url  |
> ++--+
> |  2 | mikeshawauto.com |
> ++--+
>
> This brings back a total of 5 values. I need to have a document that has 5 
> values, though if values have the same field-name, then I want to 
> consolidate them into one vector. There are 4 unique field names, so I 
> expect to end up with 4 vectors, holding 5 values. Instead, I get this: 
>
> ({:company_profile_id ["2"], :topic :company, 
> :how-many-rows-and-fields-from-database 13, :url ["mikeshawauto.com"], 
> :reference_id ["331089191"], :reference_source ["ein"]})
>
> I expect: 
>
> {:company_profile_id ["2" "2"]
>
> but I get: 
>
> {:company_profile_id ["2"]
>
> The documents are combined in a map in an atom, with this function: 
>
>
> (def documents (atom {}))
>
>
> (defn update-documents
>   [denormalized-id field-name field-value 
> how-many-rows-and-fields-from-database topic]
>   {:pre [
>  (not (nil? denormalized-id))
>  (not (nil? field-name))
>  (vector? field-value)
>  ]}
>   (swap! documents
>  (fn [old-documents]
>(slingshot/try+
> (let [
>   document (get old-documents denormalized-id {})
>   old-field-value (get old-documents field-name [])
>   new-field-value (into old-field-value field-value)
>   document (assoc document field-name new-field-value)
>
>   previous-how-many-rows-and-fields-from-database (get 
> document :how-many-rows-and-fields-from-database 0)
>   new-how-many-rows-and-fields-from-database (+ 
> previous-how-many-rows-and-fields-from-database 
> how-many-rows-and-fields-from-database)
>   document (assoc document :topic topic)
>   document (assoc document 
> :how-many-rows-and-fields-from-database 
> new-how-many-rows-and-fields-from-database)
>   new-documents (assoc old-documents denormalized-id 
> document)
>   ]
>   new-documents)
> (catch Object o
>   (errors/log o) 
>   (slingshot/throw+ {
>  :type ::update-documents
>  :error o
>  }
> ))
>
> Can I assume that this always gives me 2 values in a vector? 
>
>   old-field-value (get old-documents field-name [])
>   new-field-value (into old-field-value field-value)
>   document (assoc document field-name new-field-value)
>
> I'm going to guess that the bug is somewhere else in my code. But if 
> anyone sees a flaw in this function, I'd be grateful if you could point it 
> out to me. 
>
>
>
>

-- 
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: Does (into) ever combine 2 numbers into 1?

2017-10-11 Thread lawrence . krubner
So I have this: 

({:company_profile_id ["2"], :topic :company, :url ["mikeshawauto.com"]})

And then I get this field name and value: 

(:company_profile_id)

(["2"])

The next 3 lines of code are: 

  old-field-value (get old-documents field-name [])
  new-field-value (into old-field-value field-value)
  document (assoc document field-name new-field-value)

And when the function is next called, I end up with :

({:company_profile_id ["2"], :topic :company, :url ["mikeshawauto.com"]})

I need: 

({:company_profile_id ["2", "2"], :topic :company, :url 
["mikeshawauto.com"]})

So perhaps I've misunderstood what (into) is for? How do I add another the 
values of these 2 vectors together? 





On Wednesday, October 11, 2017 at 12:20:55 PM UTC-4, lawrence...@gmail.com 
wrote:
>
> Using conj instead of into, for no particular reason, except debugging. 
> The document is slowly built-up: 
>
> ({:company_profile_id [["2"]], :topic :company, :url [["mikeshawauto.com
> "]]})
>
> ({:company_profile_id [["2"]], :topic :company, :url [["mikeshawauto.com
> "]]})
>
> ({:company_profile_id [["2"]], :topic :company, :url [["mikeshawauto.com"]], 
> :reference_id [["331089191"]]})
>
> In the transition from row 1 to row 2, I assume the field being added is 
> company_profile_id. Why is there no change? Why isn't a new value added to 
> the vector? I must be missing something obvious. 
>
>
>
>
>
>
>
> On Wednesday, October 11, 2017 at 11:44:40 AM UTC-4, lawrence...@gmail.com 
> wrote:
>>
>> I seem unable to figure out where I made a mistake, though this should be 
>> simple.
>>
>> I have two SQL calls that bring back 5 fields:
>>
>>  SELECT company_profile_id ,  reference_id,  reference_source   FROM   
>> company_reference_idlimit 1  ;
>>
>> ++--+--+
>> | company_profile_id | reference_id | reference_source |
>> ++--+--+
>> |  2 | 331089191| EIN  |
>> ++--+--+
>>
>>  SELECT company_profile_id, urlFROM company_website limit 
>> 1   ;
>>
>> ++--+
>> | company_profile_id | url  |
>> ++--+
>> |  2 | mikeshawauto.com |
>> ++--+
>>
>> This brings back a total of 5 values. I need to have a document that has 
>> 5 values, though if values have the same field-name, then I want to 
>> consolidate them into one vector. There are 4 unique field names, so I 
>> expect to end up with 4 vectors, holding 5 values. Instead, I get this: 
>>
>> ({:company_profile_id ["2"], :topic :company, 
>> :how-many-rows-and-fields-from-database 13, :url ["mikeshawauto.com"], 
>> :reference_id ["331089191"], :reference_source ["ein"]})
>>
>> I expect: 
>>
>> {:company_profile_id ["2" "2"]
>>
>> but I get: 
>>
>> {:company_profile_id ["2"]
>>
>> The documents are combined in a map in an atom, with this function: 
>>
>>
>> (def documents (atom {}))
>>
>>
>> (defn update-documents
>>   [denormalized-id field-name field-value 
>> how-many-rows-and-fields-from-database topic]
>>   {:pre [
>>  (not (nil? denormalized-id))
>>  (not (nil? field-name))
>>  (vector? field-value)
>>  ]}
>>   (swap! documents
>>  (fn [old-documents]
>>(slingshot/try+
>> (let [
>>   document (get old-documents denormalized-id {})
>>   old-field-value (get old-documents field-name [])
>>   new-field-value (into old-field-value field-value)
>>   document (assoc document field-name new-field-value)
>>
>>   previous-how-many-rows-and-fields-from-database (get 
>> document :how-many-rows-and-fields-from-database 0)
>>   new-how-many-rows-and-fields-from-database (+ 
>> previous-how-many-rows-and-fields-from-database 
>> how-many-rows-and-fields-from-database)
>>   document (assoc document :topic topic)
>>   document (assoc document 
>> :how-many-rows-and-fields-from-database 
>> new-how-many-rows-and-fields-from-database)
>>   new-documents (assoc old-documents denormalized-id 
>> document)
>>   ]
>>   new-documents)
>> (catch Object o
>>   (errors/log o) 
>>   (slingshot/throw+ {
>>  :type ::update-documents
>>  :error o
>>  }
>> ))
>>
>> Can I assume that this always gives me 2 values in a vector? 
>>
>>   old-field-value (get old-documents field-name [])
>>   new-field-value (into old-field-value field-value)
>>   document (assoc document field-name new-field-value)
>>

CLJS: experiencing "callback envy" re closures as DOM event handlers

2017-10-11 Thread hiskennyness
I am cobbling together my own little CLJS web framework and it is going 
well but I am stumped by one bit of interop: supporting event handlers that 
close over lexical variables. It seems to be a piece of cake for, inter 
alia, Reagent. Here is an excerpt from the "simple" example, hacked a bit 
(the "xxx" bits) to make sure I was seeing what I was seeing:

(defn color-input []
  (let [xxx (atom 0)]
[:div.color-input
 "Time color: "
 [:input {:type  "text"
  :value @time-color
  :on-change #(do (reset! xxx (rand-int 32767))
  (println :xnow @xxx)
  (reset! time-color (-> % .-target .-value)))}]]))


My approach is to convert the anonymous function to  a string via STR and 
specify it in the generate HTML as the handler. Just to see my html I have 
a little test code:

(let [xxx (atom 42)]
  (println :htm!!! (tag/to-html [(h1 {:onclick (on-evt #(swap! xxx inc))} 
"Help!")])))


Here is `on-evt`:

(defn on-evt [cbfn]
  (cl-format nil
"(~a)(event)"
(str cbfn)))


Here is what I see in the console:
:htm!!! Help!

But JS understandably does not see the  "xxx_12780".

I have tried more than once digging into the reagent code to see how it is 
working its magic but always run into a dead end. 

The one thing I do see when I inspect the DOM in the Chrome debugger is 
that the handler is not there on the target element, just a react-id or 
some such. This makes me think that the anonymous function itself (happily 
compiled into JS closed over the lexical variable) is being stashed in a 
dictionary under the react-id and that a handler at the document level is 
navigating from the event target to the closure via the react-id.

That's just crazy enough to work. :) But am I just missing some simple CLJS 
interop capability? Any other ideas? 







-- 
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: CLJS: experiencing "callback envy" re closures as DOM event handlers

2017-10-11 Thread James Reeves
If you output your HTML as DOM nodes, rather than a string, you can just
attach the function directly to the attribute.

On 11 October 2017 at 18:20, hiskennyness  wrote:

> I am cobbling together my own little CLJS web framework and it is going
> well but I am stumped by one bit of interop: supporting event handlers that
> close over lexical variables. It seems to be a piece of cake for, inter
> alia, Reagent. Here is an excerpt from the "simple" example, hacked a bit
> (the "xxx" bits) to make sure I was seeing what I was seeing:
>
> (defn color-input []
>   (let [xxx (atom 0)]
> [:div.color-input
>  "Time color: "
>  [:input {:type  "text"
>   :value @time-color
>   :on-change #(do (reset! xxx (rand-int 32767))
>   (println :xnow @xxx)
>   (reset! time-color (-> % .-target 
> .-value)))}]]))
>
>
> My approach is to convert the anonymous function to  a string via STR and
> specify it in the generate HTML as the handler. Just to see my html I have
> a little test code:
>
> (let [xxx (atom 42)]
>   (println :htm!!! (tag/to-html [(h1 {:onclick (on-evt #(swap! xxx inc))} 
> "Help!")])))
>
>
> Here is `on-evt`:
>
> (defn on-evt [cbfn]
>   (cl-format nil
> "(~a)(event)"
> (str cbfn)))
>
>
> Here is what I see in the console:
> :htm!!! Help!
>
> But JS understandably does not see the  "xxx_12780".
>
> I have tried more than once digging into the reagent code to see how it is
> working its magic but always run into a dead end.
>
> The one thing I do see when I inspect the DOM in the Chrome debugger is
> that the handler is not there on the target element, just a react-id or
> some such. This makes me think that the anonymous function itself (happily
> compiled into JS closed over the lexical variable) is being stashed in a
> dictionary under the react-id and that a handler at the document level is
> navigating from the event target to the closure via the react-id.
>
> That's just crazy enough to work. :) But am I just missing some simple
> CLJS interop capability? Any other ideas?
>
>
>
>
>
>
>
> --
> 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.
>



-- 
James Reeves
booleanknot.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.


Re: Does (into) ever combine 2 numbers into 1?

2017-10-11 Thread lawrence . krubner
So I tried this:

  new-field-value (into [] (concat old-field-value 
field-value))

And I did not get what I expected. Maybe I am sleep deprived, but I don't 
see why I can't build up a vector with several values. This is in a map in 
an atom. This is the code: 

  (swap! documents
 (fn [old-documents]
(let [
  document (get old-documents denormalized-id {})

  _ (errors/log document)
  _ (errors/log field-name)
  _ (errors/log field-value)

  old-field-value (get old-documents field-name [])
  new-field-value (into [] (concat old-field-value 
field-value))
  document (assoc document field-name new-field-value)

  _ (errors/log "final document: " document)
  new-documents (assoc old-documents denormalized-id 
document)
  ]  
  new-documents)

Those log statements show me this for old-field-value:

({:company_profile_id ["2"], :topic :company, :url ["mikeshawauto.com"]})

field-name: 
(:company_profile_id)

field-value:
(["2"])

but I in the final document I only get: 

("final document: " {:company_profile_id ["2"], :topic :company, :url 
["mikeshawauto.com"]})

I want: 

("final document: " {:company_profile_id ["2", "2"], :topic :company, :url 
["mikeshawauto.com"]})

What am I missing here? 




On Wednesday, October 11, 2017 at 12:28:59 PM UTC-4, lawrence...@gmail.com 
wrote:
>
> So I have this: 
>
> ({:company_profile_id ["2"], :topic :company, :url ["mikeshawauto.com"]})
>
> And then I get this field name and value: 
>
> (:company_profile_id)
>
> (["2"])
>
> The next 3 lines of code are: 
>
>   old-field-value (get old-documents field-name [])
>   new-field-value (into old-field-value field-value)
>   document (assoc document field-name new-field-value)
>
> And when the function is next called, I end up with :
>
> ({:company_profile_id ["2"], :topic :company, :url ["mikeshawauto.com"]})
>
> I need: 
>
> ({:company_profile_id ["2", "2"], :topic :company, :url ["mikeshawauto.com
> "]})
>
> So perhaps I've misunderstood what (into) is for? How do I add another the 
> values of these 2 vectors together? 
>
>
>
>
>
> On Wednesday, October 11, 2017 at 12:20:55 PM UTC-4, lawrence...@gmail.com 
> wrote:
>>
>> Using conj instead of into, for no particular reason, except debugging. 
>> The document is slowly built-up: 
>>
>> ({:company_profile_id [["2"]], :topic :company, :url [["mikeshawauto.com
>> "]]})
>>
>> ({:company_profile_id [["2"]], :topic :company, :url [["mikeshawauto.com
>> "]]})
>>
>> ({:company_profile_id [["2"]], :topic :company, :url [["mikeshawauto.com"]], 
>> :reference_id [["331089191"]]})
>>
>> In the transition from row 1 to row 2, I assume the field being added is 
>> company_profile_id. Why is there no change? Why isn't a new value added to 
>> the vector? I must be missing something obvious. 
>>
>>
>>
>>
>>
>>
>>
>> On Wednesday, October 11, 2017 at 11:44:40 AM UTC-4, 
>> lawrence...@gmail.com wrote:
>>>
>>> I seem unable to figure out where I made a mistake, though this should 
>>> be simple.
>>>
>>> I have two SQL calls that bring back 5 fields:
>>>
>>>  SELECT company_profile_id ,  reference_id,  reference_source   FROM   
>>> company_reference_idlimit 1  ;
>>>
>>> ++--+--+
>>> | company_profile_id | reference_id | reference_source |
>>> ++--+--+
>>> |  2 | 331089191| EIN  |
>>> ++--+--+
>>>
>>>  SELECT company_profile_id, urlFROM company_website 
>>> limit 1   ;
>>>
>>> ++--+
>>> | company_profile_id | url  |
>>> ++--+
>>> |  2 | mikeshawauto.com |
>>> ++--+
>>>
>>> This brings back a total of 5 values. I need to have a document that has 
>>> 5 values, though if values have the same field-name, then I want to 
>>> consolidate them into one vector. There are 4 unique field names, so I 
>>> expect to end up with 4 vectors, holding 5 values. Instead, I get this: 
>>>
>>> ({:company_profile_id ["2"], :topic :company, 
>>> :how-many-rows-and-fields-from-database 13, :url ["mikeshawauto.com"], 
>>> :reference_id ["331089191"], :reference_source ["ein"]})
>>>
>>> I expect: 
>>>
>>> {:company_profile_id ["2" "2"]
>>>
>>> but I get: 
>>>
>>> {:company_profile_id ["2"]
>>>
>>> The documents are combined in a map in an atom, with this function: 
>>>
>>>
>>> (def documents (atom {}))
>>>
>>>
>>> (defn update-documents
>>>   [denormalized-id field-name field-value 
>>> how-many-rows-and-fields-from-database topic]
>>>   {:pre [
>>>  (not (nil? denormalized-id))
>>>  (not (nil? field-name))

Re: Does (into) ever combine 2 numbers into 1?

2017-10-11 Thread lawrence . krubner
I should remove the parens before they confuse anyone. They are added by 
the log statement. Without the parens:



{:company_profile_id ["2"], :topic :company, :url ["mikeshawauto.com"]}

field-name: 
:company_profile_id

field-value:
["2"]

but I in the final document I only get: 

"final document: " {:company_profile_id ["2"], :topic :company, :url ["
mikeshawauto.com"]}

I want: 

"final document: " {:company_profile_id ["2" "2"], :topic :company, :url ["
mikeshawauto.com"]}



On Wednesday, October 11, 2017 at 1:42:12 PM UTC-4, lawrence...@gmail.com 
wrote:
>
> So I tried this:
>
>   new-field-value (into [] (concat old-field-value 
> field-value))
>
> And I did not get what I expected. Maybe I am sleep deprived, but I don't 
> see why I can't build up a vector with several values. This is in a map in 
> an atom. This is the code: 
>
>   (swap! documents
>  (fn [old-documents]
> (let [
>   document (get old-documents denormalized-id {})
>
>   _ (errors/log document)
>   _ (errors/log field-name)
>   _ (errors/log field-value)
>
>   old-field-value (get old-documents field-name [])
>   new-field-value (into [] (concat old-field-value 
> field-value))
>   document (assoc document field-name new-field-value)
>
>   _ (errors/log "final document: " document)
>   new-documents (assoc old-documents denormalized-id 
> document)
>   ]  
>   new-documents)
>
> Those log statements show me this for old-field-value:
>
> ({:company_profile_id ["2"], :topic :company, :url ["mikeshawauto.com"]})
>
> field-name: 
> (:company_profile_id)
>
> field-value:
> (["2"])
>
> but I in the final document I only get: 
>
> ("final document: " {:company_profile_id ["2"], :topic :company, :url ["
> mikeshawauto.com"]})
>
> I want: 
>
> ("final document: " {:company_profile_id ["2", "2"], :topic :company, :url 
> ["mikeshawauto.com"]})
>
> What am I missing here? 
>
>
>
>
> On Wednesday, October 11, 2017 at 12:28:59 PM UTC-4, lawrence...@gmail.com 
> wrote:
>>
>> So I have this: 
>>
>> ({:company_profile_id ["2"], :topic :company, :url ["mikeshawauto.com"]})
>>
>> And then I get this field name and value: 
>>
>> (:company_profile_id)
>>
>> (["2"])
>>
>> The next 3 lines of code are: 
>>
>>   old-field-value (get old-documents field-name [])
>>   new-field-value (into old-field-value field-value)
>>   document (assoc document field-name new-field-value)
>>
>> And when the function is next called, I end up with :
>>
>> ({:company_profile_id ["2"], :topic :company, :url ["mikeshawauto.com"]})
>>
>> I need: 
>>
>> ({:company_profile_id ["2", "2"], :topic :company, :url ["
>> mikeshawauto.com"]})
>>
>> So perhaps I've misunderstood what (into) is for? How do I add another 
>> the values of these 2 vectors together? 
>>
>>
>>
>>
>>
>> On Wednesday, October 11, 2017 at 12:20:55 PM UTC-4, 
>> lawrence...@gmail.com wrote:
>>>
>>> Using conj instead of into, for no particular reason, except debugging. 
>>> The document is slowly built-up: 
>>>
>>> ({:company_profile_id [["2"]], :topic :company, :url [["mikeshawauto.com
>>> "]]})
>>>
>>> ({:company_profile_id [["2"]], :topic :company, :url [["mikeshawauto.com
>>> "]]})
>>>
>>> ({:company_profile_id [["2"]], :topic :company, :url 
>>> [["mikeshawauto.com"]], 
>>> :reference_id [["331089191"]]})
>>>
>>> In the transition from row 1 to row 2, I assume the field being added is 
>>> company_profile_id. Why is there no change? Why isn't a new value added to 
>>> the vector? I must be missing something obvious. 
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Wednesday, October 11, 2017 at 11:44:40 AM UTC-4, 
>>> lawrence...@gmail.com wrote:

 I seem unable to figure out where I made a mistake, though this should 
 be simple.

 I have two SQL calls that bring back 5 fields:

  SELECT company_profile_id ,  reference_id,  reference_source   FROM   
 company_reference_idlimit 1  ;

 ++--+--+
 | company_profile_id | reference_id | reference_source |
 ++--+--+
 |  2 | 331089191| EIN  |
 ++--+--+

  SELECT company_profile_id, urlFROM company_website 
 limit 1   ;

 ++--+
 | company_profile_id | url  |
 ++--+
 |  2 | mikeshawauto.com |
 ++--+

 This brings back a total of 5 values. I need to have a document that 
 has 5 values, though if values have the same field-name, then I want to 
 consolidate them into one vector. Ther

Re: Does (into) ever combine 2 numbers into 1?

2017-10-11 Thread lawrence . krubner
Sorry, this is the problem with working all night. My sleep deprived eyes 
skipped over this line: 

  old-field-value (get old-documents field-name [])

I fetch the value from the wrong map. Such a basic error. 


On Wednesday, October 11, 2017 at 1:44:13 PM UTC-4, lawrence...@gmail.com 
wrote:
>
> I should remove the parens before they confuse anyone. They are added by 
> the log statement. Without the parens:
>
>
>
> {:company_profile_id ["2"], :topic :company, :url ["mikeshawauto.com"]}
>
> field-name: 
> :company_profile_id
>
> field-value:
> ["2"]
>
> but I in the final document I only get: 
>
> "final document: " {:company_profile_id ["2"], :topic :company, :url ["
> mikeshawauto.com"]}
>
> I want: 
>
> "final document: " {:company_profile_id ["2" "2"], :topic :company, :url ["
> mikeshawauto.com"]}
>
>
>
> On Wednesday, October 11, 2017 at 1:42:12 PM UTC-4, lawrence...@gmail.com 
> wrote:
>>
>> So I tried this:
>>
>>   new-field-value (into [] (concat old-field-value 
>> field-value))
>>
>> And I did not get what I expected. Maybe I am sleep deprived, but I don't 
>> see why I can't build up a vector with several values. This is in a map in 
>> an atom. This is the code: 
>>
>>   (swap! documents
>>  (fn [old-documents]
>> (let [
>>   document (get old-documents denormalized-id {})
>>
>>   _ (errors/log document)
>>   _ (errors/log field-name)
>>   _ (errors/log field-value)
>>
>>   old-field-value (get old-documents field-name [])
>>   new-field-value (into [] (concat old-field-value 
>> field-value))
>>   document (assoc document field-name new-field-value)
>>
>>   _ (errors/log "final document: " document)
>>   new-documents (assoc old-documents denormalized-id 
>> document)
>>   ]  
>>   new-documents)
>>
>> Those log statements show me this for old-field-value:
>>
>> ({:company_profile_id ["2"], :topic :company, :url ["mikeshawauto.com"]})
>>
>> field-name: 
>> (:company_profile_id)
>>
>> field-value:
>> (["2"])
>>
>> but I in the final document I only get: 
>>
>> ("final document: " {:company_profile_id ["2"], :topic :company, :url ["
>> mikeshawauto.com"]})
>>
>> I want: 
>>
>> ("final document: " {:company_profile_id ["2", "2"], :topic :company, 
>> :url ["mikeshawauto.com"]})
>>
>> What am I missing here? 
>>
>>
>>
>>
>> On Wednesday, October 11, 2017 at 12:28:59 PM UTC-4, 
>> lawrence...@gmail.com wrote:
>>>
>>> So I have this: 
>>>
>>> ({:company_profile_id ["2"], :topic :company, :url ["mikeshawauto.com
>>> "]})
>>>
>>> And then I get this field name and value: 
>>>
>>> (:company_profile_id)
>>>
>>> (["2"])
>>>
>>> The next 3 lines of code are: 
>>>
>>>   old-field-value (get old-documents field-name [])
>>>   new-field-value (into old-field-value field-value)
>>>   document (assoc document field-name new-field-value)
>>>
>>> And when the function is next called, I end up with :
>>>
>>> ({:company_profile_id ["2"], :topic :company, :url ["mikeshawauto.com
>>> "]})
>>>
>>> I need: 
>>>
>>> ({:company_profile_id ["2", "2"], :topic :company, :url ["
>>> mikeshawauto.com"]})
>>>
>>> So perhaps I've misunderstood what (into) is for? How do I add another 
>>> the values of these 2 vectors together? 
>>>
>>>
>>>
>>>
>>>
>>> On Wednesday, October 11, 2017 at 12:20:55 PM UTC-4, 
>>> lawrence...@gmail.com wrote:

 Using conj instead of into, for no particular reason, except debugging. 
 The document is slowly built-up: 

 ({:company_profile_id [["2"]], :topic :company, :url [["
 mikeshawauto.com"]]})

 ({:company_profile_id [["2"]], :topic :company, :url [["
 mikeshawauto.com"]]})

 ({:company_profile_id [["2"]], :topic :company, :url [["
 mikeshawauto.com"]], :reference_id [["331089191"]]})

 In the transition from row 1 to row 2, I assume the field being added 
 is company_profile_id. Why is there no change? Why isn't a new value added 
 to the vector? I must be missing something obvious. 







 On Wednesday, October 11, 2017 at 11:44:40 AM UTC-4, 
 lawrence...@gmail.com wrote:
>
> I seem unable to figure out where I made a mistake, though this should 
> be simple.
>
> I have two SQL calls that bring back 5 fields:
>
>  SELECT company_profile_id ,  reference_id,  reference_source   FROM   
> company_reference_idlimit 1  ;
>
> ++--+--+
> | company_profile_id | reference_id | reference_source |
> ++--+--+
> |  2 | 331089191| EIN  |
> ++--+--+
>
>  SELECT company_profile_id, url 

Re: CLJS: experiencing "callback envy" re closures as DOM event handlers

2017-10-11 Thread hiskennyness


On Wednesday, October 11, 2017 at 1:23:36 PM UTC-4, James Reeves wrote:
>
> If you output your HTML as DOM nodes, rather than a string, you can just 
> attach the function directly to the attribute.
>

Aha! I have only ever mucked with innerHTML, I will have to look into this 
approach.

Meanwhile, I just did some more inspecting of the Reagent app in the 
browser and sure enough the only event listeners I see are on the document, 
and they call DispatchEvent. But your approach sounds a lot simpler.

Thx, kt

-- 
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: Does (into) ever combine 2 numbers into 1?

2017-10-11 Thread geraldo dev
(do
  (def a {:foo :bar})
  (def b {:another :value :foo :BAR})

  (merge-with (fn [x y]
(conj (if-not (vector? x)
[x]
x)
  y))
  a b))


If override the duplicate values merge could be used. Also one approach you 
can take is try to isolate your code that is impure (talks to database) , 
updates atom as much as possible. This way your experience with repl 
becomes more productive because you reduce the complexity of things that 
can go wrong. 

Regards,

Geraldo


On Wednesday, October 11, 2017 at 12:44:40 PM UTC-3, lawrence...@gmail.com 
wrote:
>
> I seem unable to figure out where I made a mistake, though this should be 
> simple.
>
> I have two SQL calls that bring back 5 fields:
>
>  SELECT company_profile_id ,  reference_id,  reference_source   FROM   
> company_reference_idlimit 1  ;
>
> ++--+--+
> | company_profile_id | reference_id | reference_source |
> ++--+--+
> |  2 | 331089191| EIN  |
> ++--+--+
>
>  SELECT company_profile_id, urlFROM company_website limit 
> 1   ;
>
> ++--+
> | company_profile_id | url  |
> ++--+
> |  2 | mikeshawauto.com |
> ++--+
>
> This brings back a total of 5 values. I need to have a document that has 5 
> values, though if values have the same field-name, then I want to 
> consolidate them into one vector. There are 4 unique field names, so I 
> expect to end up with 4 vectors, holding 5 values. Instead, I get this: 
>
> ({:company_profile_id ["2"], :topic :company, 
> :how-many-rows-and-fields-from-database 13, :url ["mikeshawauto.com"], 
> :reference_id ["331089191"], :reference_source ["ein"]})
>
> I expect: 
>
> {:company_profile_id ["2" "2"]
>
> but I get: 
>
> {:company_profile_id ["2"]
>
> The documents are combined in a map in an atom, with this function: 
>
>
> (def documents (atom {}))
>
>
> (defn update-documents
>   [denormalized-id field-name field-value 
> how-many-rows-and-fields-from-database topic]
>   {:pre [
>  (not (nil? denormalized-id))
>  (not (nil? field-name))
>  (vector? field-value)
>  ]}
>   (swap! documents
>  (fn [old-documents]
>(slingshot/try+
> (let [
>   document (get old-documents denormalized-id {})
>   old-field-value (get old-documents field-name [])
>   new-field-value (into old-field-value field-value)
>   document (assoc document field-name new-field-value)
>
>   previous-how-many-rows-and-fields-from-database (get 
> document :how-many-rows-and-fields-from-database 0)
>   new-how-many-rows-and-fields-from-database (+ 
> previous-how-many-rows-and-fields-from-database 
> how-many-rows-and-fields-from-database)
>   document (assoc document :topic topic)
>   document (assoc document 
> :how-many-rows-and-fields-from-database 
> new-how-many-rows-and-fields-from-database)
>   new-documents (assoc old-documents denormalized-id 
> document)
>   ]
>   new-documents)
> (catch Object o
>   (errors/log o) 
>   (slingshot/throw+ {
>  :type ::update-documents
>  :error o
>  }
> ))
>
> Can I assume that this always gives me 2 values in a vector? 
>
>   old-field-value (get old-documents field-name [])
>   new-field-value (into old-field-value field-value)
>   document (assoc document field-name new-field-value)
>
> I'm going to guess that the bug is somewhere else in my code. But if 
> anyone sees a flaw in this function, I'd be grateful if you could point it 
> out to me. 
>
>
>
>

-- 
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: CLJS: experiencing "callback envy" re closures as DOM event handlers

2017-10-11 Thread hiskennyness


On Wednesday, October 11, 2017 at 1:23:36 PM UTC-4, James Reeves wrote:
>
> If you output your HTML as DOM nodes, rather than a string, you can just 
> attach the function directly to the attribute.
>

It just occurred to me that one advantage of the string approach is that 
the initial page load is simply of one big wodge of HTML. I am no expert on 
this stuff, but somewhere I saw a mention that this was optimal.

If I build individual DOM nodes so I can attach listeners, I then also have 
to assemble them into the final structure. 

Is that right? Will that be slower? 

Thx!

 

>
> On 11 October 2017 at 18:20, hiskennyness 
> > wrote:
>
>> I am cobbling together my own little CLJS web framework and it is going 
>> well but I am stumped by one bit of interop: supporting event handlers that 
>> close over lexical variables. It seems to be a piece of cake for, inter 
>> alia, Reagent. Here is an excerpt from the "simple" example, hacked a bit 
>> (the "xxx" bits) to make sure I was seeing what I was seeing:
>>
>> (defn color-input []
>>   (let [xxx (atom 0)]
>> [:div.color-input
>>  "Time color: "
>>  [:input {:type  "text"
>>   :value @time-color
>>   :on-change #(do (reset! xxx (rand-int 32767))
>>   (println :xnow @xxx)
>>   (reset! time-color (-> % .-target 
>> .-value)))}]]))
>>
>>
>> My approach is to convert the anonymous function to  a string via STR and 
>> specify it in the generate HTML as the handler. Just to see my html I have 
>> a little test code:
>>
>> (let [xxx (atom 42)]
>>   (println :htm!!! (tag/to-html [(h1 {:onclick (on-evt #(swap! xxx inc))} 
>> "Help!")])))
>>
>>
>> Here is `on-evt`:
>>
>> (defn on-evt [cbfn]
>>   (cl-format nil
>> "(~a)(event)"
>> (str cbfn)))
>>
>>
>> Here is what I see in the console:
>> :htm!!! > id='0'>Help!
>>
>> But JS understandably does not see the  "xxx_12780".
>>
>> I have tried more than once digging into the reagent code to see how it 
>> is working its magic but always run into a dead end. 
>>
>> The one thing I do see when I inspect the DOM in the Chrome debugger is 
>> that the handler is not there on the target element, just a react-id or 
>> some such. This makes me think that the anonymous function itself (happily 
>> compiled into JS closed over the lexical variable) is being stashed in a 
>> dictionary under the react-id and that a handler at the document level is 
>> navigating from the event target to the closure via the react-id.
>>
>> That's just crazy enough to work. :) But am I just missing some simple 
>> CLJS interop capability? Any other ideas? 
>>
>>
>>
>>
>>
>>
>>
>> -- 
>> 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.
>>
>
>
>
> -- 
> James Reeves
> booleanknot.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.


Re: Is the Learning Guide in Order?

2017-10-11 Thread TP
As a first step I would recommend this tutorial: 
https://aphyr.com/posts/301-clojure-from-the-ground-up-welcome (unless 
you are ready to buy a book).



2017-10-11 16:01 keltezéssel, Mark Nutter írta:

See also https://www.braveclojure.com/.

On Tue, Oct 10, 2017 at 9:11 PM, Tomiwa Ademidun 
mailto:tomiademi...@gmail.com>> wrote:


Hey guys,

I Finally started learning Lisp/Clojure thanks to inspiration from
the great Paul Graham's essays
. First, I wanted to say I
appreciate your work in putting together the tutorial and
clojure-docs website, its very helpful and I really appreciate all
your efforts.

After working through the introduction
, I'm
about to start the language guide
. I
was just wondering if there is a recommended order in which to
work through the guide (or should I do a tutorial and then use the
guide as a reference?). I'm assuming I should start with
functions, if so, what comes after that as I am a bit overwhelmed
by all the things I don't know :)


Thanks,
Tomiwa
-- 
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.


possibly a Clojure question or possibly an AWS question: slow writes to durable-queue

2017-10-11 Thread lawrence . krubner
I can't figure out if this is a Clojure question or an AWS question. And if 
it is a Clojure question, I can't figure out if it is more of a general JVM 
question, or if it is specific to some library such as durable-queue. I can 
redirect my question elsewhere, if people think this is an AWS question. 

In my project.clj, I try to give my app a lot of memory:

  :jvm-opts ["-Xms7g" "-Xmx7g" "-XX:-UseCompressedOops"])

And the app starts off pulling data from MySQL and writing it to 
Durable-Queue at a rapid rate. ( https://github.com/Factual/durable-queue )

I have some logging set up to report every 30 seconds.

:enqueued 370137,

30 seconds later:

:enqueued 608967,

30 seconds later: 

:enqueued 828950,

It's a dramatic slowdown. The app is initially writing to the queue at 
faster than 10,000 documents a second, but it slows steadily, and after 10 
minutes it writes less than 1,000 documents per second. Since I have to 
write a few million documents, 10,000 a second is the slowest speed I can 
live with. 

The queues are in the /tmp folder of an AWS instance that has plenty of 
disk space, 4 CPUs, and 16 gigs of RAM. 

Why does the app slow down so much? I had 4 thoughts:

1.) the app struggles as it hits a memory limit

2.) memory bandwidth is the problem

3.) AWS is enforcing some weird IOPS limit

4.) durable-queue is misbehaving

As to possibility #1, I notice the app starts like this:

Memory in use (percentage/used/max-heap): (\"66%\" \"2373M\" \"3568M\")

but 60 seconds later I see: 

Memory in use (percentage/used/max-heap): (\"94%\" \"3613M\" \"3819M\")

So I've run out of allowed memory. But why is that? I thought I gave this 
app 7 gigs: 

  :jvm-opts ["-Xms7g" "-Xmx7g" "-XX:-UseCompressedOops"])

As to possibility #2, I found this old post on the Clojure mailist:

Andy Fingerhut wrote, "one thing I've found in the past on a 2-core machine 
that was achieving much less than 2x speedup was memory bandwidth being the 
limiting factor."

https://groups.google.com/forum/#!searchin/clojure/xmx$20xms$20maximum%7Csort:relevance/clojure/48W2eff3caU/HS6u547gtrAJ

But I am not sure how to test this. 

As to possibility #3, I'm not sure how AWS enforces its IOPS limits. If 
people think this is the most likely possibility, then I will repost my 
question in an AWS forum. 

As to possibility #4, durable-queue is well-tested and used in a lot of 
projects, and Zach Tellman is smart and makes few mistakes, so I'm doubtful 
that it is to blame, but I do notice that it starts off with 4 active slabs 
and then after 120 seconds, it is only using 1 slab. Is that expected? If 
people think this is the possible problem then I'll ask somewhere specific 
to durable-queue

Overall, my log information looks like this: 

("\nStats about from-mysql-to-tables-queue: " {"message" {:num-slabs 3, 
:num-active-slabs 2, :enqueued 370137, :retried 0, :completed 369934, 
:in-progress 10}})

("\nResource usage: " "Memory in use (percentage/used/max-heap): 
(\"66%\" \"2373M\" \"3568M\")\n\nCPU usage (how-many-cpu's/load-average): 
 [4 5.05]\n\nFree memory in jvm: [1171310752]")

30 seconds later

("\nStats about from-mysql-to-tables-queue: " {"message" {:num-slabs 4, 
:num-active-slabs 4, :enqueued 608967, :retried 0, :completed 608511, 
:in-progress 10}})

("\nResource usage: " "Memory in use (percentage/used/max-heap): 
(\"76%\" \"2752M\" \"3611M\")\n\nCPU usage (how-many-cpu's/load-average): 
 [4 5.87]\n\nFree memory in jvm: [901122456]")

30 seconds later

("\nStats about from-mysql-to-tables-queue: " {"message" {:num-slabs 4, 
:num-active-slabs 3, :enqueued 828950, :retried 0, :completed 828470, 
:in-progress 10}})

("\nResource usage: " "Memory in use (percentage/used/max-heap): 
(\"94%\" \"3613M\" \"3819M\")\n\nCPU usage (how-many-cpu's/load-average): 
 [4 6.5]\n\nFree memory in jvm: [216459664]")

30 seconds later

("\nStats about from-mysql-to-tables-queue: " {"message" {:num-slabs 1, 
:num-active-slabs 1, :enqueued 1051974, :retried 0, :completed 1051974, 
:in-progress 0}})


-- 
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: possibly a Clojure question or possibly an AWS question: slow writes to durable-queue

2017-10-11 Thread Justin Smith
a small thing here, if memory usage is important you should be building and
running an uberjar instead of using lein on the server (this also has other
benefits), and if you are doing that your project.clj jvm-opts are not
used, you have to configure your java command line in aws instead

On Wed, Oct 11, 2017 at 3:52 PM  wrote:

> I can't figure out if this is a Clojure question or an AWS question. And
> if it is a Clojure question, I can't figure out if it is more of a general
> JVM question, or if it is specific to some library such as durable-queue. I
> can redirect my question elsewhere, if people think this is an AWS
> question.
>
> In my project.clj, I try to give my app a lot of memory:
>
>   :jvm-opts ["-Xms7g" "-Xmx7g" "-XX:-UseCompressedOops"])
>
> And the app starts off pulling data from MySQL and writing it to
> Durable-Queue at a rapid rate. ( https://github.com/Factual/durable-queue
> )
>
> I have some logging set up to report every 30 seconds.
>
> :enqueued 370137,
>
> 30 seconds later:
>
> :enqueued 608967,
>
> 30 seconds later:
>
> :enqueued 828950,
>
> It's a dramatic slowdown. The app is initially writing to the queue at
> faster than 10,000 documents a second, but it slows steadily, and after 10
> minutes it writes less than 1,000 documents per second. Since I have to
> write a few million documents, 10,000 a second is the slowest speed I can
> live with.
>
> The queues are in the /tmp folder of an AWS instance that has plenty of
> disk space, 4 CPUs, and 16 gigs of RAM.
>
> Why does the app slow down so much? I had 4 thoughts:
>
> 1.) the app struggles as it hits a memory limit
>
> 2.) memory bandwidth is the problem
>
> 3.) AWS is enforcing some weird IOPS limit
>
> 4.) durable-queue is misbehaving
>
> As to possibility #1, I notice the app starts like this:
>
> Memory in use (percentage/used/max-heap): (\"66%\" \"2373M\" \"3568M\")
>
> but 60 seconds later I see:
>
> Memory in use (percentage/used/max-heap): (\"94%\" \"3613M\" \"3819M\")
>
> So I've run out of allowed memory. But why is that? I thought I gave this
> app 7 gigs:
>
>   :jvm-opts ["-Xms7g" "-Xmx7g" "-XX:-UseCompressedOops"])
>
> As to possibility #2, I found this old post on the Clojure mailist:
>
> Andy Fingerhut wrote, "one thing I've found in the past on a 2-core
> machine that was achieving much less than 2x speedup was memory bandwidth
> being the limiting factor."
>
>
> https://groups.google.com/forum/#!searchin/clojure/xmx$20xms$20maximum%7Csort:relevance/clojure/48W2eff3caU/HS6u547gtrAJ
>
> But I am not sure how to test this.
>
> As to possibility #3, I'm not sure how AWS enforces its IOPS limits. If
> people think this is the most likely possibility, then I will repost my
> question in an AWS forum.
>
> As to possibility #4, durable-queue is well-tested and used in a lot of
> projects, and Zach Tellman is smart and makes few mistakes, so I'm doubtful
> that it is to blame, but I do notice that it starts off with 4 active slabs
> and then after 120 seconds, it is only using 1 slab. Is that expected? If
> people think this is the possible problem then I'll ask somewhere specific
> to durable-queue
>
> Overall, my log information looks like this:
>
> ("\nStats about from-mysql-to-tables-queue: " {"message" {:num-slabs
> 3, :num-active-slabs 2, :enqueued 370137, :retried 0, :completed 369934,
> :in-progress 10}})
>
> ("\nResource usage: " "Memory in use (percentage/used/max-heap):
> (\"66%\" \"2373M\" \"3568M\")\n\nCPU usage (how-many-cpu's/load-average):
>  [4 5.05]\n\nFree memory in jvm: [1171310752]")
>
> 30 seconds later
>
> ("\nStats about from-mysql-to-tables-queue: " {"message" {:num-slabs
> 4, :num-active-slabs 4, :enqueued 608967, :retried 0, :completed 608511,
> :in-progress 10}})
>
> ("\nResource usage: " "Memory in use (percentage/used/max-heap):
> (\"76%\" \"2752M\" \"3611M\")\n\nCPU usage (how-many-cpu's/load-average):
>  [4 5.87]\n\nFree memory in jvm: [901122456]")
>
> 30 seconds later
>
> ("\nStats about from-mysql-to-tables-queue: " {"message" {:num-slabs
> 4, :num-active-slabs 3, :enqueued 828950, :retried 0, :completed 828470,
> :in-progress 10}})
>
> ("\nResource usage: " "Memory in use (percentage/used/max-heap):
> (\"94%\" \"3613M\" \"3819M\")\n\nCPU usage (how-many-cpu's/load-average):
>  [4 6.5]\n\nFree memory in jvm: [216459664]")
>
> 30 seconds later
>
> ("\nStats about from-mysql-to-tables-queue: " {"message" {:num-slabs
> 1, :num-active-slabs 1, :enqueued 1051974, :retried 0, :completed 1051974,
> :in-progress 0}})
>
>
> --
> 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 recei

Re: How to add a java servlet into a clojure ring project

2017-10-11 Thread Matching Socks
war files are zip files, so you can unzip the war and see what's wrong with 
it.  If necessary, build the combined war file another way.  You might be 
able to do that by producing a war file with your web app only (which you 
know works) and then taking it apart with unzip, incorporating the other 
webapp according to its instructions, and zipping it back up again 
(including the MANIFEST stuff as the very first entries).

-- 
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: possibly a Clojure question or possibly an AWS question: slow writes to durable-queue

2017-10-11 Thread Daniel Compton
Without more information it's hard to tell, but this looks a like it could
be a garbage collection issue. Can you run your test again and add some
logging/monitoring to show each garbage collection? If my hunch is right,
you'll see garbage collections getting more and more frequent until they
take up nearly all the CPU time, preventing much forward progress writing
to the queue.

If it's AWS based throttling, then CloudWatch monitoring
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-volume-status.html#using_cloudwatch_ebs
might
show you some hints. You could also test with an NVMe drive attached, just
to see if disk bandwidth is the issue.

On Thu, Oct 12, 2017 at 11:58 AM Justin Smith  wrote:

> a small thing here, if memory usage is important you should be building
> and running an uberjar instead of using lein on the server (this also has
> other benefits), and if you are doing that your project.clj jvm-opts are
> not used, you have to configure your java command line in aws instead
>
> On Wed, Oct 11, 2017 at 3:52 PM  wrote:
>
>> I can't figure out if this is a Clojure question or an AWS question. And
>> if it is a Clojure question, I can't figure out if it is more of a general
>> JVM question, or if it is specific to some library such as durable-queue. I
>> can redirect my question elsewhere, if people think this is an AWS
>> question.
>>
>> In my project.clj, I try to give my app a lot of memory:
>>
>>   :jvm-opts ["-Xms7g" "-Xmx7g" "-XX:-UseCompressedOops"])
>>
>> And the app starts off pulling data from MySQL and writing it to
>> Durable-Queue at a rapid rate. ( https://github.com/Factual/durable-queue
>> )
>>
>> I have some logging set up to report every 30 seconds.
>>
>> :enqueued 370137,
>>
>> 30 seconds later:
>>
>> :enqueued 608967,
>>
>> 30 seconds later:
>>
>> :enqueued 828950,
>>
>> It's a dramatic slowdown. The app is initially writing to the queue at
>> faster than 10,000 documents a second, but it slows steadily, and after 10
>> minutes it writes less than 1,000 documents per second. Since I have to
>> write a few million documents, 10,000 a second is the slowest speed I can
>> live with.
>>
>> The queues are in the /tmp folder of an AWS instance that has plenty of
>> disk space, 4 CPUs, and 16 gigs of RAM.
>>
>> Why does the app slow down so much? I had 4 thoughts:
>>
>> 1.) the app struggles as it hits a memory limit
>>
>> 2.) memory bandwidth is the problem
>>
>> 3.) AWS is enforcing some weird IOPS limit
>>
>> 4.) durable-queue is misbehaving
>>
>> As to possibility #1, I notice the app starts like this:
>>
>> Memory in use (percentage/used/max-heap): (\"66%\" \"2373M\" \"3568M\")
>>
>> but 60 seconds later I see:
>>
>> Memory in use (percentage/used/max-heap): (\"94%\" \"3613M\" \"3819M\")
>>
>> So I've run out of allowed memory. But why is that? I thought I gave this
>> app 7 gigs:
>>
>>   :jvm-opts ["-Xms7g" "-Xmx7g" "-XX:-UseCompressedOops"])
>>
>> As to possibility #2, I found this old post on the Clojure mailist:
>>
>> Andy Fingerhut wrote, "one thing I've found in the past on a 2-core
>> machine that was achieving much less than 2x speedup was memory bandwidth
>> being the limiting factor."
>>
>>
>> https://groups.google.com/forum/#!searchin/clojure/xmx$20xms$20maximum%7Csort:relevance/clojure/48W2eff3caU/HS6u547gtrAJ
>>
>> But I am not sure how to test this.
>>
>> As to possibility #3, I'm not sure how AWS enforces its IOPS limits. If
>> people think this is the most likely possibility, then I will repost my
>> question in an AWS forum.
>>
>> As to possibility #4, durable-queue is well-tested and used in a lot of
>> projects, and Zach Tellman is smart and makes few mistakes, so I'm doubtful
>> that it is to blame, but I do notice that it starts off with 4 active slabs
>> and then after 120 seconds, it is only using 1 slab. Is that expected? If
>> people think this is the possible problem then I'll ask somewhere specific
>> to durable-queue
>>
>> Overall, my log information looks like this:
>>
>> ("\nStats about from-mysql-to-tables-queue: " {"message" {:num-slabs
>> 3, :num-active-slabs 2, :enqueued 370137, :retried 0, :completed 369934,
>> :in-progress 10}})
>>
>> ("\nResource usage: " "Memory in use (percentage/used/max-heap):
>> (\"66%\" \"2373M\" \"3568M\")\n\nCPU usage (how-many-cpu's/load-average):
>>  [4 5.05]\n\nFree memory in jvm: [1171310752]")
>>
>> 30 seconds later
>>
>> ("\nStats about from-mysql-to-tables-queue: " {"message" {:num-slabs
>> 4, :num-active-slabs 4, :enqueued 608967, :retried 0, :completed 608511,
>> :in-progress 10}})
>>
>> ("\nResource usage: " "Memory in use (percentage/used/max-heap):
>> (\"76%\" \"2752M\" \"3611M\")\n\nCPU usage (how-many-cpu's/load-average):
>>  [4 5.87]\n\nFree memory in jvm: [901122456]")
>>
>> 30 seconds later
>>
>> ("\nStats about from-mysql-to-tables-queue: " {"message" {:num-slabs
>> 4, :num-active-slabs 3, :enqueued 828950, :retried 0, :completed 828470,
>> :in-progress 10}})
>>
>>

[ANN] Reactive with ClojureScript Recipes (book)

2017-10-11 Thread Nicolas Modrzyk
Good morning All,

>From the other side of the planet, Apress just published a recipe book on 
ClojureScript with React/Reagent. 

It should quite a fun and easy read for most of the people on this list, so 
please have a look:
http://www.apress.com/jp/book/9781484230084

This being a book on Clojure, I really had a blast writing it. Hopefully, 
it will spark new ideas and makes readers try out many new things.
For beginners, it should also be quite coherent and easy to pick up.

Feedback very welcome.

Nicolas,

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


SourceDebugExtension Class Attribute in clojure-1.8.0.jar

2017-10-11 Thread Nick Mudge
Recently I needed to run pack200 on the clojure-1.8.0.jar

When I did this I got an error that SourceDebugExtension is an unknown 
class attribute.

I got around this problem by removing all the SourceDebugExtension class 
attributes from clojure-1.8.0.jar.

Here are my questions:

What is clojure using SourceDebugExtension for?   What are the possible 
consequences or downsides from removing all the SourceDebugExtension class 
attributes from clojure-1.8.0.jar?


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