- macro and accessing context
Hi, I sometimes (in fact quite often) want to use the - macro like this: (- {} (assoc :a a) (assoc :b (some-fn CTX))) where CTX should be the current value of the threaded element. Currently, I'm forced to write a helper function (defn add-some-fn [ctx] (assoc ctx :b (some-fn ctx))) and rewrite my usage of - to (- {} (assoc :a a) (add-some-fn)) This works, of course, but somehow feels awkward (it destroys the uniformity of my assoc chaining). Is there a more idiomatic way to do this? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: - macro and accessing context
Hi, since 1.5 there is as-http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/as- : (as- {} ctx (assoc ctx :a a) (assoc ctx :b (some-fn ctx))) Kind regards Meikel -- -- 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: - macro and accessing context
That looks like it can do the job; thanks! On Tuesday, July 2, 2013 8:12:04 AM UTC+2, Meikel Brandmeyer (kotarak) wrote: Hi, since 1.5 there is as-http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/as-%3E : (as- {} ctx (assoc ctx :a a) (assoc ctx :b (some-fn ctx))) Kind regards Meikel -- -- 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.set/union bug?
On 1 July 2013 21:39, Cedric Greevey cgree...@gmail.com wrote: What bugs me is that sorted-set-by needs apply to convert a coll into a sorted set; there's no short-and-pithy into for that case, and no coll-taking and varargs version pair like vec/vector either. (into (sorted-set) coll) -- -- 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.set/union bug?
Er...that won't use my custom comparator. :) On Tue, Jul 2, 2013 at 2:40 AM, Ray Miller r...@1729.org.uk wrote: On 1 July 2013 21:39, Cedric Greevey cgree...@gmail.com wrote: What bugs me is that sorted-set-by needs apply to convert a coll into a sorted set; there's no short-and-pithy into for that case, and no coll-taking and varargs version pair like vec/vector either. (into (sorted-set) coll) -- -- 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.
How to get value which been created in java from cli file
Hi all my english poor i hope someone could know what i said. i create Var in Java such as RT(mysapce xv object); and then i load a clj file RT.loadResourceScript(xx.clj); the question is how to get Value of xv in xx.clj and could reload it in nrepl. i try to do something like (use 'mysapce) (println xv) throw error unable to resovle symbol xv in this context . someone could help me may i have missing something? -- -- 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.set/union bug?
On 2 July 2013 08:10, Cedric Greevey cgree...@gmail.com wrote: Er...that won't use my custom comparator. :) Sorry, I thought it was clear how to generalize from my previous example. Here it is with a custom comparator: (into (sorted-set-by ) [1 2 4 2 1 2 3]) ;; = #{4 3 2 1} On Tue, Jul 2, 2013 at 2:40 AM, Ray Miller r...@1729.org.uk wrote: On 1 July 2013 21:39, Cedric Greevey cgree...@gmail.com wrote: What bugs me is that sorted-set-by needs apply to convert a coll into a sorted set; there's no short-and-pithy into for that case, and no coll-taking and varargs version pair like vec/vector either. (into (sorted-set) coll) -- -- 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.
Functions that return seqs
One things that always bugged me about clojure is that most functions that work on collections return seqs and not the original data structure type: (= [2 4 6] (- [2 [4]] flatten (conj 6))) = false Every time I transform collections I need to be aware of this. My questions is: is there a philosophical reason for that or it was implement this way because it's easier? Why conj is different? Doesn't it break the principle of least surprise? Thanks, Islon -- -- 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.set/union bug?
Still seems verbose compared to (into #{}) ... On Tue, Jul 2, 2013 at 4:41 AM, Ray Miller r...@1729.org.uk wrote: On 2 July 2013 08:10, Cedric Greevey cgree...@gmail.com wrote: Er...that won't use my custom comparator. :) Sorry, I thought it was clear how to generalize from my previous example. Here it is with a custom comparator: (into (sorted-set-by ) [1 2 4 2 1 2 3]) ;; = #{4 3 2 1} On Tue, Jul 2, 2013 at 2:40 AM, Ray Miller r...@1729.org.uk wrote: On 1 July 2013 21:39, Cedric Greevey cgree...@gmail.com wrote: What bugs me is that sorted-set-by needs apply to convert a coll into a sorted set; there's no short-and-pithy into for that case, and no coll-taking and varargs version pair like vec/vector either. (into (sorted-set) coll) -- -- 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: Functions that return seqs
On 02/07/13 09:45, Islon Scherer wrote: My questions is: is there a philosophical reason for that or it was implement this way because it's easier? the reason is that there is a common underlying abstraction tying all these data-structures together and that is the 'Seq' abstraction. conj is polymorphic and will do its best to provide the most efficient way to add something to a collection. I guess the philosophical reason is that 'concrete types don't really matter'... Jim -- -- 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: Functions that return seqs
It's not really breaking principle of least surprise if you expect such functions to return sequences. A lot of people do expect this after a little bit of Lisp experience (Clojure or otherwise) I can see two advantages to having many functions return seqs: - It's a shared abstraction, which dramatically helps composability - It is a decent guess at the most efficient collection to use for general-purpose coding (functional code is pretty likely to do something recursively on a list, so a sequence is the most efficient thing to return as it supports efficient non-allocating traversal) My main issue with it is that (currently) it often leads to the production of an intermediate sequence that isn't needed. Reducers mitigate this somewhat in 1.5, but in the medium term I hope that the compiler gets smart enough to eliminate these. Right now it's a pain having to hand-write functions to avoid this in performance critical code, but you have to do it since the cost can be a 2x-5x overhead. On Tuesday, 2 July 2013 09:45:45 UTC+1, Islon Scherer wrote: One things that always bugged me about clojure is that most functions that work on collections return seqs and not the original data structure type: (= [2 4 6] (- [2 [4]] flatten (conj 6))) = false Every time I transform collections I need to be aware of this. My questions is: is there a philosophical reason for that or it was implement this way because it's easier? Why conj is different? Doesn't it break the principle of least surprise? Thanks, Islon -- -- 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] byte-streams: a rosetta stone for all the byte representations the jvm has to offer
This is cool, thanks Zach! Another set of mostly-isomporphic types that this could be applied to is different matrix/array types in core.matrix. core.matrix already has generic conversion mechanisms but they probably aren't as efficient as they could be. I'll take a look and see if the same techniques might be applicable. Quick question for you and the crowd: does there exist or should we build a standard immutable byte data representation for Clojure? I think this is often needed: ByteBuffers and byte[] arrays work well enough but are mutable. Byte sequences are nice and idiomatic but have a lot of overhead, so people are often forced to resort to a variety of other techniques. And it would be nice to support some higher level operations on such types, e.g. production of efficient (non-copying) immutable subsequences. From a data structure perspective, I'm imagining something like a persistent data structure with byte[] data arrays at the lowest level. Given the amount of data-processing stuff people are doing, it seems like a reasonable thing to have in contrib at least? On Saturday, 29 June 2013 18:57:58 UTC+1, Zach Tellman wrote: I've recently been trying to pull out useful pieces from some of my more monolithic libraries. The most recent result is 'byte-streams' [1], a library that figures how how to convert between different byte representations (including character streams), and how to efficiently transfer bytes between various byte sources and sinks. The net result is that you can do something like: (byte-streams/convert (File. /tmp/foo) String {:encoding utf-8}) and get a string representation of the file's contents. Of course, this is already possible using 'slurp', but you could also convert it to a CharSequence, or lazy sequence of ByteBuffers, or pretty much anything else you can imagine. This is accomplished by traversing a graph of available conversions (don't worry, it's memoized), so simply defining a new conversion from some custom type to (say) a ByteBuffer will transitively allow you to convert it to any other type. As an aside, this sort of conversion mechanism isn't limited to just byte representations, but I'm not sure if there's another large collection of mostly-isomorphic types out there that would benefit from this. If anyone has ideas on where else this could be applied, I'd be interested to hear them. Zach [1] https://github.com/ztellman/byte-streams -- -- 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.
reset! and merge for (transient {})
Is there reset! and merge a possibility for (transient {}) sometimes we have a doseq and it might be requirement sometime. -- -- 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.
reset! and merge for (transient {})
Hi, how we can achieve reset! and merge for (transient {}) e.g. when we have a doseq thanks. -- -- 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: reset! and merge for (transient {})
No merge will not work with transients because it uses conj instead of conj! If you absolutely have to do this define your own 'merge!' that uses conj!. I'm not sure what you mean by reset! for transients...reset! is an operation on reference types (atom, ref, agent etc) Jim On 02/07/13 11:33, Amir Wasim wrote: Is there reset! and merge a possibility for (transient {}) sometimes we have a doseq and it might be requirement sometime. -- -- 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: Functions that return seqs
If you really need to write functions that are polymorphic on collections type, then you can use the idiom: (defn some-fn [xs] (into (empty xs) ... )) But there is value in having the return type of a function to be predictable. -- Dave -- -- 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: Functions that return seqs
On 02/07/13 11:48, David Powell wrote: If you really need to write functions that are polymorphic on collections type, then you can use the idiom: (defn some-fn [xs] (into (empty xs) ... )) hehe :) good one! ...in other words you can piggyback 'conj'... Jim -- -- 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: reset! and merge for (transient {})
Maybe he means clear? 2013/7/2 Jim jimpil1...@gmail.com No merge will not work with transients because it uses conj instead of conj! If you absolutely have to do this define your own 'merge!' that uses conj!. I'm not sure what you mean by reset! for transients...reset! is an operation on reference types (atom, ref, agent etc) Jim On 02/07/13 11:33, Amir Wasim wrote: Is there reset! and merge a possibility for (transient {}) sometimes we have a doseq and it might be requirement sometime. -- -- 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+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://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+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com . For more options, visit https://groups.google.com/**groups/opt_outhttps://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+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://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+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com . For more options, visit https://groups.google.com/**groups/opt_outhttps://groups.google.com/groups/opt_out . -- 庄晓丹 Email:killme2...@gmail.com xzhu...@avos.com Site: http://fnil.net Twitter: @killme2008 -- -- 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: reset! and merge for (transient {})
what is 'clear' ? cannot find it anywhere... Jim On 02/07/13 12:03, dennis zhuang wrote: Maybe he means clear? 2013/7/2 Jim jimpil1...@gmail.com mailto:jimpil1...@gmail.com No merge will not work with transients because it uses conj instead of conj! If you absolutely have to do this define your own 'merge!' that uses conj!. I'm not sure what you mean by reset! for transients...reset! is an operation on reference types (atom, ref, agent etc) Jim On 02/07/13 11:33, Amir Wasim wrote: Is there reset! and merge a possibility for (transient {}) sometimes we have a doseq and it might be requirement sometime. -- -- 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 mailto: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 mailto:clojure%2bunsubscr...@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 mailto:clojure%2bunsubscr...@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 mailto: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 mailto:clojure%2bunsubscr...@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 mailto:clojure%2bunsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- 庄晓丹 Email: killme2...@gmail.com mailto:killme2...@gmail.com xzhu...@avos.com mailto:xzhu...@avos.com Site: http://fnil.net http://fnil.net Twitter: @killme2008 -- -- 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: reset! and merge for (transient {})
Clear the collection. user= (doc empty) - clojure.core/empty ([coll]) Returns an empty collection of the same category as coll, or nil nil 2013/7/2 Jim jimpil1...@gmail.com what is 'clear' ? cannot find it anywhere... Jim On 02/07/13 12:03, dennis zhuang wrote: Maybe he means clear? 2013/7/2 Jim jimpil1...@gmail.com No merge will not work with transients because it uses conj instead of conj! If you absolutely have to do this define your own 'merge!' that uses conj!. I'm not sure what you mean by reset! for transients...reset! is an operation on reference types (atom, ref, agent etc) Jim On 02/07/13 11:33, Amir Wasim wrote: Is there reset! and merge a possibility for (transient {}) sometimes we have a doseq and it might be requirement sometime. -- -- 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. -- 庄晓丹 Email:killme2...@gmail.com xzhu...@avos.com Site: http://fnil.net Twitter: @killme2008 -- -- 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. -- 庄晓丹 Email:killme2...@gmail.com xzhu...@avos.com Site: http://fnil.net Twitter: @killme2008 -- -- 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: Functions that return seqs
Thanks for all the answers. Agreed that sequences are a great abstraction (100 functions in 1 data structure instead of 10 to 10) and, as David said, there's value in having the return type to be predictable. I think a 'generics collection functions' library would be nice for those edge cases you want those functions to be generic. I guess the philosophical reason is that 'concrete types don't really matter'... Well, maybe most of the time, but there's cases where the concrete type semantics matters a lot, specially with sets but sometimes with vectors too, right now i'm using into or just calling vec|set or reducers library but maybe I'll try to implement this generics library I just talk about as it's really easy to do that in clojure =) Islon -- -- 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: Functions that return seqs
On 02/07/13 12:42, Islon Scherer wrote: Well, maybe most of the time, but there's cases where the concrete type semantics matters a lot, specially with sets but sometimes with vectors too, right now i'm using into or just calling vec|set or reducers library but maybe I'll try to implement this generics library I just talk about as it's really easy to do that in clojure =) Yes I actually agree...there are times where you don't want to mess with the types. In my work, this often comes up in clojure-java interop. I recently implemented a 'DataSet' protocol and extended it to all collection types (both persistent and non-persistent). Yes sure there is some code duplication, but now I can 'normalise' any collection (or gather basic statistics from it) using the most efficient way (depending on the type) and without messing with the actual concrete types. you can see the approach here: https://github.com/jimpil/hotel-nlp/blob/master/src/hotel_nlp/tools/normalito/core.clj Jim -- -- 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] byte-streams: a rosetta stone for all the byte representations the jvm has to offer
I have already used this library and it is really really useful. Thanks Zach. Thomas -- -- 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: - macro and accessing context
I believe the intended idiom for as- (and the reason it doesn't take a binding vector, like other forms that create locals) is (- {} (assoc :a a) (as- ctx (assoc ctx :b (some-fn ctx On Jul 2, 2013 1:12 AM, Meikel Brandmeyer (kotarak) m...@kotka.de wrote: Hi, since 1.5 there is as-http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/as-%3E : (as- {} ctx (assoc ctx :a a) (assoc ctx :b (some-fn ctx))) Kind regards Meikel -- -- 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: reset! and merge for (transient {})
Note that `merge` is basically just `conj` plus nil-checking, so there's a good chance `conj!` already does what you need. On Jul 2, 2013 5:33 AM, Amir Wasim amir.wa...@gmail.com wrote: Is there reset! and merge a possibility for (transient {}) sometimes we have a doseq and it might be requirement sometime. -- -- 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.
[ANN] lein-spell: Spell check your clojure docstrings and library docs
Introducing lein-spell, https://github.com/cldwalker/lein-spell - a library to quickly and easily spell check your clojure libraries. Usage - lein-spell prints misspelled words, one per line to STDOUT. By default your library's docstrings and markdown/txt docs are searched: $ lein-spell associtaed bugfix communitcated ... You can also check individual files: $ lein-spell doc/my-tutorial.org Until lein-spell's dictionary is good enough, there will be false positives. Add those to your local whitelist in .lein-spell. In the example above, bugfix would be a false positive. Once you're ready to edit your typos, you can see their locations with: $ lein spell -n ./README.md:25:associtaed src/my/lib.clj:44:communitcated This format is compatible with vim's grep so you can easily navigate your typos $ vim -c 'set grepprg=lein\ spell\ -n' -c 'botright copen' -c 'silent! grep' Install - Install aspell: # For mac osx $ brew install aspell # For ubuntu/debian $ apt-get install aspell Add to your project's :plugins key: [lein-spell 0.1.0] For more info, see the readme, https://github.com/cldwalker/lein-spell#readme Feedback welcome, Gabriel -- -- 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: Functions that return seqs
On Tue, Jul 2, 2013 at 4:45 AM, Islon Scherer islonsche...@gmail.com wrote: One things that always bugged me about clojure is that most functions that work on collections return seqs and not the original data structure type: (= [2 4 6] (- [2 [4]] flatten (conj 6))) = false Every time I transform collections I need to be aware of this. My questions is: is there a philosophical reason for that or it was implement this way because it's easier? Why conj is different? Doesn't it break the principle of least surprise? This prompted me to do a little REPL exploration as it surprised me in principle. My understanding of the sequence abstraction was that it was an abstraction over concrete types like list, vector, hash-sets, hash-maps, etc. The fact that many of the operations that work on those concrete types through the sequence abstraction returned seqs didn't matter because their concrete types were stilled preserved under the hood. So I had the following REPL session: user ; let's conj onto a vector, list, and hash-set user (conj [:a] :b) [:a :b] user (conj (list :a) :b) (:b :a) user (conj #{:a} :b) #{:a :b} user (conj #{:a} :a) #{:a} user ; notice that semantics of the hash-set are preserved and a duplicate value is impossible to conj on user ; now let's conj onto a seq of a vector, list, and hash-set user (conj (seq [:a]) :b) (:b :a) user (conj (seq (list :a)) :b) (:b :a) user (conj (seq #{:a}) :b) (:b :a) user (conj (seq #{:a}) :a) (:a :a) user ; notice how the semantics of the underlying datastructure are destroyed in all cases but the list, given that vectors are best conjed onto at the back, and hash-sets should not allow duplicates. user ; this violates my understanding of seqs, in that I thought they were an abstraction over concrete types which conj would always honor despite the fact that they were an instance of an abstraction. Anyway, I'm sure I'm lightyears behind everyone else but I feel like I remember Rich at one point saying that you should never fear to use conj or worry about seqs because the underlying types will always be preserved and honored. Anyway, blew my mind. :) -- In Christ, Timmy V. http://blog.twonegatives.com/ http://five.sentenc.es/ -- Spend less time on mail -- -- 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] byte-streams: a rosetta stone for all the byte representations the jvm has to offer
Ropes? http://en.m.wikipedia.org/wiki/Rope_(data_structure) Ben -- This message was sent via electromagnetism. On 02.07.2013, at 12:19, Mikera mike.r.anderson...@gmail.com wrote: This is cool, thanks Zach! Another set of mostly-isomporphic types that this could be applied to is different matrix/array types in core.matrix. core.matrix already has generic conversion mechanisms but they probably aren't as efficient as they could be. I'll take a look and see if the same techniques might be applicable. Quick question for you and the crowd: does there exist or should we build a standard immutable byte data representation for Clojure? I think this is often needed: ByteBuffers and byte[] arrays work well enough but are mutable. Byte sequences are nice and idiomatic but have a lot of overhead, so people are often forced to resort to a variety of other techniques. And it would be nice to support some higher level operations on such types, e.g. production of efficient (non-copying) immutable subsequences. From a data structure perspective, I'm imagining something like a persistent data structure with byte[] data arrays at the lowest level. Given the amount of data-processing stuff people are doing, it seems like a reasonable thing to have in contrib at least? On Saturday, 29 June 2013 18:57:58 UTC+1, Zach Tellman wrote: I've recently been trying to pull out useful pieces from some of my more monolithic libraries. The most recent result is 'byte-streams' [1], a library that figures how how to convert between different byte representations (including character streams), and how to efficiently transfer bytes between various byte sources and sinks. The net result is that you can do something like: (byte-streams/convert (File. /tmp/foo) String {:encoding utf-8}) and get a string representation of the file's contents. Of course, this is already possible using 'slurp', but you could also convert it to a CharSequence, or lazy sequence of ByteBuffers, or pretty much anything else you can imagine. This is accomplished by traversing a graph of available conversions (don't worry, it's memoized), so simply defining a new conversion from some custom type to (say) a ByteBuffer will transitively allow you to convert it to any other type. As an aside, this sort of conversion mechanism isn't limited to just byte representations, but I'm not sure if there's another large collection of mostly-isomorphic types out there that would benefit from this. If anyone has ideas on where else this could be applied, I'd be interested to hear them. Zach [1] https://github.com/ztellman/byte-streams -- -- 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.
Casting to Object[]
Hello all. I have a following deftype: (deftype NDArray [^objects data ^long ndims ^longs shape ^longs strides]) ( https://github.com/si14/matrix-api/blob/70b376f58ec3846df6622b971001c3ade32d0725/src/main/clojure/clojure/core/matrix/impl/ndarray.clj#L30 ) Then, when I use data field in various contexts like aget/aset, Clojure warns me about reflection (and rightfully so). It's not a problem with primitive arrays because we can use (longs …) and similar functions to make cast explicitly, but there is no (objects …). With some googling I've found a following solution: (let [… #^[Ljava.lang.Object; data (.data m) …] (aset data idx v ( https://github.com/si14/matrix-api/blob/70b376f58ec3846df6622b971001c3ade32d0725/src/main/clojure/clojure/core/matrix/impl/ndarray.clj#L259 ) But it's really really ugly. Is there a way to make it better? -- -- 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: Casting to Object[]
On 02/07/13 15:41, Dmitry Groshev wrote: (let [… #^[Ljava.lang.Object; data (.data m) …] (aset data idx v that is exactly how you type-hint non-primitive arrays...agreed it's ugly but there is no other way :) Jim -- -- 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 generates unnecessary and slow type-checks
Jason, can you please help me with this: I'm not sure if the protocol-based implementation can give users any help writing new core operations efficiently (say, making a new array with c[i] = a[i] + b[i]^2 / 2) -- unless there's some clever way of combining protocols with macros (hmmm). Did you mean an optimization of the whole expression (like in expresso project) or optimization of the way this operation is done on the actual matrix representation? The difference is subtle, but important: the former one can be done with some abstract matrix implementation and the latter one is a matter of a particular implementation. If I understand correctly, expresso project is strictly about the former. I've elaborated on this in numerical-clojure group: https://groups.google.com/forum/#!topic/numerical-clojure/eioNIa8oc7E (point 4). On Sunday, June 30, 2013 1:01:32 AM UTC+4, Jason Wolfe wrote: This looks very interesting, thanks for sharing! I'll think about it a bit while working on our codebase and see if I can contribute any good examples. On Fri, Jun 28, 2013 at 7:17 AM, Mikera mike.r.an...@gmail.comjavascript: wrote: On Thursday, 20 June 2013 08:45:47 UTC+1, Jason Wolfe wrote: On Saturday, June 15, 2013 4:37:06 AM UTC-7, Mikera wrote: On Friday, 14 June 2013 18:15:34 UTC+1, Jason Wolfe wrote: Hey Mikera, I did look at core.matrix awhile ago, but I'll take another look. Right now, flop is just trying to make it easy to write *arbitrary* array operations compactly, while minimizing the chance of getting worse-than-Java performance. This used to be very tricky to get right when flop was developed (against Clojure 1.2); the situation has clearly improved since then, but there still seem to be some subtleties in going fast with arrays in 1.5.1 that we are trying to understand and then automate. As I understand it, core.matrix has a much more ambitious goal of abstracting over all matrix types. This is a great goal, but I'm not sure if the protocol-based implementation can give users any help writing new core operations efficiently (say, making a new array with c[i] = a[i] + b[i]^2 / 2) -- unless there's some clever way of combining protocols with macros (hmmm). A longer term objective for core.matrix could be to allow compiling such expressions. Our GSoC student Maik Schünemann is exploring how to represent and optimised mathematical expressions in Clojure, and in theory these could be used to compile down to efficient low-level operations. API could look something like this: ;; define an expression (def my-expression (expression [a b] (+ a (/ (* b b) 2 ;; compile the expression for the specified matrix implementation A (def func (compile-expression A my-expression)). ;; now computation can be run using the pre-compiled, optimised function (func A B) In the case that A is a Java double array, then perhaps the flop macros could be the engine behind generating the compiled function? I just benchmarked core.matrix/esum, and on my machine in Clojure 1.5.1 it's 2.69x slower than the Java version above, and 1.62x slower than our current best Clojure version. Great - happy to steal your implementation :-) Other core.matrix implementations are probably faster BTW: vectorz-clj is pure Java and has esum for the general-purpose Vector type implemented in exactly the same way as your fast Java example. Clatrix executes a lot of operations via native code using BLAS. I should follow up on this and clarify that core.matrix's esum is in fact as fast as Java -- I apologize for the false statement (I was unaware that new versions of leiningen disable advanced JIT optimizations by default, which lead to the numbers I reported). Nevertheless, I hope there may be room for interesting collaboration on more complex operations, or code gen as you mentioned. I'll follow up later when we're a bit further along. Great thanks for confirming, I was getting worried :-) On the topic of code gen, we've been thinking a bit about how to represent expressions in the expresso project, and are developing a few potential use case API examples. https://github.com/clojure-numerics/expresso/wiki/User-API-examples If anyone has any additional use cases to think about, then please throw them in! -- -- 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit
Re: Casting to Object[]
I think that is the only way. The good news is that this is Clojure, so you can easily wrap it in an object-array-cast macro On Tuesday, 2 July 2013 15:41:02 UTC+1, Dmitry Groshev wrote: Hello all. I have a following deftype: (deftype NDArray [^objects data ^long ndims ^longs shape ^longs strides]) ( https://github.com/si14/matrix-api/blob/70b376f58ec3846df6622b971001c3ade32d0725/src/main/clojure/clojure/core/matrix/impl/ndarray.clj#L30 ) Then, when I use data field in various contexts like aget/aset, Clojure warns me about reflection (and rightfully so). It's not a problem with primitive arrays because we can use (longs …) and similar functions to make cast explicitly, but there is no (objects …). With some googling I've found a following solution: (let [… #^[Ljava.lang.Object; data (.data m) …] (aset data idx v ( https://github.com/si14/matrix-api/blob/70b376f58ec3846df6622b971001c3ade32d0725/src/main/clojure/clojure/core/matrix/impl/ndarray.clj#L259 ) But it's really really ugly. Is there a way to make it better? -- -- 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: Casting to Object[]
= (def a (object-array 1)) #'user/a = (set! *warn-on-reflection* true) true = (aset a 0 nil) Reflection warning, NO_SOURCE_PATH:1:1 - call to aset can't be resolved. nil = (aset ^objects a 0 nil) nil hth, Christophe On Tue, Jul 2, 2013 at 5:13 PM, Mikera mike.r.anderson...@gmail.com wrote: I think that is the only way. The good news is that this is Clojure, so you can easily wrap it in an object-array-cast macro On Tuesday, 2 July 2013 15:41:02 UTC+1, Dmitry Groshev wrote: Hello all. I have a following deftype: (deftype NDArray [^objects data ^long ndims ^longs shape ^longs strides]) (https://github.com/si14/**matrix-api/blob/** 70b376f58ec3846df6622b971001c3**ade32d0725/src/main/clojure/** clojure/core/matrix/impl/**ndarray.clj#L30https://github.com/si14/matrix-api/blob/70b376f58ec3846df6622b971001c3ade32d0725/src/main/clojure/clojure/core/matrix/impl/ndarray.clj#L30 ) Then, when I use data field in various contexts like aget/aset, Clojure warns me about reflection (and rightfully so). It's not a problem with primitive arrays because we can use (longs …) and similar functions to make cast explicitly, but there is no (objects …). With some googling I've found a following solution: (let [… #^[Ljava.lang.Object; data (.data m) …] (aset data idx v (https://github.com/si14/**matrix-api/blob/** 70b376f58ec3846df6622b971001c3**ade32d0725/src/main/clojure/** clojure/core/matrix/impl/**ndarray.clj#L259https://github.com/si14/matrix-api/blob/70b376f58ec3846df6622b971001c3ade32d0725/src/main/clojure/clojure/core/matrix/impl/ndarray.clj#L259 ) But it's really really ugly. Is there a way to make it better? -- -- 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. -- On Clojure http://clj-me.cgrand.net/ Clojure Programming http://clojurebook.com Training, Consulting Contracting http://lambdanext.eu/ -- -- 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.
Bounded futures
Hi all, I'd like to get some feedback on an approach I took to limit the concurrency of parallel processing in some of my Clojure codebase. I've often found that I want to split work over some number of threads greater than CPUs + 2, but less than infinity. In the past I had used promises that were fulfilled by a FixedThreadPool. But that's a lot of setup and teardown that distracts from what you're actually trying to achieve. My new approach was to leverage a Semaphore: (defn bounded-pmap [limit f coll] (let [sem (Semaphore. limit true) step (fn [x] (.acquire sem) (future (try (f x) (finally (.release sem)] (- (map step coll) (doall) (map deref It's not lazy, but in my case the collection is already fully realized. I'm interested in constructive criticism or other approaches. Thanks! Best, Brian -- -- 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: Casting to Object[]
Thank you, works like a charm and makes my code smell better. On Tuesday, July 2, 2013 8:48:14 PM UTC+4, Christophe Grand wrote: = (def a (object-array 1)) #'user/a = (set! *warn-on-reflection* true) true = (aset a 0 nil) Reflection warning, NO_SOURCE_PATH:1:1 - call to aset can't be resolved. nil = (aset ^objects a 0 nil) nil hth, Christophe On Tue, Jul 2, 2013 at 5:13 PM, Mikera mike.r.an...@gmail.comjavascript: wrote: I think that is the only way. The good news is that this is Clojure, so you can easily wrap it in an object-array-cast macro On Tuesday, 2 July 2013 15:41:02 UTC+1, Dmitry Groshev wrote: Hello all. I have a following deftype: (deftype NDArray [^objects data ^long ndims ^longs shape ^longs strides]) (https://github.com/si14/**matrix-api/blob/** 70b376f58ec3846df6622b971001c3**ade32d0725/src/main/clojure/** clojure/core/matrix/impl/**ndarray.clj#L30https://github.com/si14/matrix-api/blob/70b376f58ec3846df6622b971001c3ade32d0725/src/main/clojure/clojure/core/matrix/impl/ndarray.clj#L30 ) Then, when I use data field in various contexts like aget/aset, Clojure warns me about reflection (and rightfully so). It's not a problem with primitive arrays because we can use (longs …) and similar functions to make cast explicitly, but there is no (objects …). With some googling I've found a following solution: (let [… #^[Ljava.lang.Object; data (.data m) …] (aset data idx v (https://github.com/si14/**matrix-api/blob/** 70b376f58ec3846df6622b971001c3**ade32d0725/src/main/clojure/** clojure/core/matrix/impl/**ndarray.clj#L259https://github.com/si14/matrix-api/blob/70b376f58ec3846df6622b971001c3ade32d0725/src/main/clojure/clojure/core/matrix/impl/ndarray.clj#L259 ) But it's really really ugly. Is there a way to make it better? -- -- 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. -- On Clojure http://clj-me.cgrand.net/ Clojure Programming http://clojurebook.com Training, Consulting Contracting http://lambdanext.eu/ -- -- 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 generates unnecessary and slow type-checks
I'm really sorry for coming back to this but even after everything we learned I'm still not able to get performance equal to java in a simple factorial benchmark. I'd like to think that I'm doing all the correct things to keep the comparison fair...observe this: benchmarks.core= (crit/bench (jf! 50)) WARNING: Final GC required 2.3432463351555 % of runtime Evaluation count : 311580 in 60 samples of 5193 calls. Execution time mean : 196.444969 µs Execution time std-deviation : 10.637274 µs Execution time lower quantile : 194.356268 µs ( 2.5%) Execution time upper quantile : 197.042127 µs (97.5%) Overhead used : 258.723396 ns Found 9 outliers in 60 samples (15. %) low-severe 2 (3. %) low-mild 7 (11.6667 %) Variance from outliers : 40.1247 % Variance is moderately inflated by outliers nil now java: benchmarks.core= (crit/bench (.factorial ^Benchmarks (Benchmarks.) 50)) WARNING: Final GC required 2.656271755497413 % of runtime Evaluation count : 562260 in 60 samples of 9371 calls. Execution time mean : 107.148989 µs Execution time std-deviation : 1.650542 µs Execution time lower quantile : 106.504235 µs ( 2.5%) Execution time upper quantile : 108.934066 µs (97.5%) Overhead used : 258.723396 ns Found 5 outliers in 60 samples (8. %) low-severe 1 (1.6667 %) low-mild 4 (6.6667 %) Variance from outliers : 1.6389 % Variance is slightly inflated by outliers can you spot any differences with this code that would justify needing almost twice as much time? (defn jf! Calculate factorial of n as fast as Java without overflowing. [n] (loop [i (int n) ret 1N] (if (== 1 i) ret (recur (dec i) (* ret i) now java: public BigInteger factorial(final int n){ BigInteger res = BigInteger.valueOf(1L); //build upresult for (int i = n; i 1; i--) res = res.multiply(BigInteger.valueOf(i)); return res; } I know this is getting ridiculous but I'm preparing a presentation and I was sort of counting on this example...Of course, it goes without saying that I'm using unchecked-math and :jvm-opts ^replace[] . am I doing something wrong? thanks for your time Jim On Fri, 14 Jun 2013 00:11:52 -0700 (PDT) Jason Wolfe ja...@w01fe.com wrote: Thanks for your response. I attempted to answer this in my clarification, but our goal is to attack this 'general advice' and make it possible to get the same speed for array handling in natural-seeming Clojure without writing Java. In particular, we want to create macros that make it easy to achieve maximum performance by putting *your code* for manipulating array elements in the middle of an optimized loop, and this can't be done easily at the library level (as far as I can see) by dropping to Java, since in Java your code would always have to be wrapped in a method invocation with corresponding performance implications. Our previous version of this library (developed for Clojure 1.2, IIRC) was able to get within 0-30% or so of raw Java speed while providing a clean Clojure interface, and we're trying to get back to this point with Clojure 1.5 so we can release it as open-source for everyone to use. -Jason On Friday, June 14, 2013 12:04:12 AM UTC-7, Glen Mailer wrote: This doesn't really answer your question directly, but is there a reason you need to keep this in clojure, or are you just aiming to establish why this is happening? My understanding was that for performance critical code the general advice is to drop down to raw java? Glen -- -- 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] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.uncomplicate.org/articles/community.html -- -- 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 generates unnecessary and slow type-checks
Try longs instead of ints? Clojure doesn't support local ints, so you may be casting longs to ints a lot. On Tue, Jul 2, 2013 at 11:05 AM, Jim - FooBar(); jimpil1...@gmail.comwrote: I'm really sorry for coming back to this but even after everything we learned I'm still not able to get performance equal to java in a simple factorial benchmark. I'd like to think that I'm doing all the correct things to keep the comparison fair...observe this: benchmarks.core= (crit/bench (jf! 50)) WARNING: Final GC required 2.3432463351555 % of runtime Evaluation count : 311580 in 60 samples of 5193 calls. Execution time mean : 196.444969 µs Execution time std-deviation : 10.637274 µs Execution time lower quantile : 194.356268 µs ( 2.5%) Execution time upper quantile : 197.042127 µs (97.5%) Overhead used : 258.723396 ns Found 9 outliers in 60 samples (15. %) low-severe 2 (3. %) low-mild 7 (11.6667 %) Variance from outliers : 40.1247 % Variance is moderately inflated by outliers nil now java: benchmarks.core= (crit/bench (.factorial ^Benchmarks (Benchmarks.) 50)) WARNING: Final GC required 2.656271755497413 % of runtime Evaluation count : 562260 in 60 samples of 9371 calls. Execution time mean : 107.148989 µs Execution time std-deviation : 1.650542 µs Execution time lower quantile : 106.504235 µs ( 2.5%) Execution time upper quantile : 108.934066 µs (97.5%) Overhead used : 258.723396 ns Found 5 outliers in 60 samples (8. %) low-severe 1 (1.6667 %) low-mild 4 (6.6667 %) Variance from outliers : 1.6389 % Variance is slightly inflated by outliers can you spot any differences with this code that would justify needing almost twice as much time? (defn jf! Calculate factorial of n as fast as Java without overflowing. [n] (loop [i (int n) ret 1N] (if (== 1 i) ret (recur (dec i) (* ret i) now java: public BigInteger factorial(final int n){ BigInteger res = BigInteger.valueOf(1L); //build upresult for (int i = n; i 1; i--) res = res.multiply(BigInteger.**valueOf(i)); return res; } I know this is getting ridiculous but I'm preparing a presentation and I was sort of counting on this example...Of course, it goes without saying that I'm using unchecked-math and :jvm-opts ^replace[] . am I doing something wrong? thanks for your time Jim On Fri, 14 Jun 2013 00:11:52 -0700 (PDT) Jason Wolfe ja...@w01fe.com wrote: Thanks for your response. I attempted to answer this in my clarification, but our goal is to attack this 'general advice' and make it possible to get the same speed for array handling in natural-seeming Clojure without writing Java. In particular, we want to create macros that make it easy to achieve maximum performance by putting *your code* for manipulating array elements in the middle of an optimized loop, and this can't be done easily at the library level (as far as I can see) by dropping to Java, since in Java your code would always have to be wrapped in a method invocation with corresponding performance implications. Our previous version of this library (developed for Clojure 1.2, IIRC) was able to get within 0-30% or so of raw Java speed while providing a clean Clojure interface, and we're trying to get back to this point with Clojure 1.5 so we can release it as open-source for everyone to use. -Jason On Friday, June 14, 2013 12:04:12 AM UTC-7, Glen Mailer wrote: This doesn't really answer your question directly, but is there a reason you need to keep this in clojure, or are you just aiming to establish why this is happening? My understanding was that for performance critical code the general advice is to drop down to raw java? Glen -- -- 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+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/** topic/clojure/LTtxhPxH_ws/**unsubscribehttps://groups.google.com/d/topic/clojure/LTtxhPxH_ws/unsubscribe . To unsubscribe from this group and all its topics, send an email to clojure+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com . For more options, visit https://groups.google.com/**groups/opt_outhttps://groups.google.com/groups/opt_out . -- -- You
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
2013/7/2 Dragan Djuric draga...@gmail.com I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Good job, Dragan! -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- 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 generates unnecessary and slow type-checks
with a long counter it needs slightly longer (216 microseconds in average instead of 196)! any other ideas? On 02/07/13 19:11, Leon Barrett wrote: Try longs instead of ints? Clojure doesn't support local ints, so you may be casting longs to ints a lot. On Tue, Jul 2, 2013 at 11:05 AM, Jim - FooBar(); jimpil1...@gmail.com mailto:jimpil1...@gmail.com wrote: I'm really sorry for coming back to this but even after everything we learned I'm still not able to get performance equal to java in a simple factorial benchmark. I'd like to think that I'm doing all the correct things to keep the comparison fair...observe this: benchmarks.core= (crit/bench (jf! 50)) WARNING: Final GC required 2.3432463351555 % of runtime Evaluation count : 311580 in 60 samples of 5193 calls. Execution time mean : 196.444969 µs Execution time std-deviation : 10.637274 µs Execution time lower quantile : 194.356268 µs ( 2.5%) Execution time upper quantile : 197.042127 µs (97.5%) Overhead used : 258.723396 ns Found 9 outliers in 60 samples (15. %) low-severe 2 (3. %) low-mild 7 (11.6667 %) Variance from outliers : 40.1247 % Variance is moderately inflated by outliers nil now java: benchmarks.core= (crit/bench (.factorial ^Benchmarks (Benchmarks.) 50)) WARNING: Final GC required 2.656271755497413 % of runtime Evaluation count : 562260 in 60 samples of 9371 calls. Execution time mean : 107.148989 µs Execution time std-deviation : 1.650542 µs Execution time lower quantile : 106.504235 µs ( 2.5%) Execution time upper quantile : 108.934066 µs (97.5%) Overhead used : 258.723396 ns Found 5 outliers in 60 samples (8. %) low-severe 1 (1.6667 %) low-mild 4 (6.6667 %) Variance from outliers : 1.6389 % Variance is slightly inflated by outliers can you spot any differences with this code that would justify needing almost twice as much time? (defn jf! Calculate factorial of n as fast as Java without overflowing. [n] (loop [i (int n) ret 1N] (if (== 1 i) ret (recur (dec i) (* ret i) now java: public BigInteger factorial(final int n){ BigInteger res = BigInteger.valueOf(1L); //build upresult for (int i = n; i 1; i--) res = res.multiply(BigInteger.valueOf(i)); return res; } I know this is getting ridiculous but I'm preparing a presentation and I was sort of counting on this example...Of course, it goes without saying that I'm using unchecked-math and :jvm-opts ^replace[] . am I doing something wrong? thanks for your time Jim On Fri, 14 Jun 2013 00:11:52 -0700 (PDT) Jason Wolfe ja...@w01fe.com mailto:ja...@w01fe.com wrote: Thanks for your response. I attempted to answer this in my clarification, but our goal is to attack this 'general advice' and make it possible to get the same speed for array handling in natural-seeming Clojure without writing Java. In particular, we want to create macros that make it easy to achieve maximum performance by putting *your code* for manipulating array elements in the middle of an optimized loop, and this can't be done easily at the library level (as far as I can see) by dropping to Java, since in Java your code would always have to be wrapped in a method invocation with corresponding performance implications. Our previous version of this library (developed for Clojure 1.2, IIRC) was able to get within 0-30% or so of raw Java speed while providing a clean Clojure interface, and we're trying to get back to this point with Clojure 1.5 so we can release it as open-source for everyone to use. -Jason On Friday, June 14, 2013 12:04:12 AM UTC-7, Glen Mailer wrote: This doesn't really answer your question directly, but is there a reason you need to keep this in clojure, or are you just aiming to establish why this is happening? My understanding was that for performance critical code the general advice is to drop down to raw java? Glen -- -- 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 mailto: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
Re: New CSS library - Garden
Rob, Sorry for the late reply. I've been a bit distracted the past few days. I'll try to address your thoughts as best I can. *There could even be a grid protocol and fluid, responsive, fixed, mobile, etc be implementations of it, or multi-methods, or maybe its an overkill.* I don't think this is overkill. At the very least it's probably worth exploring. While I was translating the semantic grid SCSS code to Clojure, protocols did cross my mind. As I noted in the code comments there are a handful of core functions you see in virtually every grid system; well, in virtually every grid system I've ever seen. My instincts lead me to believe experimenting with protocols would be a step in the right direction. *... image overlay ... that could be really nice since a lot of designers still hand in photoshop illustrations that developers need to fit in* We have the JVM at our disposal. I'm fairly certain this could be a simple task although I'm not certain where one would start (probably Google). *Do you plan on incorporating a grid framework/concept in Garden? * Yes, but I'm waiting until Garden is no longer in beta (which should only be for another month or so). If you, or anyone reading this, would like to share gists/concepts for a grid framework that would definitely help keep the ball rolling. My main focus right now is making sure I've covered the most important topics (ie. color, units, comments, compilation) so people can feel confident and productive - especially if they're coming from Sass or another alt-css language. *...the pound signs are causing reader errors... * That's because I was using *data_readers.clj*. Have a look *here*https://github.com/noprompt/garden/blob/master/dev/data_readers.clj. I would definitely encourage anyone using Garden to employee this approach. Regarding the new CSS grid spec and not holding my breath. I won't. It'll probably be at least a year or two before we see something solidified and even longer before it's a viable option. It's a good idea but it still needs a ton of work. Anyhow, thanks for sharing your ideas! I look forward to hearing more from you. Joel On Thu, Jun 27, 2013 at 11:09 AM, Rob Jens rob.jentz...@gmail.com wrote: P.p.s. the pound signs are causing reader errors (e.g. #px) in LightTable so I changed those plus additionally added a little Jetty https://gist.github.com/clojens/5878804 Cheers Op dinsdag 9 april 2013 21:58:50 UTC+2 schreef Joel Holdbrooks het volgende: Nobel Clojurians, I am pleased to announce the alpha version of *Garden*https://github.com/noprompt/garden, a new library for writing CSS in Clojure. The project weds the best ideas from Hiccup, gaka, and cssgen and aims to provide a clean and conventional way to author stylesheets without being too simple or too complex. Currently the list of notable features include: - Nestable rules - Nestable declarations (this my change) - A builtin set of tools for working with CSS unit values - Convenient multiple selector syntax (IE. h1, h2, h3 { ... }) - Output formatting options What's planned for the near future: - The ability to use Clojure meta as a media query - A builtin set of tools for working with CSS color values - selector syntax for nested rules For those of you who are interested in this sort of thing, please have a look at the *project's repository* https://github.com/noprompt/garden. There is still quite a bit of ground to do cover and any help/criticism/contribution would be greatly appreciated. Please feel free to offer suggestions, ask questions, open issues, or send pull requests. I would love nothing more than to see this library succeed where other's have not. Truly, Joel Holdbrooks (aka noprompt) -- -- 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/xbFU2prTxlY/unsubscribe. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- Joel -- -- 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
Re: Bounded futures
a purely stylistic comment... you may want to consider 'with-resources' to get rid of all the try/finally clutter. I'd write your let statement like this: (let [step (fn [x] (with-resources [sem (Semaphore. limit true)] #(.release ^Semaphore %) (.acquire sem) (future (f x] a pretty basic map-reduce style function might the do the trick as well depending on your case. You still use pmap but in a much more disciplined fashion due to partitioning. (defn mapr A pretty basic map-reduce style mapping function. Will partition the data according to p-size and assign a future to each partition (per pmap). ([f coll p-size shuffle?] (- (cond- coll shuffle? shuffle) (partition-all p-size) (pmap #(mapv f %) ) (apply concat)) ) ;;concat the inner vectors that represent the partitions ([f coll p-size] (mapr f coll p-size false)) ([f coll] (mapr f coll (+ 2 cpu-no hope that helps :) Jim On 02/07/13 18:30, Brian Kirkbride wrote: Hi all, I'd like to get some feedback on an approach I took to limit the concurrency of parallel processing in some of my Clojure codebase. I've often found that I want to split work over some number of threads greater than CPUs + 2, but less than infinity. In the past I had used promises that were fulfilled by a FixedThreadPool. But that's a lot of setup and teardown that distracts from what you're actually trying to achieve. My new approach was to leverage a Semaphore: (defn bounded-pmap [limit f coll] (let [sem (Semaphore. limit true) step (fn [x] (.acquire sem) (future (try (f x) (finally (.release sem)] (- (map step coll) (doall) (map deref It's not lazy, but in my case the collection is already fully realized. I'm interested in constructive criticism or other approaches. Thanks! Best, Brian -- -- 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: Bounded futures
On 02/07/13 18:30, Brian Kirkbride wrote: In the past I had used promises that were fulfilled by a FixedThreadPool. But that's a lot of setup and teardown that distracts from what you're actually trying to achieve. no it's not...you define it once you use it forever! :) (defn pool-map A saner, more disciplined version of pmap. Submits jobs eagerly but polls for results lazily. Don't use if original ordering of 'coll' matters. ([f coll threads] (let [exec (Executors/newFixedThreadPool threads) pool (ExecutorCompletionService. exec) futures (try (mapv (fn [x] (.submit pool #(f x))) coll) (finally (.shutdown exec)))] (repeatedly (count futures) #(.. pool take get ([f coll] (pool-map f coll (+ 2 cpu-no Jim -- -- 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: Bounded futures
On Tuesday, July 2, 2013 1:37:20 PM UTC-5, Jim foo.bar wrote: a purely stylistic comment... you may want to consider 'with-resources' to get rid of all the try/finally clutter. I'd write your let statement like this: (let [step (fn [x] (with-resources [sem (Semaphore. limit true)] #(.release ^Semaphore %) (.acquire sem) (future (f x] Interesting, I hadn't considered with-resources. I don't think your code does the same thing, since the release happens in the calling thread, not inside the future. Right? a pretty basic map-reduce style function might the do the trick as well depending on your case. You still use pmap but in a much more disciplined fashion due to partitioning. (defn mapr A pretty basic map-reduce style mapping function. Will partition the data according to p-size and assign a future to each partition (per pmap). ([f coll p-size shuffle?] (- (cond- coll shuffle? shuffle) (partition-all p-size) (pmap #(mapv f %) ) (apply concat)) ) ;;concat the inner vectors that represent the partitions ([f coll p-size] (mapr f coll p-size false)) ([f coll] (mapr f coll (+ 2 cpu-no hope that helps :) This is a great technique when using pmap on fine-grained, CPU bound tasks with lots of items. The shuffle? is a nice touch too! In my case, processing each item can take a while, is not CPU intensive and their aren't too many items. That's why I want more than CPUs+2 threads (as in core/pmap). Jim On 02/07/13 18:30, Brian Kirkbride wrote: Hi all, I'd like to get some feedback on an approach I took to limit the concurrency of parallel processing in some of my Clojure codebase. I've often found that I want to split work over some number of threads greater than CPUs + 2, but less than infinity. In the past I had used promises that were fulfilled by a FixedThreadPool. But that's a lot of setup and teardown that distracts from what you're actually trying to achieve. My new approach was to leverage a Semaphore: (defn bounded-pmap [limit f coll] (let [sem (Semaphore. limit true) step (fn [x] (.acquire sem) (future (try (f x) (finally (.release sem)] (- (map step coll) (doall) (map deref It's not lazy, but in my case the collection is already fully realized. I'm interested in constructive criticism or other approaches. Thanks! Best, Brian -- -- 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 generates unnecessary and slow type-checks
I got nothin'. Stare at the bytecode? On Tue, Jul 2, 2013 at 11:21 AM, Jim - FooBar(); jimpil1...@gmail.comwrote: with a long counter it needs slightly longer (216 microseconds in average instead of 196)! any other ideas? On 02/07/13 19:11, Leon Barrett wrote: Try longs instead of ints? Clojure doesn't support local ints, so you may be casting longs to ints a lot. On Tue, Jul 2, 2013 at 11:05 AM, Jim - FooBar(); jimpil1...@gmail.comwrote: I'm really sorry for coming back to this but even after everything we learned I'm still not able to get performance equal to java in a simple factorial benchmark. I'd like to think that I'm doing all the correct things to keep the comparison fair...observe this: benchmarks.core= (crit/bench (jf! 50)) WARNING: Final GC required 2.3432463351555 % of runtime Evaluation count : 311580 in 60 samples of 5193 calls. Execution time mean : 196.444969 µs Execution time std-deviation : 10.637274 µs Execution time lower quantile : 194.356268 µs ( 2.5%) Execution time upper quantile : 197.042127 µs (97.5%) Overhead used : 258.723396 ns Found 9 outliers in 60 samples (15. %) low-severe 2 (3. %) low-mild 7 (11.6667 %) Variance from outliers : 40.1247 % Variance is moderately inflated by outliers nil now java: benchmarks.core= (crit/bench (.factorial ^Benchmarks (Benchmarks.) 50)) WARNING: Final GC required 2.656271755497413 % of runtime Evaluation count : 562260 in 60 samples of 9371 calls. Execution time mean : 107.148989 µs Execution time std-deviation : 1.650542 µs Execution time lower quantile : 106.504235 µs ( 2.5%) Execution time upper quantile : 108.934066 µs (97.5%) Overhead used : 258.723396 ns Found 5 outliers in 60 samples (8. %) low-severe 1 (1.6667 %) low-mild 4 (6.6667 %) Variance from outliers : 1.6389 % Variance is slightly inflated by outliers can you spot any differences with this code that would justify needing almost twice as much time? (defn jf! Calculate factorial of n as fast as Java without overflowing. [n] (loop [i (int n) ret 1N] (if (== 1 i) ret (recur (dec i) (* ret i) now java: public BigInteger factorial(final int n){ BigInteger res = BigInteger.valueOf(1L); //build upresult for (int i = n; i 1; i--) res = res.multiply(BigInteger.valueOf(i)); return res; } I know this is getting ridiculous but I'm preparing a presentation and I was sort of counting on this example...Of course, it goes without saying that I'm using unchecked-math and :jvm-opts ^replace[] . am I doing something wrong? thanks for your time Jim On Fri, 14 Jun 2013 00:11:52 -0700 (PDT) Jason Wolfe ja...@w01fe.com wrote: Thanks for your response. I attempted to answer this in my clarification, but our goal is to attack this 'general advice' and make it possible to get the same speed for array handling in natural-seeming Clojure without writing Java. In particular, we want to create macros that make it easy to achieve maximum performance by putting *your code* for manipulating array elements in the middle of an optimized loop, and this can't be done easily at the library level (as far as I can see) by dropping to Java, since in Java your code would always have to be wrapped in a method invocation with corresponding performance implications. Our previous version of this library (developed for Clojure 1.2, IIRC) was able to get within 0-30% or so of raw Java speed while providing a clean Clojure interface, and we're trying to get back to this point with Clojure 1.5 so we can release it as open-source for everyone to use. -Jason On Friday, June 14, 2013 12:04:12 AM UTC-7, Glen Mailer wrote: This doesn't really answer your question directly, but is there a reason you need to keep this in clojure, or are you just aiming to establish why this is happening? My understanding was that for performance critical code the general advice is to drop down to raw java? Glen -- -- 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/LTtxhPxH_ws/unsubscribe. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit
Re: Bounded futures
On 02/07/13 19:49, Brian Kirkbride wrote: Interesting, I hadn't considered with-resources. I don't think your code does the same thing, since the release happens in the calling thread, not inside the future. Right? oops! you're right...I rushed and I apologise...with-resources won't work here cos you're not really cleaning up anything. You are releasing a virtual resource from within a closure... Jim -- -- 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: Bounded futures
On 02/07/13 19:49, Brian Kirkbride wrote: In my case, processing each item can take a while, is not CPU intensive and their aren't too many items. so in your case you need an unbounded-pool...my work involves cpu-intensive tasks and haven't written a version of pool-map that uses an unboudned-pool. In fact, on second thoughts have you tried agents with 'send-off' ? Jim -- -- 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: Bounded futures
On Tuesday, July 2, 2013 1:41:14 PM UTC-5, Jim foo.bar wrote: On 02/07/13 18:30, Brian Kirkbride wrote: In the past I had used promises that were fulfilled by a FixedThreadPool. But that's a lot of setup and teardown that distracts from what you're actually trying to achieve. no it's not...you define it once you use it forever! :) (defn pool-map A saner, more disciplined version of pmap. Submits jobs eagerly but polls for results lazily. Don't use if original ordering of 'coll' matters. ([f coll threads] (let [exec (Executors/newFixedThreadPool threads) pool (ExecutorCompletionService. exec) futures (try (mapv (fn [x] (.submit pool #(f x))) coll) (finally (.shutdown exec)))] (repeatedly (count span class=nv style=color: rgb(0, 128, 128);futures) #(.. pool take get ([f coll] (pool-map f coll (+ 2 cpu-no Jim Absolutely true! I do like relying on future rather than creating and shutting down a ThreadPool for each run, though. And, as you mentioned, ordering is preserved with the Semaphore approach. One thing that I really like about blocking in acquire vs submitting everything to an ExecutorService/CompletionService right off the bat: you can bail out of the remainder of the computation when one part fails. I've got a function that creates a lazy Seq that will become empty if any application of (f x) fails. That means you don't even schedule the remaining items. You can, of course, check and abort inside of (f x) too. But there's a lot to like about not processing those items at all. Especially in composed pipelines of functions. -- -- 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.
Using core.async to port Clojure to Go
Are all Clojure concurrency primitives efficiently implementable on top of core.async? If so, could this be used to port Clojure from the JVM/CLR/JS to Go? -- -- 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: Bounded futures
On 02/07/13 20:05, Brian Kirkbride wrote: One thing that I really like about blocking in acquire vs submitting everything to an ExecutorService/CompletionService right off the bat: you can bail out of the remainder of the computation when one part fails. I've got a function that creates a lazy Seq that will become empty if any application of (f x) fails. That means you don't even schedule the remaining items. You can, of course, check and abort inside of (f x) too. But there's a lot to like about not processing those items at all. Especially in composed pipelines of functions. aaa ok now we're getting slightly off just 'mapping'. I thought all you wanted to do was a parallel map - I didn't realise there is more logic to it (aborting and stuff) now it makes sense why you won't like something like this either which can use hundreds of threads no problem :) (- coll (map agent) (map #(send-off % f))) Jim -- -- 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: Using core.async to port Clojure to Go
I've not looked at core.async yet but I'd expect it to build on top of the built-in concurrency primitives and not the other way around... Jim On 02/07/13 20:12, Robert wrote: Are all Clojure concurrency primitives efficiently implementable on top of core.async? If so, could this be used to port Clojure from the JVM/CLR/JS to Go? -- -- 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: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric draga...@gmail.com wrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.uncomplicate.org/articles/community.html -- -- 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. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- 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: Using core.async to port Clojure to Go
also what you're asking doesn't really make sensehow would you implement synchronisation primitives (stm atoms promises) on top of asynchronous infrastructure? agents are asynchronous but I haven't got a clue about the potential benefits (or not) of implementing them on top of core.async. Jim On 02/07/13 20:14, Jim - FooBar(); wrote: I've not looked at core.async yet but I'd expect it to build on top of the built-in concurrency primitives and not the other way around... Jim On 02/07/13 20:12, Robert wrote: Are all Clojure concurrency primitives efficiently implementable on top of core.async? If so, could this be used to port Clojure from the JVM/CLR/JS to Go? -- -- 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: core.async implemented on top of Pulsar
I had some time to play with core.async further today, and I learned some more about it. First let me say that I've completed the implementation of core.async on top of Pulsar (I've copied the alt! macro from the core.async repository and placed a copyright notice around it). I ran some of core.async tests on it, and they pass unchanged. But before I get back to what I've found, I want to address your remarks, Tim. My main point wasn't performance in general, but performance in a distributed system, and I may have expressed myself too mildly. Using alts! with distributed channels is not just slow - it is extremely difficult to do right, and actually makes it harder to build a robust system (to go back to Joe Armstrong). I might very well be wrong, but a distributed alts! would translate, in all but few cases, to a distributed transaction. And distributed transactions are hard. Now, this is what I've found playing with core.async today. First, the API is, unsurprisingly considering its source, simply brilliant. It's a paragon of simplicity (although I do forget the meaning of ! and !; I mean, which is send and which is receive? then I remember, oh, the ! stands for the channel, but again I forget which side of the bang the arrow goes). The alts! statement is a thing of beauty, although, I do stand by my opinion that it's too general by far. With regards to performance: core.async performs quite well. On several small benchmarks it outperforms Pulsar's core.async, like on this one (by Alex Miller): (let [n 1000 cs (repeatedly n chan) begin (System/currentTimeMillis)] (doseq [c cs] (go (! c hi))) (dotimes [i n] (let [[v c] (alts!! cs)] (assert (= hi v (println Read n msgs in (- (System/currentTimeMillis) begin) ms)) When I investigated, I found the cause to be (mostly) Pulsar's use of FJPool vs. core.async's use of ThreadPoolExecutor. In the above example, the go-blocks (we need a better name for them; I'm used to calling them fibers in Pulsar, so maybe fibers? or gos?) don't block. They are just all put into the thread-pool once, where they execute to completion. TPE beats FJP in that scenario. FJP shines when its tasks keep spawning other tasks, which translates to gos parking and unparking other gos. So when you have lots of interaction between fibers, that's when Pulsar's async beats core.async. Like in this example: (let [n 1 cs (repeatedly n chan) ; or; #(chan 10)) ; begin (System/currentTimeMillis)] (doseq [c cs] (go (dotimes [i 100] (! c i (let [cs2 (doall (map #(go (loop [i 0 sum (int 0)] (if ( i 100) (recur (inc i) (int (+ sum (! % sum))) cs))] (doseq [c cs2] (let [v (!! c)] (assert (= 4950 v (println Read n msgs in (- (System/currentTimeMillis) begin) ms))) Also, when benchmarking core.async on Pulsar (or any program using Pulsar) it is *extremely* important to run lein trampoline. Without trampoline, Pulsar runs *much* slower. core.async isn't affected much by the lack of trampoline. In any case, we now have two, quite different, implementations of the core.async API. I'd be interested to learn what other people find. To try core.async on Pulsar, you need the dev release: [co.paralleluniverse/pulsar 0.2-SNAPSHOT] On Monday, July 1, 2013 6:46:26 PM UTC+3, tbc++ wrote: Ben, you make a good point. I guess I was stating was something more along the lines of the following. We have really really good concurrency primitives (atom, ref, agent) and I think it would be a mistake to reach for channels when one of those would do. core.async is pretty fast, but reducers will probably work faster for normal map/reduce needs. You can write something like an agent using channels, but it won't be as fast as Clojure's agents. So I should have stated this much clearer to focus a system purely on core.async would be to ignore the other features of Clojure. Use core.async when other core language features won't work Timothy On Mon, Jul 1, 2013 at 9:27 AM, Ben Wolfson wol...@gmail.comjavascript: wrote: On Mon, Jul 1, 2013 at 7:10 AM, Timothy Baldridge tbald...@gmail.comjavascript: wrote: It's my opinion that core.async shouldn't be used a concurrency mechanism, or as a new programming paradigm. Instead, it should be used as a communication method between sequential processes, and as a de-coupling method between modules. Let's go back to Rich's original post on the library: There comes a time in all good programs when components or subsystems must stop communicating directly with one another. This is often achieved via the introduction of queues between the producers of data and the consumers/processors of that data. Well, if you're looking for guidance as to how the library should be used
Re: Clojure generates unnecessary and slow type-checks
I guess this is not connected to our issue. You're using Clojure's BigInt, which is probably a bit slower than BigInteger if you know you want it to be big: user (class 1N) clojure.lang.BigInt Have you tried translating your Java code directly to see if that helps? On Tue, Jul 2, 2013 at 11:05 AM, Jim - FooBar(); jimpil1...@gmail.comwrote: I'm really sorry for coming back to this but even after everything we learned I'm still not able to get performance equal to java in a simple factorial benchmark. I'd like to think that I'm doing all the correct things to keep the comparison fair...observe this: benchmarks.core= (crit/bench (jf! 50)) WARNING: Final GC required 2.3432463351555 % of runtime Evaluation count : 311580 in 60 samples of 5193 calls. Execution time mean : 196.444969 µs Execution time std-deviation : 10.637274 µs Execution time lower quantile : 194.356268 µs ( 2.5%) Execution time upper quantile : 197.042127 µs (97.5%) Overhead used : 258.723396 ns Found 9 outliers in 60 samples (15. %) low-severe 2 (3. %) low-mild 7 (11.6667 %) Variance from outliers : 40.1247 % Variance is moderately inflated by outliers nil now java: benchmarks.core= (crit/bench (.factorial ^Benchmarks (Benchmarks.) 50)) WARNING: Final GC required 2.656271755497413 % of runtime Evaluation count : 562260 in 60 samples of 9371 calls. Execution time mean : 107.148989 µs Execution time std-deviation : 1.650542 µs Execution time lower quantile : 106.504235 µs ( 2.5%) Execution time upper quantile : 108.934066 µs (97.5%) Overhead used : 258.723396 ns Found 5 outliers in 60 samples (8. %) low-severe 1 (1.6667 %) low-mild 4 (6.6667 %) Variance from outliers : 1.6389 % Variance is slightly inflated by outliers can you spot any differences with this code that would justify needing almost twice as much time? (defn jf! Calculate factorial of n as fast as Java without overflowing. [n] (loop [i (int n) ret 1N] (if (== 1 i) ret (recur (dec i) (* ret i) now java: public BigInteger factorial(final int n){ BigInteger res = BigInteger.valueOf(1L); //build upresult for (int i = n; i 1; i--) res = res.multiply(BigInteger.**valueOf(i)); return res; } I know this is getting ridiculous but I'm preparing a presentation and I was sort of counting on this example...Of course, it goes without saying that I'm using unchecked-math and :jvm-opts ^replace[] . am I doing something wrong? thanks for your time Jim On Fri, 14 Jun 2013 00:11:52 -0700 (PDT) Jason Wolfe ja...@w01fe.com wrote: Thanks for your response. I attempted to answer this in my clarification, but our goal is to attack this 'general advice' and make it possible to get the same speed for array handling in natural-seeming Clojure without writing Java. In particular, we want to create macros that make it easy to achieve maximum performance by putting *your code* for manipulating array elements in the middle of an optimized loop, and this can't be done easily at the library level (as far as I can see) by dropping to Java, since in Java your code would always have to be wrapped in a method invocation with corresponding performance implications. Our previous version of this library (developed for Clojure 1.2, IIRC) was able to get within 0-30% or so of raw Java speed while providing a clean Clojure interface, and we're trying to get back to this point with Clojure 1.5 so we can release it as open-source for everyone to use. -Jason On Friday, June 14, 2013 12:04:12 AM UTC-7, Glen Mailer wrote: This doesn't really answer your question directly, but is there a reason you need to keep this in clojure, or are you just aiming to establish why this is happening? My understanding was that for performance critical code the general advice is to drop down to raw java? Glen -- -- 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+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/** topic/clojure/LTtxhPxH_ws/**unsubscribehttps://groups.google.com/d/topic/clojure/LTtxhPxH_ws/unsubscribe . To unsubscribe from this group and all its topics, send an email to
ANN Elastisch 1.1.1 is released
Elastisch [1] is a minimalistic, feature rich, well documented Clojure client for ElasticSearch. 1.1.1 is a bug fix release. Release notes: http://blog.clojurewerkz.org/blog/2013/07/02/elastisch-1-dot-1-1-is-released/ 1. http://clojureelasticsearch.info -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- 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 Pantomime 1.8.0 is released
Pantomime [1] is a tiny Clojure library that deals with MIME types. Release notes: http://blog.clojurewerkz.org/blog/2013/07/02/pantomime-1-dot-8-0-is-released/ 1. https://github.com/michaelklishin/pantomime -- MK http://github.com/michaelklishin http://twitter.com/michaelklishin -- -- 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: Bounded futures
On Tuesday, July 2, 2013 2:13:04 PM UTC-5, Jim foo.bar wrote: On 02/07/13 20:05, Brian Kirkbride wrote: One thing that I really like about blocking in acquire vs submitting everything to an ExecutorService/CompletionService right off the bat: you can bail out of the remainder of the computation when one part fails. I've got a function that creates a lazy Seq that will become empty if any application of (f x) fails. That means you don't even schedule the remaining items. You can, of course, check and abort inside of (f x) too. But there's a lot to like about not processing those items at all. Especially in composed pipelines of functions. aaa ok now we're getting slightly off just 'mapping'. I thought all you wanted to do was a parallel map - I didn't realise there is more logic to it (aborting and stuff) now it makes sense why you won't like something like this either which can use hundreds of threads no problem :) (- coll (map agent) (map #(send-off % f))) Jim Forget that I mentioned the short-circuiting, it's nice but orthogonal to my question. :) Sure, there are a lot of ways to kick off 100,000 threads in Clojure. Most Clojure examples that I've found of non-CPU-bounded parallelism fire off a future or agent for each item. For reasons in addition to avoiding memory exhaustion, I'd like to avoid that. Dropping down to CompletionService and friends is definitely an option, but my goal was to find a simple and flexible solution implemented (as far as possible) using Clojure primitives. Are most people using Executors for this sort of thing? If so, I'm surprised there isn't some small lib wrapping it up. Any major faults in the Semaphore approach? Did I miss a simpler way to split the work of processing N items over K threads and wait for it? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.comjavascript: wrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.uncomplicate.org/articles/community.html -- -- 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. -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric draga...@gmail.com wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.com wrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.**uncomplicate.orghttp://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If you have any additional suggestion, contact us here: http://fluokitten.**uncomplicate.org/articles/**community.htmlhttp://fluokitten.uncomplicate.org/articles/community.html -- -- 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=enhttp://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wolf...@gmail.com wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric draga...@gmail.com wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.comwrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.**uncomplicate.orghttp://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse existing widespread monadic programming know-how and easily translate it to Clojure code. - Be reasonably easy to learn - the code from the existing books, articles and tutorials for learning monadic programming, which is usually written in Haskell should be easily translatable to Clojure with Fluokitten. - Offer good performance. Please give us your feedback, and we would also love if anyone is willing to help, regardless of previous experience, so please *get involved*. There are lots of things to be improved: - If you are a native English speaker, i would really appreciate if you can help with correcting the English on the Fluokitten site and in the documentation. - Contribute your example code (your own or the ports from Haskell tutorials) to be added to Fluokitten tests. - Contribute articles and tutorials. - Do code review of the Fluokitten code and suggest improvements. - If you find bugs, report them via Fluokitten issue tracker. - If
Re: Microsoft Rx -style operations with core.async
When I first wrote this code, I intentionally avoided any custom syntactical sugar and worked as closely with the primitives as I could. After a few days away, I've used fresh eyes to abstract and revamp. The new code is *dramatically* cleaner and I only needed to introduce a few simple and predictable macros. With regards to my prior feedback: 1) The (let [c chan] (go ...) c) pattern is *extremely-common*. Might be nice to have something like (go-as c ...) that expands to that pattern. I've implemented go-as without buffer parameterization. This was a huge cleanup. 2) It's somewhat annoying to always have to consider boolean false all the time. I've introduced two macros: if-recv and when-recv. (if-recv [x p] ...) is equivalent to (let [x (! p)] (if-not (nil? x) ...)) and when-recv does what you'd expect. Currently, these macros only operate on a single port to read from. I need to give this a bit more thought before I attempt a multiplexing version of this macro. 3) Not mentioned in my prior feedback: Looping receives over a channel is pretty common too. For that, I've got the (dorecv [x port] ...) macro, which is analogous to doseq, but reads from port via ! Similarly, a multiplexing variant of dorecv needs more thought before I attempt that. I think you'll agree that the new code is much nicer looking: https://github.com/brandonbloom/asyncx/blob/89fe35eae8be9a3350855bf841fc11c46ea04b0f/src/asyncx/core.clj (doc strings available for these new macros too) Each one of these primitives is about an order of magnitude more useful than any of the original Rx operators... So I guess that means I can consider this a successful learning experience! In fact, I think these 4 macros might even be useful enough for the core.async namespace after some more field testing. Please let me know if these are helpful to you. I'd also love to know if there are any little patterns or macros like these that you've discovered. Cheers, Brandon -- -- 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: Microsoft Rx -style operations with core.async
These look great! I would, however, avoid using go-as. In the JCSP example a style such as this is prefered most of the time: (defn inc-all increments every int received in the input channel ([in] (let [out (chan)] (inc-all in out) out)) ([in out] (go (while true (! out (inc (! in)) Now users can feel free to supply their own output (and input) channels. This avoids needless copy operations, and allows users to build communication graphs either forwards or backwards. Timothy On Tue, Jul 2, 2013 at 4:12 PM, Brandon Bloom brandon.d.bl...@gmail.comwrote: When I first wrote this code, I intentionally avoided any custom syntactical sugar and worked as closely with the primitives as I could. After a few days away, I've used fresh eyes to abstract and revamp. The new code is *dramatically* cleaner and I only needed to introduce a few simple and predictable macros. With regards to my prior feedback: 1) The (let [c chan] (go ...) c) pattern is *extremely-common*. Might be nice to have something like (go-as c ...) that expands to that pattern. I've implemented go-as without buffer parameterization. This was a huge cleanup. 2) It's somewhat annoying to always have to consider boolean false all the time. I've introduced two macros: if-recv and when-recv. (if-recv [x p] ...) is equivalent to (let [x (! p)] (if-not (nil? x) ...)) and when-recv does what you'd expect. Currently, these macros only operate on a single port to read from. I need to give this a bit more thought before I attempt a multiplexing version of this macro. 3) Not mentioned in my prior feedback: Looping receives over a channel is pretty common too. For that, I've got the (dorecv [x port] ...) macro, which is analogous to doseq, but reads from port via ! Similarly, a multiplexing variant of dorecv needs more thought before I attempt that. I think you'll agree that the new code is much nicer looking: https://github.com/brandonbloom/asyncx/blob/89fe35eae8be9a3350855bf841fc11c46ea04b0f/src/asyncx/core.clj (doc strings available for these new macros too) Each one of these primitives is about an order of magnitude more useful than any of the original Rx operators... So I guess that means I can consider this a successful learning experience! In fact, I think these 4 macros might even be useful enough for the core.async namespace after some more field testing. Please let me know if these are helpful to you. I'd also love to know if there are any little patterns or macros like these that you've discovered. Cheers, Brandon -- -- 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. -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wol...@gmail.comjavascript: wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric drag...@gmail.comjavascript: wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.comwrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.**uncomplicate.orghttp://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and understand Fluokitten like any regular Clojure library. - Fit well into Haskell monadic types conventions - programmers should be able to reuse
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
I wanted to say THE pure function. Now I realize that pure function is ambiguous :) On Wednesday, July 3, 2013 1:03:26 AM UTC+2, Dragan Djuric wrote: pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wol...@gmail.com wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric drag...@gmail.com wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_] (throw-error early exit))) 5) #Either [:left early exit] monads.core (st/run-state (r/run-reader-t (r/t st/m) (tst-reader (fn [env] ( (modify #(assoc % :env env)) (return (dec env) 5) {}) here I am #Pair [4 {:env 5}] monads.core ? On Tue, Jul 2, 2013 at 11:07 AM, Dragan Djuric drag...@gmail.comwrote: I am pleased to announce a first public release of new (and different) monads and friends library for Clojure. Extensive *documentation* is at http://fluokitten.**uncomplicate.orghttp://fluokitten.uncomplicate.org Fluokitten is a Clojure library that implements category theory concepts, such as functors, applicative functors, monads, monoids etc. in idiomatic Clojure. Main project goals are: - Fit well into idiomatic Clojure - Clojure programmers should be able to use and
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
IMO you *always* want the monad to stay the same---the laws describing monadic computations don't account for swapping the things out midstream, at any rate. And it pays to be able to define monadic computations without having to explicitly pass around a token to serve as the current monad. FWIW, you *can* directly translate that function into clojure: monads.core (defn f [g] (comp return g g)) #'monads.core/f monads.core (require '[monads.state :as st]) nil monads.core (st/run-state (= get-state (f inc)) 5) #Pair [7 5] monads.core (require '[monads.list :as l]) nil monads.core (require '[monads.maybe :as m]) nil monads.core (def mc (= (return 3) (f inc))) #'monads.core/mc monads.core (run-monad m/m mc) #Just 5 monads.core (run-monad l/m mc) (5) monads.core (st/run-state mc {}) #Pair [5 {}] You just have to take a different approach to how the results are executed. (This is with this lib: https://github.com/bwo/monads) On Tue, Jul 2, 2013 at 4:03 PM, Dragan Djuric draga...@gmail.com wrote: pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wol...@gmail.com wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric drag...@gmail.com wrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the lack of legacy) to Haskell's categorical stuff. On Tuesday, July 2, 2013 9:15:10 PM UTC+2, Ben wrote: I haven't played around with this but it looks as if the second argument to bind needs to know what kind of monad it's operating in, is that right? Would it be possible to write agnostic functions like this in this lib? monads.core (defn tst-reader [f] (mdo env - ask v - (lift (f env)) (return (println here I am)) (return v))) #'monads.core/tst-reader monads.core (require '[monads.reader :as r] '[monads.identity :as i] '[monads.state :as st] '[monads.error :as e]) nil monads.core (r/run-reader-t (r/t i/m) (tst-reader (comp return inc)) 5) here I am 6 monads.core (r/run-reader-t (r/t e/m) (tst-reader (fn [_]
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
And in this case you have to explicitly specify which monad you want to use, every time you call bind. I understand that in some case it might be a preferred way, but in my opinion for most cases that I care about I prefer it the other way. Regarding monadic laws, which one exactly demands that you cannot change the monad (not counting the fact that haskell's implementation does it that way)? Here are the laws, in Haskell: return a = k = k a m = return= m m = (\x - k x = h) = (m = k) = h It seems to me the laws are still satisfied if you keep changing monads in each bind (if compiler is not restricting it, as is the case with Haskell but not with Clojure). On Wednesday, July 3, 2013 1:19:10 AM UTC+2, Ben wrote: IMO you *always* want the monad to stay the same---the laws describing monadic computations don't account for swapping the things out midstream, at any rate. And it pays to be able to define monadic computations without having to explicitly pass around a token to serve as the current monad. FWIW, you *can* directly translate that function into clojure: monads.core (defn f [g] (comp return g g)) #'monads.core/f monads.core (require '[monads.state :as st]) nil monads.core (st/run-state (= get-state (f inc)) 5) #Pair [7 5] monads.core (require '[monads.list :as l]) nil monads.core (require '[monads.maybe :as m]) nil monads.core (def mc (= (return 3) (f inc))) #'monads.core/mc monads.core (run-monad m/m mc) #Just 5 monads.core (run-monad l/m mc) (5) monads.core (st/run-state mc {}) #Pair [5 {}] You just have to take a different approach to how the results are executed. (This is with this lib: https://github.com/bwo/monads) On Tue, Jul 2, 2013 at 4:03 PM, Dragan Djuric drag...@gmail.comjavascript: wrote: pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson wol...@gmail.com wrote: I did look at the docs and I don't really get how to return a monadic value in the right monad, the way return does automatically. All the examples I saw have something like vector or atom or what-have-you. On Tue, Jul 2, 2013 at 2:41 PM, Dragan Djuric drag...@gmail.comwrote: No, the second argument to bind only needs to be a function that takes a plain value and return a monadic value; you do not need to specify anything explicitly and it does not need to know what kind of monad it is operating on. Whatever that function returns will be a monad that the eventual second bind will operate on. Moreover, Fluokitten supports vararg bind, so the function is actually the last argument of bind in general case; it is the second argument only if there are two args. Please note that Fluokitten does not have a built-in mdo (a syntactic sugar for nested binds) for now. The reason is that Clojure itself has native constructs that do many stuff that Haskell's do does, so I am not yet sure why and if it would be useful, and if I add it how to make it non-awkward. Of course, I am open to suggestions. Also note that Fluokitten is not monad-centric, it has functors, applicatives, etc and I plan to add more categorical concepts, so It is different in that regard from other monadic Clojure libraries. That's why I would like to suggest reading the docs, most of the stuff is significantly different from other libs, and more similar (but simpler, due to the
Re: [ANN] byte-streams: a rosetta stone for all the byte representations the jvm has to offer
Hey Mike, Please feel free to appropriate or adapt any code you think might be useful. I've signed a CA, it should all be kosher. As far as an immutable byte-data type, I'm a little skeptical it would be useful in a wide variety of situations, since a dense array/matrix is going to be much faster and more predictable than pretty much anything else. If you want to guarantee read-only semantics, you have ByteBuffer.asReadOnly(). If you want a ByteBuffer-like interface atop an unbounded stream with memory-efficient subsequences, you can check out the chunked-byte-seqs in Vertigo [1], which is due for release soon. Something which behaves like a Clojure vector but is built atop byte[] seems like it would only be optimal for a very narrow set of use-cases. Maybe I'm misunderstanding what you're proposing, though. Please correct me if that's the case. Zach [1] https://github.com/ztellman/vertigo/blob/master/src/vertigo/bytes.clj#L212 On Tue, Jul 2, 2013 at 3:19 AM, Mikera mike.r.anderson...@gmail.com wrote: This is cool, thanks Zach! Another set of mostly-isomporphic types that this could be applied to is different matrix/array types in core.matrix. core.matrix already has generic conversion mechanisms but they probably aren't as efficient as they could be. I'll take a look and see if the same techniques might be applicable. Quick question for you and the crowd: does there exist or should we build a standard immutable byte data representation for Clojure? I think this is often needed: ByteBuffers and byte[] arrays work well enough but are mutable. Byte sequences are nice and idiomatic but have a lot of overhead, so people are often forced to resort to a variety of other techniques. And it would be nice to support some higher level operations on such types, e.g. production of efficient (non-copying) immutable subsequences. From a data structure perspective, I'm imagining something like a persistent data structure with byte[] data arrays at the lowest level. Given the amount of data-processing stuff people are doing, it seems like a reasonable thing to have in contrib at least? On Saturday, 29 June 2013 18:57:58 UTC+1, Zach Tellman wrote: I've recently been trying to pull out useful pieces from some of my more monolithic libraries. The most recent result is 'byte-streams' [1], a library that figures how how to convert between different byte representations (including character streams), and how to efficiently transfer bytes between various byte sources and sinks. The net result is that you can do something like: (byte-streams/convert (File. /tmp/foo) String {:encoding utf-8}) and get a string representation of the file's contents. Of course, this is already possible using 'slurp', but you could also convert it to a CharSequence, or lazy sequence of ByteBuffers, or pretty much anything else you can imagine. This is accomplished by traversing a graph of available conversions (don't worry, it's memoized), so simply defining a new conversion from some custom type to (say) a ByteBuffer will transitively allow you to convert it to any other type. As an aside, this sort of conversion mechanism isn't limited to just byte representations, but I'm not sure if there's another large collection of mostly-isomorphic types out there that would benefit from this. If anyone has ideas on where else this could be applied, I'd be interested to hear them. Zach [1] https://github.com/**ztellman/byte-streamshttps://github.com/ztellman/byte-streams -- -- 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/SElE2W7bzis/unsubscribe. To unsubscribe from this group and all its topics, 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
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Tue, Jul 2, 2013 at 4:33 PM, Dragan Djuric draga...@gmail.com wrote: And in this case you have to explicitly specify which monad you want to use, every time you call bind. I understand that in some case it might be a preferred way, but in my opinion for most cases that I care about I prefer it the other way. No, you don't. You don't have to specify the monad you want to use until you actually want to use it: ; nREPL 0.1.7 user #Namespace monads.core monads.core (defn mc [x] (= (return x) (fn [a] (= (return (inc a)) (fn [b] (return (+ x (* 2 b #'monads.core/mc monads.core (def m* (mc 5)) #'monads.core/m* monads.core (require '[monads.identity :as i] '[monads.maybe :as m]) nil monads.core (run-monad i/m m*) 17 monads.core (run-monad m/m m*) #Just 17 monads.core m* is already defined in a completely agnostic way before it's run. I thought i had already demonstrated that in my previous email when I defined mc as (= (return 3) (f inc)), prior to interpreting it in the context of any particular monad. Regarding monadic laws, which one exactly demands that you cannot change the monad (not counting the fact that haskell's implementation does it that way)? Here are the laws, in Haskell: return a = k = k a m = return= m m = (\x - k x = h) = (m = k) = h It seems to me the laws are still satisfied if you keep changing monads in each bind (if compiler is not restricting it, as is the case with Haskell but not with Clojure). I suppose that may be right: you're supposed to verify that the laws obtain for a putative monad; they don't come for free just by calling something a monad. Allowing = to have the type m a - (a - n b) - n b just means that you can't verify that yours obeys the laws. If you get to choose the type of return, even the second one is up for grabs! It does seem somewhat odd to me to advertise the package as being familiar to Haskellers and to employ category-theoretic concepts and then to be so blasé about the definition of a monad. (I wonder if you can get away with this changing of type at all if you define bind in terms of fmap and join). On Wednesday, July 3, 2013 1:19:10 AM UTC+2, Ben wrote: IMO you *always* want the monad to stay the same---the laws describing monadic computations don't account for swapping the things out midstream, at any rate. And it pays to be able to define monadic computations without having to explicitly pass around a token to serve as the current monad. FWIW, you *can* directly translate that function into clojure: monads.core (defn f [g] (comp return g g)) #'monads.core/f monads.core (require '[monads.state :as st]) nil monads.core (st/run-state (= get-state (f inc)) 5) #Pair [7 5] monads.core (require '[monads.list :as l]) nil monads.core (require '[monads.maybe :as m]) nil monads.core (def mc (= (return 3) (f inc))) #'monads.core/mc monads.core (run-monad m/m mc) #Just 5 monads.core (run-monad l/m mc) (5) monads.core (st/run-state mc {}) #Pair [5 {}] You just have to take a different approach to how the results are executed. (This is with this lib: https://github.com/bwo/monads) On Tue, Jul 2, 2013 at 4:03 PM, Dragan Djuric drag...@gmail.com wrote: pure function, defined in applicative, is equivalent to return (In Haskell, in Fluokitten there is only pure). I think I understand what is your question now. Since Clojure does not support polymorphysm based on the returning argument you cannot translate that Haskell code exactly. For such a case (when you want to keep operating in the same monad without knowing which one it is), a you have to provide an argument for m in f (but that's how Clojure works :), and then apply it partially or curry it: (defn f [m g] (comp (pure m) g g)) (def c+ (curry +)) (bind [1 2 3] (f [] (c+ 2)) or (= [1 2 3] (f [] (c+ 2)) If [] really hurts your aesthetic views maybe a macro (bind* or mdo) would help, since instead of [], any vector, let's say [1 2 3] would do, but then, it's a special case when you actually want the monad to stay the same. Thank you for helpful comments, BTW :) On Wednesday, July 3, 2013 12:03:45 AM UTC+2, Ben wrote: e.g., I'm not sure how to define the function f here: $ ghci GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude let f :: (Monad m) = (a - a) - a - m a ; f g = return . g . g Prelude Just 4 = f (2+) Just 8 Prelude [[1]] = f (2:) [[2,2,1]] Prelude import Control.Monad.State Prelude Control.Monad.State runState (get = f (+4)) 4 Loading package transformers-0.2.2.0 ... linking ... done. Loading package mtl-2.0.1.0 ... linking ... done. (12,4) Prelude Control.Monad.State On Tue, Jul 2, 2013 at 2:45 PM, Ben Wolfson
Re: [ANN] Fluokitten - Category theory concepts in Clojure - Functors, Applicatives, Monads, Monoids and more
On Tue, Jul 2, 2013 at 5:06 PM, Ben Wolfson wolf...@gmail.com wrote: On Tue, Jul 2, 2013 at 4:33 PM, Dragan Djuric draga...@gmail.com wrote: Regarding monadic laws, which one exactly demands that you cannot change the monad (not counting the fact that haskell's implementation does it that way)? Here are the laws, in Haskell: return a = k = k a m = return= m m = (\x - k x = h) = (m = k) = h It seems to me the laws are still satisfied if you keep changing monads in each bind (if compiler is not restricting it, as is the case with Haskell but not with Clojure). I suppose that may be right: you're supposed to verify that the laws obtain for a putative monad; they don't come for free just by calling something a monad. Allowing = to have the type m a - (a - n b) - n b just means that you can't verify that yours obeys the laws. If you get to choose the type of return, even the second one is up for grabs! It does seem somewhat odd to me to advertise the package as being familiar to Haskellers and to employ category-theoretic concepts and then to be so blasé about the definition of a monad. (I wonder if you can get away with this changing of type at all if you define bind in terms of fmap and join). How are you even supposed to implement bind, in fact? (Never mind reasoning about what's going on in your program if you can't be certain that the code won't switch out the monad you think you're working in, when it does matter to you that you're in a specific one.) Generally for some specific monad you need to do something specific with the return of f. For instance, your seq-bind is implemented in terms of mapcat---meaning that the f that's the second argument of mapcat had better return a seqable. This doesn't work: (mapcat (comp atom inc) '(1 2 3)). -- Ben Wolfson Human kind has used its intelligence to vary the flavour of drinks, which may be sweet, aromatic, fermented or spirit-based. ... Family and social life also offer numerous other occasions to consume drinks for pleasure. [Larousse, Drink entry] -- -- 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 generates unnecessary and slow type-checks
Hi Jim, I cannot reproduce your results. I see Clojure and Java with similar performance when they are both using java.lang.BigInteger. Clojure's arbitrary-precision integer defaults to clojure.lang.BigInt, which in my test is about 12% slower than java.lang.BigInteger. See https://gist.github.com/stuartsierra/5914513 for my code and results. I did not use Criterium or Leiningen to run the benchmark. -S On Tue, Jul 2, 2013 at 2:05 PM, Jim - FooBar(); jimpil1...@gmail.comwrote: I'm really sorry for coming back to this but even after everything we learned I'm still not able to get performance equal to java in a simple factorial benchmark. -- -- 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.
Puppet Labs needs a Clojure developer
Puppet Labs [0] [1] builds open source and commercial systems automation tools. We're in every major linux distribution, and we're managing literally millions of systems at wide variety of shops (from Google to GitHub to Spotify to CERN to Pinterest to NYSE ...). Even if you've not heard of us specifically, chances are very good that you've used a service powered by our tech under-the-hood. We develop open source projects like Puppet [2], MCollective [3], and Facter [4], which help form our automation platform. While much of our current stack is written in Ruby, we've got projects written in Clojure and have plans for more. The biggest one is PuppetDB [5], which I gave a talk on at Clojure/West [6]. PuppetDB is currently deployed in thousands of datacenters all over the planet, helping sysadmins sleep better at night. :) I'm looking for an engineer to work on the existing Clojure projects we have, and help develop new services (and rewrite existing ones) in Clojure. * you should know Clojure (duh) * you should care about reliability and performance * big plus if you can point me at some clojure code you've written * big plus if you are also conversant in Ruby * big plus if you're familiar with Puppet or similar devops tools * as much of the work is open source, big plus if you know your way around github, pull requests, travis-ci, etc. While Puppet Labs is based out of Portland, OR, I don't particularly care where you live as long as your working hours overlap with Pacific time zone. If you'd like to learn more, contact me directly at dee...@puppetlabs.com. Thanks! [0] http://puppetlabs.com [1] http://en.wikipedia.org/wiki/Puppet_Labs [2] https://github.com/puppetlabs/puppet [3] https://github.com/puppetlabs/marionette-collective [4] https://github.com/puppetlabs/facter [5] https://github.com/puppetlabs/puppetdb [6] https://github.com/strangeloop/clojurewest2013/blob/master/slides/sessions/Giridharagopal-PuppetDB.pdf?raw=true -- -- 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: Using core.async to port Clojure to Go
Promises and agents are both fairly straightforward. It's STM and atoms that wouldn't be. But delivering things to blocking channel-gets could be used as a latch to control access to critical sections, so you could probably implement ordinary locks on top of core.async, and locks can then be used to build STM and atoms. So it seems likely it can be done. Whether it's *worth* doing, to implement the other Clojure concurrency structures on top of Go, is another question, and one I'm not qualified to answer. :) On Tue, Jul 2, 2013 at 3:19 PM, Jim - FooBar(); jimpil1...@gmail.comwrote: also what you're asking doesn't really make sensehow would you implement synchronisation primitives (stm atoms promises) on top of asynchronous infrastructure? agents are asynchronous but I haven't got a clue about the potential benefits (or not) of implementing them on top of core.async. Jim On 02/07/13 20:14, Jim - FooBar(); wrote: I've not looked at core.async yet but I'd expect it to build on top of the built-in concurrency primitives and not the other way around... Jim On 02/07/13 20:12, Robert wrote: Are all Clojure concurrency primitives efficiently implementable on top of core.async? If so, could this be used to port Clojure from the JVM/CLR/JS to Go? -- -- 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+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://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+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com . For more options, visit https://groups.google.com/**groups/opt_outhttps://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+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://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+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com . For more options, visit https://groups.google.com/**groups/opt_outhttps://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: core.async implemented on top of Pulsar
On Tue, Jul 2, 2013 at 3:27 PM, pron ron.press...@gmail.com wrote: I do forget the meaning of ! and !; I mean, which is send and which is receive? then I remember, oh, the ! stands for the channel, but again I forget which side of the bang the arrow goes). Bang's always on the right, and the obvious mnemonic is to consider it an arrow pointing to or away from the channel -- to for puts, and away for pulls. -- -- 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.