Re: Example in Joy of Clojure, 2nd edition (MEAP)

2014-02-16 Thread gianluca torta
as a side note, since we are within the backquote, simply using r (instead 
of ~'r) would not work since it would incorrectly expand to the fully 
qualified symbol, e.g. user/r

Gianluca

On Saturday, February 15, 2014 5:49:57 PM UTC+1, Jan Herich wrote:

 Hello Eric,

 You can rewrite this functionality with key# and r# instead of ~'key and 
 ~'r and it would work just as well, 
 it's only not necessary to use unique symbols here, because you are not 
 using them in the function body
 anyway, so there is no danger of accidental var capture. 

 To be honest, i would rather use underscore symbols (written as ~'_ inside 
 macro definition) to indicate 
 that i won't use any of the first two parameters in the function body. 

 Dňa sobota, 15. februára 2014 9:32:48 UTC+1 Eric napísal(-a):

 Hi,

 I'm reading the second edition of Joy of Clojure (the MEAP), and there is 
 an example that I don't quite get, and I was hoping someone here could help 
 me. It's in chapter 8, talking about macros. There is an example of a macro 
 called def-watched, which prints a message each time the root binding of a 
 var changes:

 (defmacro def-watched [name  value]
   `(do
 (def ~name ~@value)
 (add-watch (var ~name)
 :re-bind
 (fn [~'key ~'r old# new#]
   (println old#  -  new#)

 I understand almost everything, but I don't see why we have to use ~'keyand 
 ~'r rather than simply key# and r#. As I understand it, the first option 
 (~'var-name) would be useful to capture an external var inside the 
 macro, but I don't see the point of doing it here, especially since ~'keyis 
 defined in the parameter list, so that it would anyway hide any external 
 var. Could someone please help me understand this?

 Thank you in advance,

 Eric



-- 
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/groups/opt_out.


Re: use/require/import and quoted form

2014-02-16 Thread Andy Smith

(require 'clojure.string)

Im just wondering why the language chose to use the quote form, rather than 
a string or a keyword e.g.


(require clojure.string)

(require :clojure.string)

There obviously must be a good reason why. 

-- 
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/groups/opt_out.


Re: NetBeans?

2014-02-16 Thread Rui Carmo
In case anyone's interested, I've picked up Geertjan's stuff and started a 
repo at https://github.com/rcarmo/netbeans-clojure, since it's minimally 
usable already.

There's a tentative roadmap there as well -- feel free to ping me directly 
if you want commit access.

Regards,

R.

On Friday, February 14, 2014 11:49:09 AM UTC, Rui Carmo wrote:

 Hi there,

 I've been using LightTable daily (and vim) for my Clojure stuff, but I'm 
 now finding myself having to use NetBeans in order to better manage a 
 number of existing Java-related sub-projects.

 It's not a matter of language choice, but of environment uniformity (I 
 need to use the same tools as other folk).

 So I would love to have modern, working Clojure support in NetBeans.

 I've tracked down Enclojure (which is deprecated) and came across 
 Geertjan's blog entry here:

 https://blogs.oracle.com/geertjan/entry/leiningen_clojure_and_netbeans_ide

 ...but that is still a work in progress, and even though I've checked out 
 his SVN, it still requires time to figure out how to build the plugin.

 Since there's a GSOC coming up, has anyone suggested putting this up as a 
 project idea? 

 I find it somewhat sad that NetBeans has great Scala support and 
 effectively zero Clojure support, and think there should be a 
 community-wide effort to even the balance.

 Regards,

 R.


-- 
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/groups/opt_out.


Re: fast parallel reduction into hash-set/map

2014-02-16 Thread Jules
Thanks, Mikera

You are right about merge:

user= (def m1 (apply hash-map (range 1000)))
#'user/m1
user= (def m2 (apply hash-map (range 500 1500)))
#'user/m2
user= (time (def m3 (merge m1 m2)))
Elapsed time: 5432.184582 msecs
#'user/m3
user= (time (def m4 (clojure.lang.PersistentHashMap/splice m1 m2)))
Elapsed time: 1064.268269 msecs
#'user/m4
user= (= m3 m4)
true
user= 

as you would expect, a splice is faster and causes less of a memory spike.


Jules


On Sunday, 16 February 2014 10:01:04 UTC, Mikera wrote:

 +1 for this approach - I've wanted something like this several times.

 It's only an optimisation, but it's a very useful one. Same technique 
 can probably be used to accelerate merge significantly  which is a pretty 
 common operation when you are building map-like structures.

 On Sunday, 16 February 2014 07:06:24 UTC+8, Jules wrote:

 Guys,

 I've been playing with reducers on and off for a while but have been 
 frustrated because they don't seem to fit a particular usecase that I have 
 in mind... specifically: getting as many associations into a hash-map as as 
 I can in as short a time as possible.

 My understanding of the reason for this is that reducers practice a 
 divide and conquer strategy. The incoming sequence is divided up. Each 
 sub-sequence is reduced into a sub-result (possibly in parallel) and then 
 the sub-results are combined into the the final outgoing result.

 Unfortunately, there does not seem to be a better way of combining two 
 hash-maps other than to read each entry from one and create a new 
 corresponding association in the other. This means that each recombination 
 in the above process essentially repeats most of the work already performed 
 in the previous reduction stage.

 Hash-sets are implemented via hash-maps, and simpler with which to 
 demonstrate this problem:

 user= (def a (doall (range 1000)))
 #'user/a
 user= (def b (doall (range 500 1500)))
 #'user/b
 user= (time (def c (into #{} a)))
 Elapsed time: 6319.392669 msecs
 #'user/c
 user= (time (def d (into #{} b)))
 Elapsed time: 5389.805233 msecs
 #'user/d
 user= (time (def e (into c d)))
 Elapsed time: 8486.032191 msecs
 #'user/e


 In the example above, you can see that the reduction into hash-sets of 
 two overlapping lists of 10,000,000 elements takes 6.3 and 5.4 seconds. 
 This stage can be carried out in parallel i.e. time elapsed for this stage 
 would be 6.3 seconds - but we now have two hash-sets and we want one, so we 
 have to combine them.


 user= (time (def e (into c d)))
 Elapsed time: 8486.032191 msecs
 #'user/e

 As you can see, all the advantages of splitting the original sequence 
 into 2 and processing the two halves in parallel are lost since the 
 recombination or their results takes 8.5 seconds - more than we saved by 
 doing the reduction in parallel.

 So, what can we do about it ?

 I had a look at the code for PersistentHashMap (PersistentHashSet uses 
 PersistantHashMap internally). I realised that it was possible to splice 
 together the internal structure of two hash maps into a single one without 
 repeating most of the work required to build one from scratch. So, I had a 
 go at implementing it:


 user= (time (def f (clojure.lang.PersistentHashSet/splice c d)))
 Elapsed time: 3052.690911 msecs
 #'user/f

 and:

 user= (= e f)
 true

 Whilst this is still adding 3 seconds to our time, that 3 seconds is half 
 the time that we would have added had we executed the second reduction in 
 serial, rather than in parallel.

 This means that we can now reduce large datasets into sets/maps more 
 quickly in parallel than we can in serial :-) As an added benefit, because 
 splice reuses as much of the internal structure of both inputs as possible, 
 it's impact in terms of heap consumption and churn is less - although I 
 think that a full implementation might add some Java-side code complexity.

 If you would like to give 'splice' a try out, you will need to clone my 
 fork of clojure at github 

 https://github.com/JulesGosnell/clojure

 Please let me know if you try out the code. I would be interested to hear 
 if people think it is worth pursuing.

 I was also thinking that it should be possible to use a similar trick to 
 quickly and cheaply split a map/set into [roughly] equal sized pieces 
 (assuming an good hash distribution). This would enable the use of a 
 map/set as an input sequence into the parallel reduction process outlined 
 above. Currently, I believe that only a vector can be used in this way. It 
 would be harder to arrange that 'count' could be implemented efficiently on 
 these sub-maps/sets, but this is not important for the reduction process.

 BTW - benchmarks were run on a 3.2ghz Phenom II / clojure/master / 
 openjdk-1.7.0_51 / Fedora 20 with min and max 4gb ram.

 regards,



 Jules




-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to 

Re: fast parallel reduction into hash-set/map

2014-02-16 Thread Mikera
Wow - that's a pretty big win. I think we should try and get this into 
Clojure ASAP.

Are we too late for 1.6?

On Sunday, 16 February 2014 18:48:09 UTC+8, Jules wrote:

 Thanks, Mikera

 You are right about merge:

 user= (def m1 (apply hash-map (range 1000)))
 #'user/m1
 user= (def m2 (apply hash-map (range 500 1500)))
 #'user/m2
 user= (time (def m3 (merge m1 m2)))
 Elapsed time: 5432.184582 msecs
 #'user/m3
 user= (time (def m4 (clojure.lang.PersistentHashMap/splice m1 m2)))
 Elapsed time: 1064.268269 msecs
 #'user/m4
 user= (= m3 m4)
 true
 user= 

 as you would expect, a splice is faster and causes less of a memory spike.


 Jules


 On Sunday, 16 February 2014 10:01:04 UTC, Mikera wrote:

 +1 for this approach - I've wanted something like this several times.

 It's only an optimisation, but it's a very useful one. Same technique 
 can probably be used to accelerate merge significantly  which is a pretty 
 common operation when you are building map-like structures.

 On Sunday, 16 February 2014 07:06:24 UTC+8, Jules wrote:

 Guys,

 I've been playing with reducers on and off for a while but have been 
 frustrated because they don't seem to fit a particular usecase that I have 
 in mind... specifically: getting as many associations into a hash-map as as 
 I can in as short a time as possible.

 My understanding of the reason for this is that reducers practice a 
 divide and conquer strategy. The incoming sequence is divided up. Each 
 sub-sequence is reduced into a sub-result (possibly in parallel) and then 
 the sub-results are combined into the the final outgoing result.

 Unfortunately, there does not seem to be a better way of combining two 
 hash-maps other than to read each entry from one and create a new 
 corresponding association in the other. This means that each recombination 
 in the above process essentially repeats most of the work already performed 
 in the previous reduction stage.

 Hash-sets are implemented via hash-maps, and simpler with which to 
 demonstrate this problem:

 user= (def a (doall (range 1000)))
 #'user/a
 user= (def b (doall (range 500 1500)))
 #'user/b
 user= (time (def c (into #{} a)))
 Elapsed time: 6319.392669 msecs
 #'user/c
 user= (time (def d (into #{} b)))
 Elapsed time: 5389.805233 msecs
 #'user/d
 user= (time (def e (into c d)))
 Elapsed time: 8486.032191 msecs
 #'user/e


 In the example above, you can see that the reduction into hash-sets of 
 two overlapping lists of 10,000,000 elements takes 6.3 and 5.4 seconds. 
 This stage can be carried out in parallel i.e. time elapsed for this stage 
 would be 6.3 seconds - but we now have two hash-sets and we want one, so we 
 have to combine them.


 user= (time (def e (into c d)))
 Elapsed time: 8486.032191 msecs
 #'user/e

 As you can see, all the advantages of splitting the original sequence 
 into 2 and processing the two halves in parallel are lost since the 
 recombination or their results takes 8.5 seconds - more than we saved by 
 doing the reduction in parallel.

 So, what can we do about it ?

 I had a look at the code for PersistentHashMap (PersistentHashSet uses 
 PersistantHashMap internally). I realised that it was possible to splice 
 together the internal structure of two hash maps into a single one without 
 repeating most of the work required to build one from scratch. So, I had a 
 go at implementing it:


 user= (time (def f (clojure.lang.PersistentHashSet/splice c d)))
 Elapsed time: 3052.690911 msecs
 #'user/f

 and:

 user= (= e f)
 true

 Whilst this is still adding 3 seconds to our time, that 3 seconds is 
 half the time that we would have added had we executed the second reduction 
 in serial, rather than in parallel.

 This means that we can now reduce large datasets into sets/maps more 
 quickly in parallel than we can in serial :-) As an added benefit, because 
 splice reuses as much of the internal structure of both inputs as possible, 
 it's impact in terms of heap consumption and churn is less - although I 
 think that a full implementation might add some Java-side code complexity.

 If you would like to give 'splice' a try out, you will need to clone my 
 fork of clojure at github 

 https://github.com/JulesGosnell/clojure

 Please let me know if you try out the code. I would be interested to 
 hear if people think it is worth pursuing.

 I was also thinking that it should be possible to use a similar trick to 
 quickly and cheaply split a map/set into [roughly] equal sized pieces 
 (assuming an good hash distribution). This would enable the use of a 
 map/set as an input sequence into the parallel reduction process outlined 
 above. Currently, I believe that only a vector can be used in this way. It 
 would be harder to arrange that 'count' could be implemented efficiently on 
 these sub-maps/sets, but this is not important for the reduction process.

 BTW - benchmarks were run on a 3.2ghz Phenom II / clojure/master / 
 openjdk-1.7.0_51 / Fedora 20 with 

Re: fast parallel reduction into hash-set/map

2014-02-16 Thread Jules
I would have thought so - it's only my first cut - seems to work but I 
wouldn't like to stake my life on it. It really needs a developer who is 
familiar with PersistentHashMap to look it over and give it the thumbs 
up...Still, I guess if it was marked experimental ...:-)

Jules


On Sunday, 16 February 2014 10:49:38 UTC, Mikera wrote:

 Wow - that's a pretty big win. I think we should try and get this into 
 Clojure ASAP.

 Are we too late for 1.6?

 On Sunday, 16 February 2014 18:48:09 UTC+8, Jules wrote:

 Thanks, Mikera

 You are right about merge:

 user= (def m1 (apply hash-map (range 1000)))
 #'user/m1
 user= (def m2 (apply hash-map (range 500 1500)))
 #'user/m2
 user= (time (def m3 (merge m1 m2)))
 Elapsed time: 5432.184582 msecs
 #'user/m3
 user= (time (def m4 (clojure.lang.PersistentHashMap/splice m1 m2)))
 Elapsed time: 1064.268269 msecs
 #'user/m4
 user= (= m3 m4)
 true
 user= 

 as you would expect, a splice is faster and causes less of a memory spike.


 Jules


 On Sunday, 16 February 2014 10:01:04 UTC, Mikera wrote:

 +1 for this approach - I've wanted something like this several times.

 It's only an optimisation, but it's a very useful one. Same technique 
 can probably be used to accelerate merge significantly  which is a pretty 
 common operation when you are building map-like structures.

 On Sunday, 16 February 2014 07:06:24 UTC+8, Jules wrote:

 Guys,

 I've been playing with reducers on and off for a while but have been 
 frustrated because they don't seem to fit a particular usecase that I have 
 in mind... specifically: getting as many associations into a hash-map as 
 as 
 I can in as short a time as possible.

 My understanding of the reason for this is that reducers practice a 
 divide and conquer strategy. The incoming sequence is divided up. Each 
 sub-sequence is reduced into a sub-result (possibly in parallel) and then 
 the sub-results are combined into the the final outgoing result.

 Unfortunately, there does not seem to be a better way of combining two 
 hash-maps other than to read each entry from one and create a new 
 corresponding association in the other. This means that each recombination 
 in the above process essentially repeats most of the work already 
 performed 
 in the previous reduction stage.

 Hash-sets are implemented via hash-maps, and simpler with which to 
 demonstrate this problem:

 user= (def a (doall (range 1000)))
 #'user/a
 user= (def b (doall (range 500 1500)))
 #'user/b
 user= (time (def c (into #{} a)))
 Elapsed time: 6319.392669 msecs
 #'user/c
 user= (time (def d (into #{} b)))
 Elapsed time: 5389.805233 msecs
 #'user/d
 user= (time (def e (into c d)))
 Elapsed time: 8486.032191 msecs
 #'user/e


 In the example above, you can see that the reduction into hash-sets of 
 two overlapping lists of 10,000,000 elements takes 6.3 and 5.4 seconds. 
 This stage can be carried out in parallel i.e. time elapsed for this stage 
 would be 6.3 seconds - but we now have two hash-sets and we want one, so 
 we 
 have to combine them.


 user= (time (def e (into c d)))
 Elapsed time: 8486.032191 msecs
 #'user/e

 As you can see, all the advantages of splitting the original sequence 
 into 2 and processing the two halves in parallel are lost since the 
 recombination or their results takes 8.5 seconds - more than we saved by 
 doing the reduction in parallel.

 So, what can we do about it ?

 I had a look at the code for PersistentHashMap (PersistentHashSet uses 
 PersistantHashMap internally). I realised that it was possible to splice 
 together the internal structure of two hash maps into a single one without 
 repeating most of the work required to build one from scratch. So, I had a 
 go at implementing it:


 user= (time (def f (clojure.lang.PersistentHashSet/splice c d)))
 Elapsed time: 3052.690911 msecs
 #'user/f

 and:

 user= (= e f)
 true

 Whilst this is still adding 3 seconds to our time, that 3 seconds is 
 half the time that we would have added had we executed the second 
 reduction 
 in serial, rather than in parallel.

 This means that we can now reduce large datasets into sets/maps more 
 quickly in parallel than we can in serial :-) As an added benefit, because 
 splice reuses as much of the internal structure of both inputs as 
 possible, 
 it's impact in terms of heap consumption and churn is less - although I 
 think that a full implementation might add some Java-side code complexity.

 If you would like to give 'splice' a try out, you will need to clone my 
 fork of clojure at github 

 https://github.com/JulesGosnell/clojure

 Please let me know if you try out the code. I would be interested to 
 hear if people think it is worth pursuing.

 I was also thinking that it should be possible to use a similar trick 
 to quickly and cheaply split a map/set into [roughly] equal sized pieces 
 (assuming an good hash distribution). This would enable the use of a 
 map/set as an input sequence into the parallel 

Re: fast parallel reduction into hash-set/map

2014-02-16 Thread Jules
Thinking about it a bit more, it would be good to have an interface e.g. 
Spliceable which e.g. 'into' could take advantage of when it found itself 
concatenating two seq of the same implementation...

Further digging might demonstrate that a similar trick could be used with 
other seq types ?

Splice currently only supports 2 params - splice(left, right). If you could 
splice(lhs, rhses...) then I think it could be used more efficiently in a 
reducers combination phase... I would like to be able to recombine the 
subresults of multiple cores in a single iteration.

Finally, I would also be keen to investigate my idea about the efficient 
'cleave'-ing of tree-based seqs so that they can be used as inputs to the 
reducers library, as mentioned in my original post...


Jules


On Sunday, 16 February 2014 10:57:35 UTC, Jules wrote:

 I would have thought so - it's only my first cut - seems to work but I 
 wouldn't like to stake my life on it. It really needs a developer who is 
 familiar with PersistentHashMap to look it over and give it the thumbs 
 up...Still, I guess if it was marked experimental ...:-)

 Jules


 On Sunday, 16 February 2014 10:49:38 UTC, Mikera wrote:

 Wow - that's a pretty big win. I think we should try and get this into 
 Clojure ASAP.

 Are we too late for 1.6?

 On Sunday, 16 February 2014 18:48:09 UTC+8, Jules wrote:

 Thanks, Mikera

 You are right about merge:

 user= (def m1 (apply hash-map (range 1000)))
 #'user/m1
 user= (def m2 (apply hash-map (range 500 1500)))
 #'user/m2
 user= (time (def m3 (merge m1 m2)))
 Elapsed time: 5432.184582 msecs
 #'user/m3
 user= (time (def m4 (clojure.lang.PersistentHashMap/splice m1 m2)))
 Elapsed time: 1064.268269 msecs
 #'user/m4
 user= (= m3 m4)
 true
 user= 

 as you would expect, a splice is faster and causes less of a memory 
 spike.


 Jules


 On Sunday, 16 February 2014 10:01:04 UTC, Mikera wrote:

 +1 for this approach - I've wanted something like this several times.

 It's only an optimisation, but it's a very useful one. Same technique 
 can probably be used to accelerate merge significantly  which is a 
 pretty 
 common operation when you are building map-like structures.

 On Sunday, 16 February 2014 07:06:24 UTC+8, Jules wrote:

 Guys,

 I've been playing with reducers on and off for a while but have been 
 frustrated because they don't seem to fit a particular usecase that I 
 have 
 in mind... specifically: getting as many associations into a hash-map as 
 as 
 I can in as short a time as possible.

 My understanding of the reason for this is that reducers practice a 
 divide and conquer strategy. The incoming sequence is divided up. Each 
 sub-sequence is reduced into a sub-result (possibly in parallel) and then 
 the sub-results are combined into the the final outgoing result.

 Unfortunately, there does not seem to be a better way of combining two 
 hash-maps other than to read each entry from one and create a new 
 corresponding association in the other. This means that each 
 recombination 
 in the above process essentially repeats most of the work already 
 performed 
 in the previous reduction stage.

 Hash-sets are implemented via hash-maps, and simpler with which to 
 demonstrate this problem:

 user= (def a (doall (range 1000)))
 #'user/a
 user= (def b (doall (range 500 1500)))
 #'user/b
 user= (time (def c (into #{} a)))
 Elapsed time: 6319.392669 msecs
 #'user/c
 user= (time (def d (into #{} b)))
 Elapsed time: 5389.805233 msecs
 #'user/d
 user= (time (def e (into c d)))
 Elapsed time: 8486.032191 msecs
 #'user/e


 In the example above, you can see that the reduction into hash-sets of 
 two overlapping lists of 10,000,000 elements takes 6.3 and 5.4 seconds. 
 This stage can be carried out in parallel i.e. time elapsed for this 
 stage 
 would be 6.3 seconds - but we now have two hash-sets and we want one, so 
 we 
 have to combine them.


 user= (time (def e (into c d)))
 Elapsed time: 8486.032191 msecs
 #'user/e

 As you can see, all the advantages of splitting the original sequence 
 into 2 and processing the two halves in parallel are lost since the 
 recombination or their results takes 8.5 seconds - more than we saved by 
 doing the reduction in parallel.

 So, what can we do about it ?

 I had a look at the code for PersistentHashMap (PersistentHashSet uses 
 PersistantHashMap internally). I realised that it was possible to 
 splice 
 together the internal structure of two hash maps into a single one 
 without 
 repeating most of the work required to build one from scratch. So, I had 
 a 
 go at implementing it:


 user= (time (def f (clojure.lang.PersistentHashSet/splice c d)))
 Elapsed time: 3052.690911 msecs
 #'user/f

 and:

 user= (= e f)
 true

 Whilst this is still adding 3 seconds to our time, that 3 seconds is 
 half the time that we would have added had we executed the second 
 reduction 
 in serial, rather than in parallel.

 This means that we can now reduce large datasets 

Re: use/require/import and quoted form

2014-02-16 Thread James Reeves
Symbols are used in Clojure to represent identifiers, and in this case
we're identifying a namespace.

I believe it's also the case that a valid symbol is also a valid namespace
name.

- James


On 16 February 2014 10:39, Andy Smith the4thamig...@googlemail.com wrote:


 (require 'clojure.string)

 Im just wondering why the language chose to use the quote form, rather
 than a string or a keyword e.g.


 (require clojure.string)

 (require :clojure.string)

 There obviously must be a good reason why.

 --
 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/groups/opt_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/groups/opt_out.


Some advice about introducing clojurescript into a project using js/jquery

2014-02-16 Thread Kashyap CK
Hi,

It took me some time to get started with clojurescript (on windows/cygwin) 
- http://swannodette.github.io/2013/11/07/clojurescript-101/ worked for me.

I'd like to use clojurescript to do some UI component development for 
product which is built using webkit/js/jquery. I was wondering if it is 
okay to develop a feature in such an application, where most of the UI is 
in jquery, in clojurescript?

I'd appreciate it very much to know if there are any known gotha's here or 
any tips that I could use?  

Regards,
Kashyap

-- 
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/groups/opt_out.


Re: [ANN] lispy.el 0.8: jump to any Clojure tag in current directory screencast

2014-02-16 Thread Olli Piepponen
This looks very neat, but I was unable to figure out how to use 
lispy/clojure-semantic the way you were doing in your screencast. Could you 
give a breakdown of how this works?

On Saturday, February 15, 2014 4:46:48 AM UTC+7, Oleh wrote:

 Hi all,

 As a follow-up to this post - 
 https://groups.google.com/forum/#!topic/clojure/B7dTW5PDcPM,
 it's now possible to jump to any Clojure tag in current directory.
 No project definitions required: CEDET will parse every source file in 
 current directory.
 The tags are completed with helm plugin, so it's quite fast to find a 
 candidate to jump to.

 As a showcase, I've took this popular Clojure statistics package: 
 https://github.com/liebke/incanter

 The screencast is here: https://vimeo.com/86727658.

 lispy is here: https://github.com/abo-abo/lispy
 clojure-semantic is here: https://github.com/kototama/clojure-semantic

 There's currently a bug in clojure-semantic the prevents permanent storage 
 of parsed tags,
 maybe someone with some expertise could look into that. 
 Also, it's generated by a bison-like grammar, so if you know bison (I 
 don't unfortunately),
 you could extend clojure-semantic to distinguish stuff like defmacro, 
 defmulti, defmethod etc.

 Same functionality is also available for Emacs Lisp, Scheme and Common 
 Lisp, if you like using
 anything else besides Clojure:)

 regards,
 Oleh


-- 
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/groups/opt_out.


rseq for subvec in clojurescript

2014-02-16 Thread Sunil S Nandihalli
Hi Everybody,

I get the following error when I do a rseq on a subvec in clojurescript
Uncaught Error: No protocol method IReversible.-rseq defined for type
cljs.core/Subvec: [(:red :clockwise) (:blue :clockwise) (:yellow
:clockwise) (:yellow :clockwise) (:orange :clockwise)]

Is this a known problem?
Thanks, Sunil

-- 
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/groups/opt_out.


Re: [ANN] Clojure 1.6.0-beta1

2014-02-16 Thread Alex Walker
Part of Rich's objection to not-nil? variants could be that they are a 
double negative, not-(no value)?, which can decrease clarity and require 
more coffee.


- nil Means 'nothing/no-value'- represents Java null and tests logical 
false [clojure.org/reader]


To compete with some? variants, I'd suggest a positive that I found 
strangely available:

exists?
if-exists[?]
when-exists[?]

Or, more proper, though potentially more overloaded: value?, if-value[?], 
when-value[?].

On Sunday, February 16, 2014 12:54:12 AM UTC-6, Эльдар Габдуллин wrote:

 Like this, just

 not-nil?
 if-not-nil
 when-not-nil

 is much better for me.



 суббота, 15 февраля 2014 г., 7:12:21 UTC+4 пользователь Joel Holdbrooks 
 написал:

 As an addendum to my last comment, *not-nil?* would also be a good 
 candidate. That really doesn't leave room for doubt.

 This:
   
 (some? false) ;; = true 

 Would confuse me. On the other hand this:
   
 (not-nil? false) ;; = true 

 Would not.

 There's really no need to complicate the naming story here. It's also 
 easy to remember!

 On Friday, February 14, 2014 3:25:36 PM UTC-8, Alex Miller wrote:



 On Friday, February 14, 2014 2:27:49 PM UTC-6, DomKM wrote:

 Great changes! I have a question about #5.
  

 5) New some operations 
 Many conditional functions rely on logical truth (where falsey
 values are nil or false). Sometimes it is useful to have functions
 that rely on not nilness instead. These functions have been added to
 support these cases [CLJ-1343]:
 * some? - same as (not (nil? x))
 * if-some - like if-let, but checks (not (nil? test)) instead of test
 * when-some - like when-let, but checks (not (nil? test)) instead of 
 test


 It seems inconsistent to have some mean two very different things 
 within the same namespace, especially since the prior uses of some 
 (`some`, `some-fn`, etc.) are more in keeping with its primary definition 
 of having to do with amount (and operate on seqs or variadic arguments) 
 while the new functions have to do with existence (and operate on any 
 single value). Why not call these new functions `not-nil?`, `if-not-nil`, 
 and `when-not-nil`? Or, if not-nil is too unwieldy then what about 
 exists (`exists?`, `if-exists`, `when-exists`)?

 Are these names up for discussion?


 Hey Dom et al,

 The names of these functions were chosen by Rich. There was already some 
 name overloading of some even before these new functions with some 
 (truthy) and some-/some- (not nil). The new functions keep with the 
 latter meaning. Many other names were considered, including everything I've 
 seen someone mention (-not-nil, exists, nnil, etc). As far as I know these 
 names are final, however, I will relay all of the feedback I've seen here, 
 on #clojure, and on Twitter to Rich for consideration.

 Alex
  



-- 
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/groups/opt_out.


[ANN] typed-clojure-mode emacs plugin

2014-02-16 Thread Ambrose Bonnaire-Sergeant
Hi,

Happy to announce the first version of
typed-clojure-modehttps://github.com/typedclojure/typed-clojure-mode,
an emacs
minor mode for Typed Clojure.

Thanks to John Walker who wrote the core functionality, he earned this open
source 
bountyhttps://www.bountysource.com/issues/1406536-emacs-plugin-for-typed-clojurefor
his work.

I'll be maintaining typed-clojure-mode from here, please open an
issuehttps://github.com/typedclojure/typed-clojure-mode/issuesor get
in touch if something is broken or missing.

Thanks,
Ambrose

-- 
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/groups/opt_out.


Re: rseq for subvec in clojurescript

2014-02-16 Thread Michał Marczyk
It is now, thanks for the report!

Ticket with patch:

http://dev.clojure.org/jira/browse/CLJS-765


On 16 February 2014 17:48, Sunil S Nandihalli
sunil.nandiha...@gmail.com wrote:
 Hi Everybody,

 I get the following error when I do a rseq on a subvec in clojurescript
 Uncaught Error: No protocol method IReversible.-rseq defined for type
 cljs.core/Subvec: [(:red :clockwise) (:blue :clockwise) (:yellow :clockwise)
 (:yellow :clockwise) (:orange :clockwise)]

 Is this a known problem?
 Thanks, Sunil

 --
 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/groups/opt_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/groups/opt_out.


Re: java.jdbc 0.3.3 select query exception: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn

2014-02-16 Thread The Dude (Abides)
You're right :) When I isolated the issue thanks to some help it turns out 
java.jdbc is working fine but I wasn't getting the resultset output 
properly in the function. So got it resolved and working like this:

(defn get-member [id]
(let [id (parse-int id)
  member (first (jdbc/query db [SELECT id, username, firstname, 
lastname, email FROM members WHERE id = ? ORDER BY id ASC LIMIT 1 id]))]
(session/put! :member member)
(session/put! :next (+ id 1))
(layout/render member/profile2.html {:member member})))

So java.jdbc working just fine, able to get the results, set in session, 
etc. Thanks for all the feedback. 

On Saturday, February 15, 2014 9:55:16 PM UTC-8, edbond wrote:

 I spot invalid let here:

 (defn get-a-member [id]
 (let [id (parse-int id) member]
 [member (memberdb/get-member id)]

 should be 

 (defn get-a-member [id]
 (let [id (parse-int id)
   member (memberdb/get-member id)]


 On Sunday, February 16, 2014 4:01:03 AM UTC+2, The Dude (Abides) wrote:

 Thanks, here's the entire stack trace:

 java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to 
 clojure.lang.IFn
  members.clj:33 sikhpyar.routes.members/get-member
  members.clj:50 sikhpyar.routes.members/fn
 core.clj:94 compojure.core/make-route[fn]
 core.clj:40 compojure.core/if-route[fn]
 core.clj:25 compojure.core/if-method[fn]
core.clj:107 compojure.core/routing[fn]
   core.clj:2443 clojure.core/some
core.clj:107 compojure.core/routing
 RestFn.java:139 clojure.lang.RestFn.applyTo
core.clj:619 clojure.core/apply
core.clj:112 compojure.core/routes[fn]
core.clj:107 compojure.core/routing[fn]
   core.clj:2443 clojure.core/some
core.clj:107 compojure.core/routing
 RestFn.java:139 clojure.lang.RestFn.applyTo
core.clj:619 clojure.core/apply
core.clj:112 compojure.core/routes[fn]
   middleware.clj:17 
 sikhpyar.middleware/template-error-page[fn]
   middleware.clj:10 sikhpyar.middleware/log-request[fn]
   middleware.clj:44 
 noir.util.middleware/wrap-request-map[fn]
   keyword_params.clj:32 
 ring.middleware.keyword-params/wrap-keyword-params[fn]
nested_params.clj:70 
 ring.middleware.nested-params/wrap-nested-params[fn]
   params.clj:58 ring.middleware.params/wrap-params[fn]
   middleware.clj:12 hiccup.middleware/wrap-base-url[fn]
multipart_params.clj:107 
 ring.middleware.multipart-params/wrap-multipart-params[fn]
  validation.clj:153 
 noir.validation/wrap-noir-validation[fn]
  cookies.clj:72 noir.cookies/noir-cookies[fn]
 cookies.clj:171 
 ring.middleware.cookies/wrap-cookies[fn]
 session.clj:142 noir.session/noir-flash[fn]
flash.clj:31 ring.middleware.flash/wrap-flash[fn]
  session.clj:97 noir.session/noir-session[fn]
  session.clj:85 
 ring.middleware.session/wrap-session[fn]
Var.java:415 clojure.lang.Var.invoke
   reload.clj:18 ring.middleware.reload/wrap-reload[fn]
   stacktrace.clj:17 
 ring.middleware.stacktrace/wrap-stacktrace-log[fn]
   stacktrace.clj:80 
 ring.middleware.stacktrace/wrap-stacktrace-web[fn]
jetty.clj:18 ring.adapter.jetty/proxy-handler[fn]
(Unknown Source) 
 ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$0.handle
 HandlerWrapper.java:116 
 org.eclipse.jetty.server.handler.HandlerWrapper.handle
 Server.java:363 org.eclipse.jetty.server.Server.handle
 AbstractHttpConnection.java:483 
 org.eclipse.jetty.server.AbstractHttpConnection.handleRequest
 AbstractHttpConnection.java:920 
 org.eclipse.jetty.server.AbstractHttpConnection.headerComplete
 AbstractHttpConnection.java:982 
 org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete
 HttpParser.java:635 
 org.eclipse.jetty.http.HttpParser.parseNext
 HttpParser.java:235 
 org.eclipse.jetty.http.HttpParser.parseAvailable
 AsyncHttpConnection.java:82 
 org.eclipse.jetty.server.AsyncHttpConnection.handle
  SelectChannelEndPoint.java:628 
 org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle
   SelectChannelEndPoint.java:52 
 org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run
   QueuedThreadPool.java:608 
 org.eclipse.jetty.util.thread.QueuedThreadPool.runJob
   QueuedThreadPool.java:543 
 

ANN: ring-http-response, ring-Swagger, ring-swagger-ui compojure-api

2014-02-16 Thread Tommi Reiman
Hi all.

We here at Metosin have been developing and using a bunch of small 
utilities for Ring-based web api development. Here they are:

*1) ring-http-response *(https://github.com/metosin/ring-http-response)

Real http status codes for Ring - ported from Spray[1]. There is a response 
function for most of the http-statuses available (ok, found, not-found,...) 
taking either a body, url or nothing as a parameter. In addition, for all 
erroneous responses there is a exception throwing version with '!' in the 
end (bad-request!, not-found!,...). There is also a middleware for catching 
these response exceptions and returning the thrown http-response instead. 
Namespace *ring.util.http-response* can be used to replace the original 
*ring.util.response*.

Should be stable.

*2) ring-swagger* (https://github.com/metosin/ring-swagger)

We wanted there to be a standalone Swagger[2] implementation for Ring, not 
tied to the used routing library. There is already Swag[3] and 
Octohipster[4], but both have strong opinions about routing. Ring-Swagger 
is integrated with Prismatic Schema for data modeling  coercing (should it 
support other validation libs also?). Offers a simple map-based api for 
routing  other higher level web libs to publish their routes.

There is an adapter for Compojure on top of this, more later.

Would be fun to other routing/web libs adapt to this too (should be quite 
straightforward to collect routes from bidi for example)

Not yet feature complete. All feedback  Pull Requests welcome.

*3) ring-swagger-ui* (https://github.com/metosin/ring-swagger-ui)

Maven-packaged version of the Swagger-UI[5]. Follows the version numbers of 
the original npm packages (permission to publish as maven artifact from the 
Reverb guys, thanks guys!). Has some small changes in the ui. All stuff can 
be overridden locally (mainly the index page).

*4) compojure-api* (https://github.com/metosin/compojure-api)

Originally was supposed to be just compojure-swagger, but added other stuff 
to make life of an web api development easier. Everything can be used 
separately, but there is also a *compojure.api.sweet* package, which can be 
used as a single entry point to the library.

Basic Swagger-functionality works with vanilla Compojure but to enable all 
features (better way to setup route meta-data, schema-aware body 
destructuring, return schemas etc.), there is a extended api, with '*' in 
the name of the http-methods (GET*, POST*). Currently the extended api is 
also sitting on top of Compojure and internally overrides a compile-route 
function from *compojure.core* to enable easy way to add meta-data to 
routes. Thinking of re-implementing the new api directly on top of Clout 
instead of trying to sit on top of the (otherwise awesome) Compojure.

Currently work in progress. Acts also as a demo how to use  bind together 
the underlying more stable libs (ring-http-response, ring-swagger 
ring-swagger-ui).

*5) compojure-api-examples* (
https://github.com/metosin/compojure-api-examples)

A sample minimalistic project to see things in action and to start creating 
schema-aware documented web apis.

...

Hopefully some of the stuff is found useful, on both Github  Clojars. We 
are using (and developing) these anyway with our projects. Also waiting 
eagerly for the @PrismaticEng next web thingie coming out soon(?), whether 
these libs complement or overlap each other.

Would appreciate your comments and thoughts on the concepts or the code. 
Either here or via email: first-name (at) metosin.fi or ikitommi at 
freenode  twitter.

regards,

Tommi

--

[1] http://spray.io
[2] https://github.com/wordnik/swagger-core/wiki
[3] https://github.com/narkisr/swag
[4] https://github.com/myfreeweb/octohipster
[5] https://github.com/wordnik/swagger-ui

-- 
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/groups/opt_out.


Re: ANN: ring-http-response, ring-Swagger, ring-swagger-ui compojure-api

2014-02-16 Thread Gary Trakhman
I was inches away from reinventing something like this for our company's
codebase.  Maybe you saved us the trouble :-).

Will definitely check it out.


On Sun, Feb 16, 2014 at 3:20 PM, Tommi Reiman tommi.rei...@gmail.comwrote:

 Hi all.

 We here at Metosin have been developing and using a bunch of small
 utilities for Ring-based web api development. Here they are:

 *1) ring-http-response *(https://github.com/metosin/ring-http-response)

 Real http status codes for Ring - ported from Spray[1]. There is a
 response function for most of the http-statuses available (ok, found,
 not-found,...) taking either a body, url or nothing as a parameter. In
 addition, for all erroneous responses there is a exception throwing version
 with '!' in the end (bad-request!, not-found!,...). There is also a
 middleware for catching these response exceptions and returning the thrown
 http-response instead. Namespace *ring.util.http-response* can be used to
 replace the original *ring.util.response*.

 Should be stable.

 *2) ring-swagger* (https://github.com/metosin/ring-swagger)

 We wanted there to be a standalone Swagger[2] implementation for Ring, not
 tied to the used routing library. There is already Swag[3] and
 Octohipster[4], but both have strong opinions about routing. Ring-Swagger
 is integrated with Prismatic Schema for data modeling  coercing (should it
 support other validation libs also?). Offers a simple map-based api for
 routing  other higher level web libs to publish their routes.

 There is an adapter for Compojure on top of this, more later.

 Would be fun to other routing/web libs adapt to this too (should be quite
 straightforward to collect routes from bidi for example)

 Not yet feature complete. All feedback  Pull Requests welcome.

 *3) ring-swagger-ui* (https://github.com/metosin/ring-swagger-ui)

 Maven-packaged version of the Swagger-UI[5]. Follows the version numbers
 of the original npm packages (permission to publish as maven artifact from
 the Reverb guys, thanks guys!). Has some small changes in the ui. All stuff
 can be overridden locally (mainly the index page).

 *4) compojure-api* (https://github.com/metosin/compojure-api)

 Originally was supposed to be just compojure-swagger, but added other
 stuff to make life of an web api development easier. Everything can be used
 separately, but there is also a *compojure.api.sweet* package, which can
 be used as a single entry point to the library.

 Basic Swagger-functionality works with vanilla Compojure but to enable all
 features (better way to setup route meta-data, schema-aware body
 destructuring, return schemas etc.), there is a extended api, with '*' in
 the name of the http-methods (GET*, POST*). Currently the extended api is
 also sitting on top of Compojure and internally overrides a compile-route
 function from *compojure.core* to enable easy way to add meta-data to
 routes. Thinking of re-implementing the new api directly on top of Clout
 instead of trying to sit on top of the (otherwise awesome) Compojure.

 Currently work in progress. Acts also as a demo how to use  bind together
 the underlying more stable libs (ring-http-response, ring-swagger
 ring-swagger-ui).

 *5) compojure-api-examples* (
 https://github.com/metosin/compojure-api-examples)

 A sample minimalistic project to see things in action and to start
 creating schema-aware documented web apis.

 ...

 Hopefully some of the stuff is found useful, on both Github  Clojars. We
 are using (and developing) these anyway with our projects. Also waiting
 eagerly for the @PrismaticEng next web thingie coming out soon(?), whether
 these libs complement or overlap each other.

 Would appreciate your comments and thoughts on the concepts or the code.
 Either here or via email: first-name (at) metosin.fi or ikitommi at
 freenode  twitter.

 regards,

 Tommi

 --

 [1] http://spray.io
 [2] https://github.com/wordnik/swagger-core/wiki
 [3] https://github.com/narkisr/swag
 [4] https://github.com/myfreeweb/octohipster
 [5] https://github.com/wordnik/swagger-ui

  --
 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/groups/opt_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 

Re: (series of swap! on atom) == single swap!

2014-02-16 Thread t x
Hi John,

  Your solution is perfectly valid and optimal for the problem I
described above.


  Unfortunately, I forgot to mention an additional constraint: sometimes I do:

(let [ foo (:some-selector @data-atom) ]
  (swap! data-atom update-in [:other-selector] ... ))

which the - doesn't quite work on, but my ugly hack above does resolve.


  The problem being -- I want to update one part of the atom, but it
depends on another part of the atom.

  I ended up with the following hack:

(defn tswap! [atm func]
  (swap! atm
 (fn [old]
   (let [natm (atom old)]
 (func natm)
 @natm


On Sat, Feb 15, 2014 at 4:09 PM, John D. Hume duelin.mark...@gmail.com wrote:
 On Sat, Feb 15, 2014 at 6:04 PM, t x txrev...@gmail.com wrote:


 (defn what-I-want []
   (with-atom some-atom
 assoc-in ...
 assoc-in ...
 update-in ...))


 I often do something like this and don't find it too ugly:
 (swap! my-atom #(- %
   (assoc-in [:k] v)
   (update-in [:k2] inc)
   ,,,))

 --
 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/groups/opt_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/groups/opt_out.


Re: Clojure code for detecting overlap of 3d shapes (specifically tetrahedra)?

2014-02-16 Thread Karsten Schmidt
Yer welcome  please do let me know how this works out for you! I've
updated the gist[1] to delay more parts of the whole computation and
replace most occurrences of `reduce` with `loop` - altogether leading
to an almost 2x faster result for the worst case scenario where all
test clauses are checked. K.

[1] https://gist.github.com/postspectacular/9021724

On 15 February 2014 17:25, Lee Spector lspec...@hampshire.edu wrote:


 On Feb 15, 2014, at 11:49 AM, Karsten Schmidt wrote:

 Hi Lee, I've already implemented the algorithm described in this paper
 and it will be part of my upcoming geometry library. To not keep you
 waiting for the release, I've extracted the relevant code and put up
 here:

 https://gist.github.com/postspectacular/9021724

 [etc]


 Hi Karsten,

 Wow! That is *extremely* helpful! Thank you so much. I will experiment with 
 it as soon as I can and let you know if I run into any issues, but it looks 
 like you've done a fantastic job here, and I'm really grateful that you've 
 done the work and released this part early.

 Thanks!!

  -Lee

 --
 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/groups/opt_out.



-- 
Karsten Schmidt
http://postspectacular.com | http://toxiclibs.org | http://toxi.co.uk

-- 
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/groups/opt_out.


Re: (series of swap! on atom) == single swap!

2014-02-16 Thread Ramesh
You can use a ref instead of an atom. And use dosync with multiple alter,
so everything is safely inside a transaction.
On Feb 16, 2014 2:04 PM, t x txrev...@gmail.com wrote:

 Hi John,

   Your solution is perfectly valid and optimal for the problem I
 described above.


   Unfortunately, I forgot to mention an additional constraint: sometimes I
 do:

 (let [ foo (:some-selector @data-atom) ]
   (swap! data-atom update-in [:other-selector] ... ))

 which the - doesn't quite work on, but my ugly hack above does resolve.


   The problem being -- I want to update one part of the atom, but it
 depends on another part of the atom.

   I ended up with the following hack:

 (defn tswap! [atm func]
   (swap! atm
  (fn [old]
(let [natm (atom old)]
  (func natm)
  @natm


 On Sat, Feb 15, 2014 at 4:09 PM, John D. Hume duelin.mark...@gmail.com
 wrote:
  On Sat, Feb 15, 2014 at 6:04 PM, t x txrev...@gmail.com wrote:
 
 
  (defn what-I-want []
(with-atom some-atom
  assoc-in ...
  assoc-in ...
  update-in ...))
 
 
  I often do something like this and don't find it too ugly:
  (swap! my-atom #(- %
(assoc-in [:k] v)
(update-in [:k2] inc)
,,,))
 
  --
  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/groups/opt_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/groups/opt_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/groups/opt_out.


Re: (series of swap! on atom) == single swap!

2014-02-16 Thread t x
I believe that's the STM approach, which has the advanrtage of:

  * can synchronize across multiple pieces of data

but has the disadvantage of:

  * work must be pure since it can be retried

  * possibly less efficient due to possibility of retrying


In the example I posted above, I only need to:

  * modify a single atom

and the approach I presented above:

  * can be impure, since it is guaranteed to only run once

  * is guaranteed to succeed (without retrys)

On Sun, Feb 16, 2014 at 2:25 PM, Ramesh ramesh10dul...@gmail.com wrote:
 You can use a ref instead of an atom. And use dosync with multiple alter, so
 everything is safely inside a transaction.

 On Feb 16, 2014 2:04 PM, t x txrev...@gmail.com wrote:

 Hi John,

   Your solution is perfectly valid and optimal for the problem I
 described above.


   Unfortunately, I forgot to mention an additional constraint: sometimes I
 do:

 (let [ foo (:some-selector @data-atom) ]
   (swap! data-atom update-in [:other-selector] ... ))

 which the - doesn't quite work on, but my ugly hack above does resolve.


   The problem being -- I want to update one part of the atom, but it
 depends on another part of the atom.

   I ended up with the following hack:

 (defn tswap! [atm func]
   (swap! atm
  (fn [old]
(let [natm (atom old)]
  (func natm)
  @natm


 On Sat, Feb 15, 2014 at 4:09 PM, John D. Hume duelin.mark...@gmail.com
 wrote:
  On Sat, Feb 15, 2014 at 6:04 PM, t x txrev...@gmail.com wrote:
 
 
  (defn what-I-want []
(with-atom some-atom
  assoc-in ...
  assoc-in ...
  update-in ...))
 
 
  I often do something like this and don't find it too ugly:
  (swap! my-atom #(- %
(assoc-in [:k] v)
(update-in [:k2] inc)
,,,))
 
  --
  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/groups/opt_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/groups/opt_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/groups/opt_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/groups/opt_out.


Looking for advice to fine tune a simple function

2014-02-16 Thread Laurent Droin
Hi,

Disclaimer - I am completely new to Clojure. I just implemented my very 
first (simple) program, letting me find out, from a GPX file, how much time 
is spent in the various heart rate zones. Now that it's working, I'm 
reviewing the code and trying to use best practices. From what I have read 
so far, there are many ways in Clojure to do the same thing and for a 
newbie, it's not always obvious to get a good grasp on what is the best way 
to  code a feature.
As a developer, and even though I love how concise Clojure programs can be, 
I am very concerned with readability and ease of maintenance so I would 
like to keep functions as short and tight as possible, but not to the point 
where it becomes hard to understand what it does.

Here is a function that I came up with that takes  a bpm (heart beats per 
minute) value, as well as a sequence of 4 values that represent the 
boundaries defining the 5 different heart rate zones for a particular 
person.
The function needs to finds out in what heart zone the bpm value falls into 
and return that zone (as a keyword - I later use that keyword in a map).

If you're an experienced Clojure developer, what would you have done 
differently (and why) ?

*(defn hr-zone*
*  Return the HR zone as a keyword according to the bpm value.*
*  [bpm [max-zone-1 max-zone-2 max-zone-3 max-zone-4]] *
*  (cond *
*(= bpm max-zone-1) :hr-zone-1*
*(and ( max-zone-1 bpm) (= max-zone-2 bpm)) :hr-zone-2 *
*(and ( max-zone-2 bpm) (= max-zone-3 bpm)) :hr-zone-3 *
*(and ( max-zone-3 bpm) (= max-zone-4 bpm)) :hr-zone-4 *
*( max-zone-4 bpm) :hr-zone-5))*

FYI, here is how I call this function in the REPL:
(def my-hr-zones-defs [120 150 165 180])

(hr-zone 115 my-hr-zones-defs)
(hr-zone 133 my-hr-zones-defs)
(hr-zone 161 my-hr-zones-defs)
(hr-zone 175 my-hr-zones-defs)
(hr-zone 192 my-hr-zones-refs)

Questions I have:
Would that make sense to consider (and maybe enforce) that the sequence 
received as parameter is sorted? If this was the case, I would assume I 
could avoid the and calls- assuming that all the conditions in the cone 
form are evaluated in order. 
Assuming that I need to test bpm against the two boundaries of each range, 
would there be a better way to do this:
*(and ( max-zone-1 bpm) (= max-zone-2 bpm))*
?
Maybe this would work, but is it preferable?
*( max-zone-1 bpm (dec **max-zone-2**))*

*Thanks in advance for the advice.*

*Laurent. *

-- 
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/groups/opt_out.


Latex style file for formatting/coloring clojure code?

2014-02-16 Thread Mark Engelberg
I am unable to find a style file that supports clojure code in LaTeX.  Can
anyone point me in the right direction?

Thanks,

Mark

-- 
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/groups/opt_out.


Re: Looking for advice to fine tune a simple function

2014-02-16 Thread gianluca torta
to me it seems that you are anyway relying on the assumption that the 
sequence is ordered, so I think it would be convenient to drop the ands

Gianluca


On Sunday, February 16, 2014 11:31:46 PM UTC+1, Laurent Droin wrote:

 Hi,

 Disclaimer - I am completely new to Clojure. I just implemented my very 
 first (simple) program, letting me find out, from a GPX file, how much time 
 is spent in the various heart rate zones. Now that it's working, I'm 
 reviewing the code and trying to use best practices. From what I have read 
 so far, there are many ways in Clojure to do the same thing and for a 
 newbie, it's not always obvious to get a good grasp on what is the best way 
 to  code a feature.
 As a developer, and even though I love how concise Clojure programs can 
 be, I am very concerned with readability and ease of maintenance so I would 
 like to keep functions as short and tight as possible, but not to the point 
 where it becomes hard to understand what it does.

 Here is a function that I came up with that takes  a bpm (heart beats per 
 minute) value, as well as a sequence of 4 values that represent the 
 boundaries defining the 5 different heart rate zones for a particular 
 person.
 The function needs to finds out in what heart zone the bpm value falls 
 into and return that zone (as a keyword - I later use that keyword in a 
 map).

 If you're an experienced Clojure developer, what would you have done 
 differently (and why) ?

 *(defn hr-zone*
 *  Return the HR zone as a keyword according to the bpm value.*
 *  [bpm [max-zone-1 max-zone-2 max-zone-3 max-zone-4]] *
 *  (cond *
 *(= bpm max-zone-1) :hr-zone-1*
 *(and ( max-zone-1 bpm) (= max-zone-2 bpm)) :hr-zone-2 *
 *(and ( max-zone-2 bpm) (= max-zone-3 bpm)) :hr-zone-3 *
 *(and ( max-zone-3 bpm) (= max-zone-4 bpm)) :hr-zone-4 *
 *( max-zone-4 bpm) :hr-zone-5))*

 FYI, here is how I call this function in the REPL:
 (def my-hr-zones-defs [120 150 165 180])

 (hr-zone 115 my-hr-zones-defs)
 (hr-zone 133 my-hr-zones-defs)
 (hr-zone 161 my-hr-zones-defs)
 (hr-zone 175 my-hr-zones-defs)
 (hr-zone 192 my-hr-zones-refs)

 Questions I have:
 Would that make sense to consider (and maybe enforce) that the sequence 
 received as parameter is sorted? If this was the case, I would assume I 
 could avoid the and calls- assuming that all the conditions in the cone 
 form are evaluated in order. 
 Assuming that I need to test bpm against the two boundaries of each range, 
 would there be a better way to do this:
 *(and ( max-zone-1 bpm) (= max-zone-2 bpm))*
 ?
 Maybe this would work, but is it preferable?
 *( max-zone-1 bpm (dec **max-zone-2**))*

 *Thanks in advance for the advice.*

 *Laurent. *



-- 
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/groups/opt_out.


Re: Looking for advice to fine tune a simple function

2014-02-16 Thread Andy-
I'm also very new to clojure but this is how I'd do it:

(def hr-zones {
   [0 100] :low
   [101 120] :fat-burn
   [121 140] :aerobic
   [141 160] :anaerobic
   [161 333] :max})

(defn hr-zone [hr]
  (some (fn [x]
(and (= (first (key x)) hr (second (key x)))
 (val x)))
hr-zones))


This method does have some disadvantages however (you have to make sure the 
boundaries are correct and it doesn't handle floating points like 140.4).

Whenever you see yourself repeating code (like the 3-4 if's you have) then 
you have to take a step back and maybe change your data structure so that 
your algorithm is easier.

Mathematically speaking you're really quantizing your data (aka applying a 
piecewise constant function). So you could even take another step back and 
make it more general. So find a data structure that represents the function 
(ie the intervals and the function value for each interval) and then you 
could come up with a function like quantize or mk-piecewise-const-fn 
that returns a function. So you could then do:

(let [myfn (mk-piecewise-const-fn [[100 :zone-1] [120 :zone-2] ...] ]
   myzone (myfn 142)]

and you have a general function  which you can now use with a much wider 
range of problems (not just specific to your hr-zone conversion).

But I'm too lazy to come up with a implementation for mk-piecewise-const-fn 
:)

HTH


On Sunday, February 16, 2014 5:31:46 PM UTC-5, Laurent Droin wrote:

 Hi,

 Disclaimer - I am completely new to Clojure. I just implemented my very 
 first (simple) program, letting me find out, from a GPX file, how much time 
 is spent in the various heart rate zones. Now that it's working, I'm 
 reviewing the code and trying to use best practices. From what I have read 
 so far, there are many ways in Clojure to do the same thing and for a 
 newbie, it's not always obvious to get a good grasp on what is the best way 
 to  code a feature.
 As a developer, and even though I love how concise Clojure programs can 
 be, I am very concerned with readability and ease of maintenance so I would 
 like to keep functions as short and tight as possible, but not to the point 
 where it becomes hard to understand what it does.

 Here is a function that I came up with that takes  a bpm (heart beats per 
 minute) value, as well as a sequence of 4 values that represent the 
 boundaries defining the 5 different heart rate zones for a particular 
 person.
 The function needs to finds out in what heart zone the bpm value falls 
 into and return that zone (as a keyword - I later use that keyword in a 
 map).

 If you're an experienced Clojure developer, what would you have done 
 differently (and why) ?

 *(defn hr-zone*
 *  Return the HR zone as a keyword according to the bpm value.*
 *  [bpm [max-zone-1 max-zone-2 max-zone-3 max-zone-4]] *
 *  (cond *
 *(= bpm max-zone-1) :hr-zone-1*
 *(and ( max-zone-1 bpm) (= max-zone-2 bpm)) :hr-zone-2 *
 *(and ( max-zone-2 bpm) (= max-zone-3 bpm)) :hr-zone-3 *
 *(and ( max-zone-3 bpm) (= max-zone-4 bpm)) :hr-zone-4 *
 *( max-zone-4 bpm) :hr-zone-5))*

 FYI, here is how I call this function in the REPL:
 (def my-hr-zones-defs [120 150 165 180])

 (hr-zone 115 my-hr-zones-defs)
 (hr-zone 133 my-hr-zones-defs)
 (hr-zone 161 my-hr-zones-defs)
 (hr-zone 175 my-hr-zones-defs)
 (hr-zone 192 my-hr-zones-refs)

 Questions I have:
 Would that make sense to consider (and maybe enforce) that the sequence 
 received as parameter is sorted? If this was the case, I would assume I 
 could avoid the and calls- assuming that all the conditions in the cone 
 form are evaluated in order. 
 Assuming that I need to test bpm against the two boundaries of each range, 
 would there be a better way to do this:
 *(and ( max-zone-1 bpm) (= max-zone-2 bpm))*
 ?
 Maybe this would work, but is it preferable?
 *( max-zone-1 bpm (dec **max-zone-2**))*

 *Thanks in advance for the advice.*

 *Laurent. *



-- 
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/groups/opt_out.


Re: (series of swap! on atom) == single swap!

2014-02-16 Thread Jan Herich
I'm afraid your understanding of atom swap! operations is not quite correct 
- update function must (or should) be pure as well.
See the 
documentationhttp://clojuredocs.org/clojure_core/clojure.core/swap!for swap!, 
update function could be potentially called multiple times if 
there are more threads of execution
updating one atomic reference - there is simple compare and 
sethttp://clojuredocs.org/clojure_core/clojure.core/compare-and-set!mechanism 
involved, which compares the old value of the atom
(input for the update function) and sets the atom to new value (return 
value from the update function) only value of the atom reference
was not changed in between, if yes the compare and set is retried until ti 
succeeds.

Dňa nedeľa, 16. februára 2014 23:35:24 UTC+1 t x napísal(-a):

 I believe that's the STM approach, which has the advanrtage of: 

   * can synchronize across multiple pieces of data 

 but has the disadvantage of: 

   * work must be pure since it can be retried 

   * possibly less efficient due to possibility of retrying 


 In the example I posted above, I only need to: 

   * modify a single atom 

 and the approach I presented above: 

   * can be impure, since it is guaranteed to only run once 

   * is guaranteed to succeed (without retrys) 

 On Sun, Feb 16, 2014 at 2:25 PM, Ramesh ramesh1...@gmail.comjavascript: 
 wrote: 
  You can use a ref instead of an atom. And use dosync with multiple 
 alter, so 
  everything is safely inside a transaction. 
  
  On Feb 16, 2014 2:04 PM, t x txre...@gmail.com javascript: wrote: 
  
  Hi John, 
  
Your solution is perfectly valid and optimal for the problem I 
  described above. 
  
  
Unfortunately, I forgot to mention an additional constraint: 
 sometimes I 
  do: 
  
  (let [ foo (:some-selector @data-atom) ] 
(swap! data-atom update-in [:other-selector] ... )) 
  
  which the - doesn't quite work on, but my ugly hack above does 
 resolve. 
  
  
The problem being -- I want to update one part of the atom, but it 
  depends on another part of the atom. 
  
I ended up with the following hack: 
  
  (defn tswap! [atm func] 
(swap! atm 
   (fn [old] 
 (let [natm (atom old)] 
   (func natm) 
   @natm 
  
  
  On Sat, Feb 15, 2014 at 4:09 PM, John D. Hume 
  duelin@gmail.comjavascript: 

  wrote: 
   On Sat, Feb 15, 2014 at 6:04 PM, t x txre...@gmail.com javascript: 
 wrote: 
   
   
   (defn what-I-want [] 
 (with-atom some-atom 
   assoc-in ... 
   assoc-in ... 
   update-in ...)) 
   
   
   I often do something like this and don't find it too ugly: 
   (swap! my-atom #(- % 
 (assoc-in [:k] v) 
 (update-in [:k2] inc) 
 ,,,)) 
   
   -- 
   You received this message because you are subscribed to the Google 
   Groups Clojure group. 
   To post to this group, send email to 
   clo...@googlegroups.comjavascript: 
   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 javascript: 
   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 javascript:. 
   For more options, visit https://groups.google.com/groups/opt_out. 
  
  -- 
  You received this message because you are subscribed to the Google 
  Groups Clojure group. 
  To post to this group, send email to clo...@googlegroups.comjavascript: 
  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 javascript: 
  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 javascript:. 
  For more options, visit https://groups.google.com/groups/opt_out. 
  
  -- 
  You received this message because you are subscribed to the Google 
  Groups Clojure group. 
  To post to this group, send email to clo...@googlegroups.comjavascript: 
  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 javascript: 
  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 
  

Re: Some advice about introducing clojurescript into a project using js/jquery

2014-02-16 Thread Dave Sann
It works pretty seamlessly.

You will need to include a jquery externs file to avoid munging of function 
call names by the google closure compiler in advanced mode.

See also

https://github.com/ibdknox/jayq

Which adds a few simplifications to usage (particularly some protocols for 
jQuery objects acting as sequences).
There may be others out there too.

if you plan to create elements on the client, you may want to use a hiccup 
style render, they are very effective and hiccup data is very amenable to 
composition. I use https://github.com/prismatic/dommy. but there are others 
too.

Dave



On Monday, 17 February 2014 01:47:18 UTC+11, Kashyap CK wrote:

 Hi,

 It took me some time to get started with clojurescript (on windows/cygwin) 
 - http://swannodette.github.io/2013/11/07/clojurescript-101/ worked for 
 me.

 I'd like to use clojurescript to do some UI component development for 
 product which is built using webkit/js/jquery. I was wondering if it is 
 okay to develop a feature in such an application, where most of the UI is 
 in jquery, in clojurescript?

 I'd appreciate it very much to know if there are any known gotha's here or 
 any tips that I could use?  

 Regards,
 Kashyap


-- 
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/groups/opt_out.


Re: (series of swap! on atom) == single swap!

2014-02-16 Thread t x
Hi Jan,

  You're right. I'm wrong.

  I'm grateful you pointed this out -- this would have otherwise been
impossible to debug.

===

To everyone:

  Why can swap! be retried? This confuses me -- to implement swap!, why can't we

  * have a lock

  * ensure that only one swap! is in session at any given time

  * have the given swap! complete before running the next swap!


Thanks!


On Sun, Feb 16, 2014 at 3:51 PM, Jan Herich jan.her...@gmail.com wrote:
 I'm afraid your understanding of atom swap! operations is not quite correct
 - update function must (or should) be pure as well.
 See the documentation for swap!, update function could be potentially called
 multiple times if there are more threads of execution
 updating one atomic reference - there is simple compare and set mechanism
 involved, which compares the old value of the atom
 (input for the update function) and sets the atom to new value (return value
 from the update function) only value of the atom reference
 was not changed in between, if yes the compare and set is retried until ti
 succeeds.

 Dňa nedeľa, 16. februára 2014 23:35:24 UTC+1 t x napísal(-a):

 I believe that's the STM approach, which has the advanrtage of:

   * can synchronize across multiple pieces of data

 but has the disadvantage of:

   * work must be pure since it can be retried

   * possibly less efficient due to possibility of retrying


 In the example I posted above, I only need to:

   * modify a single atom

 and the approach I presented above:

   * can be impure, since it is guaranteed to only run once

   * is guaranteed to succeed (without retrys)

 On Sun, Feb 16, 2014 at 2:25 PM, Ramesh ramesh1...@gmail.com wrote:
  You can use a ref instead of an atom. And use dosync with multiple
  alter, so
  everything is safely inside a transaction.
 
  On Feb 16, 2014 2:04 PM, t x txre...@gmail.com wrote:
 
  Hi John,
 
Your solution is perfectly valid and optimal for the problem I
  described above.
 
 
Unfortunately, I forgot to mention an additional constraint:
  sometimes I
  do:
 
  (let [ foo (:some-selector @data-atom) ]
(swap! data-atom update-in [:other-selector] ... ))
 
  which the - doesn't quite work on, but my ugly hack above does
  resolve.
 
 
The problem being -- I want to update one part of the atom, but it
  depends on another part of the atom.
 
I ended up with the following hack:
 
  (defn tswap! [atm func]
(swap! atm
   (fn [old]
 (let [natm (atom old)]
   (func natm)
   @natm
 
 
  On Sat, Feb 15, 2014 at 4:09 PM, John D. Hume duelin@gmail.com
  wrote:
   On Sat, Feb 15, 2014 at 6:04 PM, t x txre...@gmail.com wrote:
  
  
   (defn what-I-want []
 (with-atom some-atom
   assoc-in ...
   assoc-in ...
   update-in ...))
  
  
   I often do something like this and don't find it too ugly:
   (swap! my-atom #(- %
 (assoc-in [:k] v)
 (update-in [:k2] inc)
 ,,,))
  
   --
   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/groups/opt_out.
 
  --
  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/groups/opt_out.
 
  --
  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
  

Re: Looking for advice to fine tune a simple function

2014-02-16 Thread Andy-
I realized I could use that at some of my code so I wrote it. Not sure if 
it's the best possible implementation but here it is:

(defn quantizer
  Returns a function that quantizes input data which when called with 'x' 
returns:   o 1st val if-Inf  x = 1st bound   o 2st val if 1st 
bound  x = 2st bound   o ...   o last val if last-1 bound  x = last 
bound   o max if x  last bound where m is a vector of vectors where 
the first element specifies the boundary and   the second element the value 
which to return. Example:   (def points-grade (quantizer [[40 :F] [60 :D] 
[80 :C] [90 :B]] :A))   (map points-grade [10 80 93])   ; (:F :C :A)
  [m max]
  (fn [x]
(if (= x (first (first m)))
  (second (first m))
  (if ( x (first (last m)))
max
(some 
 (fn [i] 
   (let [[[l lv] [h hv]] i]
 (and ( l x) (= x h) hv)))
 (partition 2 1 m))


Cheers


On Sunday, February 16, 2014 6:47:51 PM UTC-5, Andy- wrote:

 I'm also very new to clojure but this is how I'd do it:

 (def hr-zones {
[0 100] :low
[101 120] :fat-burn
[121 140] :aerobic
[141 160] :anaerobic
[161 333] :max})

 (defn hr-zone [hr]
   (some (fn [x]
 (and (= (first (key x)) hr (second (key x)))
  (val x)))
 hr-zones))


 This method does have some disadvantages however (you have to make sure 
 the boundaries are correct and it doesn't handle floating points like 
 140.4).

 Whenever you see yourself repeating code (like the 3-4 if's you have) then 
 you have to take a step back and maybe change your data structure so that 
 your algorithm is easier.

 Mathematically speaking you're really quantizing your data (aka applying a 
 piecewise constant function). So you could even take another step back and 
 make it more general. So find a data structure that represents the function 
 (ie the intervals and the function value for each interval) and then you 
 could come up with a function like quantize or mk-piecewise-const-fn 
 that returns a function. So you could then do:

 (let [myfn (mk-piecewise-const-fn [[100 :zone-1] [120 :zone-2] ...] ]
myzone (myfn 142)]

 and you have a general function  which you can now use with a much wider 
 range of problems (not just specific to your hr-zone conversion).

 But I'm too lazy to come up with a implementation for 
 mk-piecewise-const-fn :)

 HTH


 On Sunday, February 16, 2014 5:31:46 PM UTC-5, Laurent Droin wrote:

 Hi,

 Disclaimer - I am completely new to Clojure. I just implemented my very 
 first (simple) program, letting me find out, from a GPX file, how much time 
 is spent in the various heart rate zones. Now that it's working, I'm 
 reviewing the code and trying to use best practices. From what I have read 
 so far, there are many ways in Clojure to do the same thing and for a 
 newbie, it's not always obvious to get a good grasp on what is the best way 
 to  code a feature.
 As a developer, and even though I love how concise Clojure programs can 
 be, I am very concerned with readability and ease of maintenance so I would 
 like to keep functions as short and tight as possible, but not to the point 
 where it becomes hard to understand what it does.

 Here is a function that I came up with that takes  a bpm (heart beats per 
 minute) value, as well as a sequence of 4 values that represent the 
 boundaries defining the 5 different heart rate zones for a particular 
 person.
 The function needs to finds out in what heart zone the bpm value falls 
 into and return that zone (as a keyword - I later use that keyword in a 
 map).

 If you're an experienced Clojure developer, what would you have done 
 differently (and why) ?

 *(defn hr-zone*
 *  Return the HR zone as a keyword according to the bpm value.*
 *  [bpm [max-zone-1 max-zone-2 max-zone-3 max-zone-4]] *
 *  (cond *
 *(= bpm max-zone-1) :hr-zone-1*
 *(and ( max-zone-1 bpm) (= max-zone-2 bpm)) :hr-zone-2 *
 *(and ( max-zone-2 bpm) (= max-zone-3 bpm)) :hr-zone-3 *
 *(and ( max-zone-3 bpm) (= max-zone-4 bpm)) :hr-zone-4 *
 *( max-zone-4 bpm) :hr-zone-5))*

 FYI, here is how I call this function in the REPL:
 (def my-hr-zones-defs [120 150 165 180])

 (hr-zone 115 my-hr-zones-defs)
 (hr-zone 133 my-hr-zones-defs)
 (hr-zone 161 my-hr-zones-defs)
 (hr-zone 175 my-hr-zones-defs)
 (hr-zone 192 my-hr-zones-refs)

 Questions I have:
 Would that make sense to consider (and maybe enforce) that the sequence 
 received as parameter is sorted? If this was the case, I would assume I 
 could avoid the and calls- assuming that all the conditions in the cone 
 form are evaluated in order. 
 Assuming that I need to test bpm against the two boundaries of each 
 range, would there be a better way to do this:
 *(and ( max-zone-1 bpm) (= max-zone-2 bpm))*
 ?
 Maybe this would work, but is it preferable?
 *( max-zone-1 bpm (dec **max-zone-2**))*

 *Thanks in advance for the advice.*

 *Laurent. *



-- 
You received this message because 

Re: [ANN] Clojure 1.6.0-beta1

2014-02-16 Thread Mars0i
I like Alex's suggestions.  Another option is something rather than 
some or exists.  Something has the disadvantage that it's long, so 
when you combine it with addition strings, you get something even longer.  

On the other hand, for me both some and exists sound like existential 
quantifiers in logic, as in Some x is F,  There exists an x such that 
Fx.  The clojure function *every?* plays the role of the universal 
quantifier (All x are F), and the *some* function plays the role of the 
existential quantifier, although it does more.

However, a function named something? doesn't really sound like an 
existential quantifier (despite the fact that in English something can be 
used to express the existential quantifier (something is F).  Rather, 
something? suggests that there's something, rather than nothing, i.e. 
rather than nil.

(something? false) = false
is still a little bit confusing, but if you think of it as saying that 
falsehood is not nothing, then maybe it makes sense.


On Sunday, February 16, 2014 11:29:38 AM UTC-6, Alex Walker wrote:

 Part of Rich's objection to not-nil? variants could be that they are a 
 double negative, not-(no value)?, which can decrease clarity and require 
 more coffee.


- nil Means 'nothing/no-value'- represents Java null and tests 
logical false [clojure.org/reader]


 To compete with some? variants, I'd suggest a positive that I found 
 strangely available:

 exists?
 if-exists[?]
 when-exists[?]

 Or, more proper, though potentially more overloaded: value?, if-value[?], 
 when-value[?].

 On Sunday, February 16, 2014 12:54:12 AM UTC-6, Эльдар Габдуллин wrote:

 Like this, just

 not-nil?
 if-not-nil
 when-not-nil

 is much better for me.



 суббота, 15 февраля 2014 г., 7:12:21 UTC+4 пользователь Joel Holdbrooks 
 написал:

 As an addendum to my last comment, *not-nil?* would also be a good 
 candidate. That really doesn't leave room for doubt.

 This:
   
 (some? false) ;; = true 

 Would confuse me. On the other hand this:
   
 (not-nil? false) ;; = true 

 Would not.

 There's really no need to complicate the naming story here. It's also 
 easy to remember!

 On Friday, February 14, 2014 3:25:36 PM UTC-8, Alex Miller wrote:



 On Friday, February 14, 2014 2:27:49 PM UTC-6, DomKM wrote:

 Great changes! I have a question about #5.
  

 5) New some operations 
 Many conditional functions rely on logical truth (where falsey
 values are nil or false). Sometimes it is useful to have functions
 that rely on not nilness instead. These functions have been added to
 support these cases [CLJ-1343]:
 * some? - same as (not (nil? x))
 * if-some - like if-let, but checks (not (nil? test)) instead of test
 * when-some - like when-let, but checks (not (nil? test)) instead of 
 test


 It seems inconsistent to have some mean two very different things 
 within the same namespace, especially since the prior uses of some 
 (`some`, `some-fn`, etc.) are more in keeping with its primary definition 
 of having to do with amount (and operate on seqs or variadic arguments) 
 while the new functions have to do with existence (and operate on any 
 single value). Why not call these new functions `not-nil?`, `if-not-nil`, 
 and `when-not-nil`? Or, if not-nil is too unwieldy then what about 
 exists (`exists?`, `if-exists`, `when-exists`)?

 Are these names up for discussion?


 Hey Dom et al,

 The names of these functions were chosen by Rich. There was already 
 some name overloading of some even before these new functions with some 
 (truthy) and some-/some- (not nil). The new functions keep with the 
 latter meaning. Many other names were considered, including everything 
 I've 
 seen someone mention (-not-nil, exists, nnil, etc). As far as I know these 
 names are final, however, I will relay all of the feedback I've seen here, 
 on #clojure, and on Twitter to Rich for consideration.

 Alex
  



-- 
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/groups/opt_out.


Re: Some advice about introducing clojurescript into a project using js/jquery

2014-02-16 Thread Dave Della Costa
Just because you are using jQuery extensively in your JS codebase
doesn't mean you need jayq/jQuery in your ClojureScript code.  If you
are trying to do inter-op and call some of your JavaScript code from
your ClojureScript code, then you can simply use standard JavaScript
inter-op; if you want to user your ClojureScript functions in JS you
simply need to label those functions with the metadata ^:export and call
them in a namespace-qualified fashion.

externs are only necessary when you need to tell the Google Closure
compiler that it should not mangle certain names when compiling in
advanced mode
(https://developers.google.com/closure/compiler/docs/api-tutorial3).
That being the case, you only really need to make sure you have an
externs file which includes JS function names that you are referring to
in your ClojureScript code, and that is only if you are compiling in
advanced mode.  If you use jayq in advanced mode, of course you'll need
this (https://github.com/ibdknox/jayq#compiling), but if you don't
include it you don't need to think about it...or jQuery.

If you find you need to access the DOM in your ClojureScript code I
would suggest starting with something like dommy or even the default
Google closure libraries (the approach David Nolen takes in most of his
blog posts).

DD


(2014/02/16 23:47), Kashyap CK wrote:
 Hi,
 
 It took me some time to get started with clojurescript (on
 windows/cygwin)
 - http://swannodette.github.io/2013/11/07/clojurescript-101/ worked for me.
 
 I'd like to use clojurescript to do some UI component development for
 product which is built using webkit/js/jquery. I was wondering if it is
 okay to develop a feature in such an application, where most of the UI
 is in jquery, in clojurescript?
 
 I'd appreciate it very much to know if there are any known gotha's here
 or any tips that I could use?  
 
 Regards,
 Kashyap
 
 -- 
 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/groups/opt_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/groups/opt_out.


Re: Latex style file for formatting/coloring clojure code?

2014-02-16 Thread Andy-
On Sunday, February 16, 2014 6:05:24 PM UTC-5, puzzler wrote:

 I am unable to find a style file that supports clojure code in LaTeX.  Can 
 anyone point me in the right direction?

Pygments can output LaTeX. (There is also minted)

HTH 

-- 
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/groups/opt_out.


Re: Some advice about introducing clojurescript into a project using js/jquery

2014-02-16 Thread Kashyap CK
Thank you Dave and David,

Regards,
Kashyap

On Monday, February 17, 2014 8:26:25 AM UTC+5:30, David Della Costa wrote:

 Just because you are using jQuery extensively in your JS codebase 
 doesn't mean you need jayq/jQuery in your ClojureScript code.  If you 
 are trying to do inter-op and call some of your JavaScript code from 
 your ClojureScript code, then you can simply use standard JavaScript 
 inter-op; if you want to user your ClojureScript functions in JS you 
 simply need to label those functions with the metadata ^:export and call 
 them in a namespace-qualified fashion. 

 externs are only necessary when you need to tell the Google Closure 
 compiler that it should not mangle certain names when compiling in 
 advanced mode 
 (https://developers.google.com/closure/compiler/docs/api-tutorial3). 
 That being the case, you only really need to make sure you have an 
 externs file which includes JS function names that you are referring to 
 in your ClojureScript code, and that is only if you are compiling in 
 advanced mode.  If you use jayq in advanced mode, of course you'll need 
 this (https://github.com/ibdknox/jayq#compiling), but if you don't 
 include it you don't need to think about it...or jQuery. 

 If you find you need to access the DOM in your ClojureScript code I 
 would suggest starting with something like dommy or even the default 
 Google closure libraries (the approach David Nolen takes in most of his 
 blog posts). 

 DD 


 (2014/02/16 23:47), Kashyap CK wrote: 
  Hi, 
  
  It took me some time to get started with clojurescript (on 
  windows/cygwin) 
  - http://swannodette.github.io/2013/11/07/clojurescript-101/ worked for 
 me. 
  
  I'd like to use clojurescript to do some UI component development for 
  product which is built using webkit/js/jquery. I was wondering if it is 
  okay to develop a feature in such an application, where most of the UI 
  is in jquery, in clojurescript? 
  
  I'd appreciate it very much to know if there are any known gotha's here 
  or any tips that I could use?   
  
  Regards, 
  Kashyap 
  
  -- 
  You received this message because you are subscribed to the Google 
  Groups Clojure group. 
  To post to this group, send email to clo...@googlegroups.comjavascript: 
  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 javascript: 
  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 javascript:. 
  For more options, visit https://groups.google.com/groups/opt_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/groups/opt_out.


Re: Looking for advice to fine tune a simple function

2014-02-16 Thread Bruno Kim Medeiros Cesar
I can't claim to be an experienced Clojure developer, specially so 
regarding maintainability as I'm the only reader of what I write. Andy 
provided a great piece of code, although I scratched my head for a second 
or two unwrapping the last two lines. You'll be surprised how often 
(partition * 1) comes up, as it provides a sliding window through a 
sequence.

(BTW, Andy, how do you format your code so prettily?)

Regarding your question about expecting a sorted input: why don't you 
ensure it? These are the (very similar) options to enforce a precondition 
that I know of:










*(defn hr-zone [bpm [zone-1 zone-2 zone-3 zone-4 :as zones]]  {:pre [( 
zone-1 zone-2 zone-3 zone-4)]} ...) ; I don't see this very often, but it's 
simple(defn hr-zone [bpm [zone-1 zone-2 zone-3 zone-4 :as zones]]  (assert 
( zone-1 zone-2 zone-3 zone-4)} Not sorted!) ...) ; throws an error just 
as the above one, but with a provided message(defn hr-zone [bpm [zone-1 
zone-2 zone-3 zone-4 :as zones]]  (when-not ( zone-1 zone-2 zone-3 
zone-4)} (throw (Exception. Not sorted!))) ...) ; If you want to be able 
to catch the error, you may throw an exception*sorted? does not do what you 
may expect: it tests whether the data structure implements Sorted, such as 
sorted-set and sorted-map. You may get the same behaviour with (apply = 
coll) or (apply  coll) for numeric collections.

For me, the simplest option is




*(defn hr-zone [bpm zones]  (let [[zone-1 zone-2 zone-3 zone-4] (sort 
zones)]...)*
which never fails, although may not be what you need (for example, you'd 
like to be alerted if you input [174 178 128 186] when you wanted [174 178 
182 186]).

Hope that helps a bit,

Bruno Kim.

On Sunday, February 16, 2014 7:31:46 PM UTC-3, Laurent Droin wrote:

 Hi,

 Disclaimer - I am completely new to Clojure. I just implemented my very 
 first (simple) program, letting me find out, from a GPX file, how much time 
 is spent in the various heart rate zones. Now that it's working, I'm 
 reviewing the code and trying to use best practices. From what I have read 
 so far, there are many ways in Clojure to do the same thing and for a 
 newbie, it's not always obvious to get a good grasp on what is the best way 
 to  code a feature.
 As a developer, and even though I love how concise Clojure programs can 
 be, I am very concerned with readability and ease of maintenance so I would 
 like to keep functions as short and tight as possible, but not to the point 
 where it becomes hard to understand what it does.

 Here is a function that I came up with that takes  a bpm (heart beats per 
 minute) value, as well as a sequence of 4 values that represent the 
 boundaries defining the 5 different heart rate zones for a particular 
 person.
 The function needs to finds out in what heart zone the bpm value falls 
 into and return that zone (as a keyword - I later use that keyword in a 
 map).

 If you're an experienced Clojure developer, what would you have done 
 differently (and why) ?

 *(defn hr-zone*
 *  Return the HR zone as a keyword according to the bpm value.*
 *  [bpm [max-zone-1 max-zone-2 max-zone-3 max-zone-4]] *
 *  (cond *
 *(= bpm max-zone-1) :hr-zone-1*
 *(and ( max-zone-1 bpm) (= max-zone-2 bpm)) :hr-zone-2 *
 *(and ( max-zone-2 bpm) (= max-zone-3 bpm)) :hr-zone-3 *
 *(and ( max-zone-3 bpm) (= max-zone-4 bpm)) :hr-zone-4 *
 *( max-zone-4 bpm) :hr-zone-5))*

 FYI, here is how I call this function in the REPL:
 (def my-hr-zones-defs [120 150 165 180])

 (hr-zone 115 my-hr-zones-defs)
 (hr-zone 133 my-hr-zones-defs)
 (hr-zone 161 my-hr-zones-defs)
 (hr-zone 175 my-hr-zones-defs)
 (hr-zone 192 my-hr-zones-refs)

 Questions I have:
 Would that make sense to consider (and maybe enforce) that the sequence 
 received as parameter is sorted? If this was the case, I would assume I 
 could avoid the and calls- assuming that all the conditions in the cone 
 form are evaluated in order. 
 Assuming that I need to test bpm against the two boundaries of each range, 
 would there be a better way to do this:
 *(and ( max-zone-1 bpm) (= max-zone-2 bpm))*
 ?
 Maybe this would work, but is it preferable?
 *( max-zone-1 bpm (dec **max-zone-2**))*

 *Thanks in advance for the advice.*

 *Laurent. *



-- 
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/groups/opt_out.


Re: (series of swap! on atom) == single swap!

2014-02-16 Thread Jan Herich
Hi t x,

I think, that lock-free approach an it's semantics is more in line with 
other Clojure reference types such as refs.
It also encourages you to only use pure functions for state transitions, 
among other things, such as significant
performance benefits in comparison with lock based approaches, see for 
example this 
articlehttp://mechanical-sympathy.blogspot.sk/2013/08/lock-based-vs-lock-free-concurrent.html
. 
If you really want to update some reference with function which will also 
perform impure actions such as file I/O,
consider using agents http://clojure.org/agents and 
sendhttp://clojure.github.io/clojure/clojure.core-api.html#clojure.core/sendor
 
send-offhttp://clojure.github.io/clojure/clojure.core-api.html#clojure.core/send-off(the
 latter in case of I/O blocking actions), functions given to send 
and send-off are guaranteed to run only once.

Dňa pondelok, 17. februára 2014 2:36:59 UTC+1 t x napísal(-a):

 Hi Jan, 

   You're right. I'm wrong. 

   I'm grateful you pointed this out -- this would have otherwise been 
 impossible to debug. 

 === 

 To everyone: 

   Why can swap! be retried? This confuses me -- to implement swap!, why 
 can't we 

   * have a lock 

   * ensure that only one swap! is in session at any given time 

   * have the given swap! complete before running the next swap! 


 Thanks! 


 On Sun, Feb 16, 2014 at 3:51 PM, Jan Herich jan.h...@gmail.comjavascript: 
 wrote: 
  I'm afraid your understanding of atom swap! operations is not quite 
 correct 
  - update function must (or should) be pure as well. 
  See the documentation for swap!, update function could be potentially 
 called 
  multiple times if there are more threads of execution 
  updating one atomic reference - there is simple compare and set 
 mechanism 
  involved, which compares the old value of the atom 
  (input for the update function) and sets the atom to new value (return 
 value 
  from the update function) only value of the atom reference 
  was not changed in between, if yes the compare and set is retried until 
 ti 
  succeeds. 
  
  Dňa nedeľa, 16. februára 2014 23:35:24 UTC+1 t x napísal(-a): 
  
  I believe that's the STM approach, which has the advanrtage of: 
  
* can synchronize across multiple pieces of data 
  
  but has the disadvantage of: 
  
* work must be pure since it can be retried 
  
* possibly less efficient due to possibility of retrying 
  
  
  In the example I posted above, I only need to: 
  
* modify a single atom 
  
  and the approach I presented above: 
  
* can be impure, since it is guaranteed to only run once 
  
* is guaranteed to succeed (without retrys) 
  
  On Sun, Feb 16, 2014 at 2:25 PM, Ramesh ramesh1...@gmail.com wrote: 
   You can use a ref instead of an atom. And use dosync with multiple 
   alter, so 
   everything is safely inside a transaction. 
   
   On Feb 16, 2014 2:04 PM, t x txre...@gmail.com wrote: 
   
   Hi John, 
   
 Your solution is perfectly valid and optimal for the problem I 
   described above. 
   
   
 Unfortunately, I forgot to mention an additional constraint: 
   sometimes I 
   do: 
   
   (let [ foo (:some-selector @data-atom) ] 
 (swap! data-atom update-in [:other-selector] ... )) 
   
   which the - doesn't quite work on, but my ugly hack above does 
   resolve. 
   
   
 The problem being -- I want to update one part of the atom, but it 
   depends on another part of the atom. 
   
 I ended up with the following hack: 
   
   (defn tswap! [atm func] 
 (swap! atm 
(fn [old] 
  (let [natm (atom old)] 
(func natm) 
@natm 
   
   
   On Sat, Feb 15, 2014 at 4:09 PM, John D. Hume duelin@gmail.com 

   wrote: 
On Sat, Feb 15, 2014 at 6:04 PM, t x txre...@gmail.com wrote: 


(defn what-I-want [] 
  (with-atom some-atom 
assoc-in ... 
assoc-in ... 
update-in ...)) 


I often do something like this and don't find it too ugly: 
(swap! my-atom #(- % 
  (assoc-in [:k] v) 
  (update-in [:k2] inc) 
  ,,,)) 

-- 
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/groups/opt_out.