Re: Example in Joy of Clojure, 2nd edition (MEAP)
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
(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?
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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!
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)?
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!
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!
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
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?
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
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
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!
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
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!
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
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
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
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?
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
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
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!
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.