Can I refer all but specified symbols with 'ns' macro?
Hi group. Assumed that I want to refer 'baz, 'qux and etc and don't want to refer 'quux of 'bar namespace within my 'foo namespace. With 'ns' macro, I can require a namespace and refer all public symbols in it. (ns foo (:require [bar :refer :all])) I can refer only some specific symbols. (ns foo (:require [bar :refer (baz qux)])) Can I refer all but specific symbols? I'm doing (ns foo (:require bar)) (refer 'bar :exclude '(quux)) or (ns foo) (require 'bar) (refer 'bar :exclude '(quux)) for now. Thanks in advance. Y. Kohyama -- -- 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: Can I refer all but specified symbols with 'ns' macro?
I think the way to do it is: (ns foo (:require [bar :refer :all :exclude (quux)])) On 1 August 2013 18:19, Yoshinori Kohyama yykohy...@gmail.com wrote: Hi group. Assumed that I want to refer 'baz, 'qux and etc and don't want to refer 'quux of 'bar namespace within my 'foo namespace. With 'ns' macro, I can require a namespace and refer all public symbols in it. (ns foo (:require [bar :refer :all])) I can refer only some specific symbols. (ns foo (:require [bar :refer (baz qux)])) Can I refer all but specific symbols? I'm doing (ns foo (:require bar)) (refer 'bar :exclude '(quux)) or (ns foo) (require 'bar) (refer 'bar :exclude '(quux)) for now. Thanks in advance. Y. Kohyama -- -- 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: async java.jdbc
What if I want to run a select query in the middle of a transaction? On Thursday, August 1, 2013 3:33:29 AM UTC+9, tbc++ wrote: DB work is a IO operation, and IO shouldn't be done inside a go block (go blocks use limited thread pools). So what about something like this? (defn handle-db [chan] (thread (while true (let [[data result] (! c)] (run-db-transaction-as-normal data) (! result :done) Now spin up a few of these: (def db-chan (let [c (chan 4)] (dotimes [x 4] (handle-db c)) c)) Now it's trivial to use this from a go block: (defn db-async [data] (go (let [c (chan)] (! db-chan [data c]) (! c So this is the pattern: create processors using threads, then send data to those processors via a shared channel, passing in a response channel. Anyways, that's the way I'm thinking these days. Timothy On Wed, Jul 31, 2013 at 12:24 PM, Alice doff...@gmail.com javascript:wrote: I have an async http handler and I don't want it to consume a thread. On Thursday, August 1, 2013 3:16:52 AM UTC+9, tbc++ wrote: Why not use !! ? Timothy On Wed, Jul 31, 2013 at 11:58 AM, Alice doff...@gmail.com wrote: It doesn't produce a compile time error but I think it's not the correct code because the transaction can be committed while insert-async! is still executing. On Thursday, August 1, 2013 2:46:29 AM UTC+9, Sean Corfield wrote: On Wed, Jul 31, 2013 at 10:29 AM, Alice doff...@gmail.com wrote: (go (jdbc/db-transaction [t-con db-spec] (! (insert-async! t-con :fruit {:name apple} Does this work: (jdbc/db-transaction [t-con db-spec] (go (! (insert-async! t-con :fruit {:name apple} -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- -- 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 the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@**googlegroups.com. For more options, visit https://groups.google.com/**groups/opt_outhttps://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 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. -- “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: In-order triggering of watches on mutable state
Try using an agent send from inside a transaction. Such sends are only dispatched if the transaction commits, and successive sends to the same agent from a single thread are run by the agent in the same order the thread sent them. On Wed, Jul 31, 2013 at 1:12 PM, Mike Drogalis madrush...@gmail.com wrote: Good reasoning; that makes a lot of sense -- even if intuitively it doesn't follow through. I'll do some more thinking about my concurrency needs and come back with a follow up question later. Thanks man! On Wed, Jul 31, 2013 at 12:51 PM, Timothy Baldridge tbaldri...@gmail.comwrote: Deadlocks? Imagine a watch that ended up running a transaction against the ref it was triggered from. Sounds insane, but it could be fairly easy to do in a situation like this: ref - calls watchers - calls fn1 - calls fn 2 - calls fn3 - starts transaction on ref Since watchers are notified outside of a ref transaction deadlocking is impossible. Inside a transaction you'd have a instant deadlock. Timothy Baldridge On Wed, Jul 31, 2013 at 10:47 AM, Mike Drogalis madrush...@gmail.comwrote: I'll play around with agents for this when I get some more free time. I find it odd that, as the sole perceiver of an indentity, events are capable of being perceived out of order. If I were watching a line queue up in person, events are obviously dispatched in order through my visual perception. I trust there's a good reason it's designed this way, at any rate. On Wed, Jul 31, 2013 at 12:25 PM, Timothy Baldridge tbaldri...@gmail.com wrote: You might want to consider switching to agents (or something else) I don't think it's possible to do what you want with refs. Timothy Baldridge On Wed, Jul 31, 2013 at 10:08 AM, Mike Drogalis madrush...@gmail.comwrote: Thanks for the link. :) I understand that the behavior I'm seeing is correct. Any idea how to achieve the desired behavior, though? On Wed, Jul 31, 2013 at 12:06 PM, Timothy Baldridge tbaldri...@gmail.com wrote: The answer is here: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LockingTransaction.java#L361 Agents and watches are dispatched outside of the transaction locking. This means that multiple transactions could be executing watches in parallel, and hence execute out of order. Timothy Baldridge On Wed, Jul 31, 2013 at 9:43 AM, Michael Drogalis madrush...@gmail.com wrote: I can precisely exemplify the behavior here: https://gist.github.com/MichaelDrogalis/6123177 On Wednesday, July 31, 2013 11:13:17 AM UTC-4, Michael Drogalis wrote: Aaron: Yep, I'm aware - and am using the value provided by the last parameter. This is going to be tough to show the problem without bringing more details of my concurrency set up. I'm not sure if this will exhibit the problem, but this is what it boils down to: https://gist.github.com/**MichaelDrogalis/6122834https://gist.github.com/MichaelDrogalis/6122834 When enough threads are trying to write to the queue, the watches triggered later can finish before watches triggered earlier. On Wednesday, July 31, 2013 11:05:16 AM UTC-4, Aaron Cohen wrote: A watcher fn has 4 parameters: key, reference, old-state, new-state If you use old-state and new-state rather than the reference, you should not see your problem. --Aaron On Wed, Jul 31, 2013 at 11:00 AM, Michael Drogalis madru...@gmail.com wrote: Problem: I have a ref representing a queue of people in line. I add a watch to the ref to print out the contents of the queue whenever it changes. Naturally, and expected, the following can happen if queuing happens in rapid succession: Queue: [] add Mike to queue add John to queue console: Queue is Mike, John console: Queue is Mike I'd like to write a UI for this program, but I clearly can't reliably render based on the result delivered by the add-watch hook. What's the solution for this problem? -- -- 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 the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com. For more options, visit https://groups.google.com/** groups/opt_out 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
core.async: faulty rebinding of loop-bindings in go blocks
There seems to be an issue with the rebinding of loop-bindings using loop/recur in go blocks, specifically when you are just changing the order of the original bindings in a recur call. Take this snippet for example: (require '[clojure.core.async :refer [go timeout]]) (go (loop [a :black, b :white] (println a b) (! (timeout 1000)) (recur b a))) Instead of repeatedly printing :black :white :white :black :black :white :white :black (...) it actually prints :black :white :white :white :white :white :white :white (...) Note however, that (require '[clojure.core.async :refer [go timeout]]) (go (loop [a :black, b :white] (println a b) (! (timeout 1000)) (recur (identity b) (identity a works correctly. Any ideas as to what's causing this? Cheers, Kevin -- -- 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: throwing an exception into the channel
throw! is an explicit operation, and there's no special channel states involved. It's passing an exception like other data that just automatically throws it when taken. So it won't hurt anybody. You can use it when you need it, you can ignore it if you don't need it. Yet, it makes using async functions look almost identical to the sync functions. On Thursday, August 1, 2013 3:37:51 AM UTC+9, tbc++ wrote: The position of core.async is to not specify how exceptions should be done (instead leaving it up to the user). So if that method works well for you, write some macros and use it! Other methods may be the use of supervisor channels. In this model, go blocks that die would enqueue the exception into a global (or shared) channel and the go block would then be re-started by a monitor process. Both methods (and may more) are supported by core.async...it simply doesn't care how you handle exceptions, but it is up to you to specify how they are handled. Timothy On Wed, Jul 31, 2013 at 11:49 AM, Alice doff...@gmail.com javascript:wrote: It would be nice to have a function throw! that puts an exception into the channel and throws it when taken, so that I can write (let [c (chan)] (go (throw! c (Exception.))) (go (try (prn (! c)) (catch Throwable t (prn exception) instead of (let [c (chan)] (go (! c (Exception.))) (go (try (let [res (! c)] (if (instance? Throwable res) (throw res) (prn res))) (catch Throwable t (prn exception) -- -- 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. -- “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: Can I refer all but specified symbols with 'ns' macro?
Carlo, Works fine. Thank you! Y. Kohyama -- -- 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: In-order triggering of watches on mutable state
Cedric: Will agents give me the guarantee that if I have something in Agent A, and I want to move it to agent B, and I do this inside a transaction: - perceivers will see it in A at read point - perceivers will see it in B at write point - perceivers will never see it in neither nor both? If that's the case, which is effectively synchronous coordination (I think?), what do refs buy you that agents don't? On Thu, Aug 1, 2013 at 5:57 AM, Cedric Greevey cgree...@gmail.com wrote: Try using an agent send from inside a transaction. Such sends are only dispatched if the transaction commits, and successive sends to the same agent from a single thread are run by the agent in the same order the thread sent them. On Wed, Jul 31, 2013 at 1:12 PM, Mike Drogalis madrush...@gmail.comwrote: Good reasoning; that makes a lot of sense -- even if intuitively it doesn't follow through. I'll do some more thinking about my concurrency needs and come back with a follow up question later. Thanks man! On Wed, Jul 31, 2013 at 12:51 PM, Timothy Baldridge tbaldri...@gmail.com wrote: Deadlocks? Imagine a watch that ended up running a transaction against the ref it was triggered from. Sounds insane, but it could be fairly easy to do in a situation like this: ref - calls watchers - calls fn1 - calls fn 2 - calls fn3 - starts transaction on ref Since watchers are notified outside of a ref transaction deadlocking is impossible. Inside a transaction you'd have a instant deadlock. Timothy Baldridge On Wed, Jul 31, 2013 at 10:47 AM, Mike Drogalis madrush...@gmail.comwrote: I'll play around with agents for this when I get some more free time. I find it odd that, as the sole perceiver of an indentity, events are capable of being perceived out of order. If I were watching a line queue up in person, events are obviously dispatched in order through my visual perception. I trust there's a good reason it's designed this way, at any rate. On Wed, Jul 31, 2013 at 12:25 PM, Timothy Baldridge tbaldri...@gmail.com wrote: You might want to consider switching to agents (or something else) I don't think it's possible to do what you want with refs. Timothy Baldridge On Wed, Jul 31, 2013 at 10:08 AM, Mike Drogalis madrush...@gmail.comwrote: Thanks for the link. :) I understand that the behavior I'm seeing is correct. Any idea how to achieve the desired behavior, though? On Wed, Jul 31, 2013 at 12:06 PM, Timothy Baldridge tbaldri...@gmail.com wrote: The answer is here: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LockingTransaction.java#L361 Agents and watches are dispatched outside of the transaction locking. This means that multiple transactions could be executing watches in parallel, and hence execute out of order. Timothy Baldridge On Wed, Jul 31, 2013 at 9:43 AM, Michael Drogalis madrush...@gmail.com wrote: I can precisely exemplify the behavior here: https://gist.github.com/MichaelDrogalis/6123177 On Wednesday, July 31, 2013 11:13:17 AM UTC-4, Michael Drogalis wrote: Aaron: Yep, I'm aware - and am using the value provided by the last parameter. This is going to be tough to show the problem without bringing more details of my concurrency set up. I'm not sure if this will exhibit the problem, but this is what it boils down to: https://gist.github.com/**MichaelDrogalis/6122834https://gist.github.com/MichaelDrogalis/6122834 When enough threads are trying to write to the queue, the watches triggered later can finish before watches triggered earlier. On Wednesday, July 31, 2013 11:05:16 AM UTC-4, Aaron Cohen wrote: A watcher fn has 4 parameters: key, reference, old-state, new-state If you use old-state and new-state rather than the reference, you should not see your problem. --Aaron On Wed, Jul 31, 2013 at 11:00 AM, Michael Drogalis madru...@gmail.com wrote: Problem: I have a ref representing a queue of people in line. I add a watch to the ref to print out the contents of the queue whenever it changes. Naturally, and expected, the following can happen if queuing happens in rapid succession: Queue: [] add Mike to queue add John to queue console: Queue is Mike, John console: Queue is Mike I'd like to write a UI for this program, but I clearly can't reliably render based on the result delivered by the add-watch hook. What's the solution for this problem? -- -- 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 the Google Groups Clojure
Re: core.async: throwing an exception into the channel
I think I'd rather see separate functions or macros for consuming from a channel with the maybe throw behavior rather than having the standard consume form(s) come with that feature (or threat, depending on whether you want it). At that point you're back to the earlier advice to wrap core.async to fit your approach. As new as core.async is to the Clojure community, it seems premature to build in an error-handling approach that may turn out not to be appropriate for many users. On Aug 1, 2013 5:19 AM, Alice dofflt...@gmail.com wrote: throw! is an explicit operation, and there's no special channel states involved. It's passing an exception like other data that just automatically throws it when taken. So it won't hurt anybody. You can use it when you need it, you can ignore it if you don't need it. Yet, it makes using async functions look almost identical to the sync functions. On Thursday, August 1, 2013 3:37:51 AM UTC+9, tbc++ wrote: The position of core.async is to not specify how exceptions should be done (instead leaving it up to the user). So if that method works well for you, write some macros and use it! Other methods may be the use of supervisor channels. In this model, go blocks that die would enqueue the exception into a global (or shared) channel and the go block would then be re-started by a monitor process. Both methods (and may more) are supported by core.async...it simply doesn't care how you handle exceptions, but it is up to you to specify how they are handled. Timothy On Wed, Jul 31, 2013 at 11:49 AM, Alice doff...@gmail.com wrote: It would be nice to have a function throw! that puts an exception into the channel and throws it when taken, so that I can write (let [c (chan)] (go (throw! c (Exception.))) (go (try (prn (! c)) (catch Throwable t (prn exception) instead of (let [c (chan)] (go (! c (Exception.))) (go (try (let [res (! c)] (if (instance? Throwable res) (throw res) (prn res))) (catch Throwable t (prn exception) -- -- 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 the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@**googlegroups.com. For more options, visit https://groups.google.com/**groups/opt_outhttps://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. -- -- 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: In-order triggering of watches on mutable state
Try using an agent send from inside a transaction. Such sends are only dispatched if the transaction commits, and successive sends to the same agent from a single thread are run by the agent in the same order the thread sent them. That's not the problem. The problem is that agent sends (just like watchers) are dispatched outside of the transaction. So multiple threads accessing the same refs can be releasing sends to agents at the same time. This in turn means that the messages being sent to the agents can arrive out-of-order since one thread could pause allowing the other to send messages. Something to think about though is that you probably should be dealing with commutative operations. So instead of sending set bank account to X to refs/agents, instead send increment bank account by 10. In this way many of these race-conditions no longer exist. Timothy On Thu, Aug 1, 2013 at 6:54 AM, Mike Drogalis madrush...@gmail.com wrote: Cedric: Will agents give me the guarantee that if I have something in Agent A, and I want to move it to agent B, and I do this inside a transaction: - perceivers will see it in A at read point - perceivers will see it in B at write point - perceivers will never see it in neither nor both? If that's the case, which is effectively synchronous coordination (I think?), what do refs buy you that agents don't? On Thu, Aug 1, 2013 at 5:57 AM, Cedric Greevey cgree...@gmail.com wrote: Try using an agent send from inside a transaction. Such sends are only dispatched if the transaction commits, and successive sends to the same agent from a single thread are run by the agent in the same order the thread sent them. On Wed, Jul 31, 2013 at 1:12 PM, Mike Drogalis madrush...@gmail.comwrote: Good reasoning; that makes a lot of sense -- even if intuitively it doesn't follow through. I'll do some more thinking about my concurrency needs and come back with a follow up question later. Thanks man! On Wed, Jul 31, 2013 at 12:51 PM, Timothy Baldridge tbaldri...@gmail.com wrote: Deadlocks? Imagine a watch that ended up running a transaction against the ref it was triggered from. Sounds insane, but it could be fairly easy to do in a situation like this: ref - calls watchers - calls fn1 - calls fn 2 - calls fn3 - starts transaction on ref Since watchers are notified outside of a ref transaction deadlocking is impossible. Inside a transaction you'd have a instant deadlock. Timothy Baldridge On Wed, Jul 31, 2013 at 10:47 AM, Mike Drogalis madrush...@gmail.comwrote: I'll play around with agents for this when I get some more free time. I find it odd that, as the sole perceiver of an indentity, events are capable of being perceived out of order. If I were watching a line queue up in person, events are obviously dispatched in order through my visual perception. I trust there's a good reason it's designed this way, at any rate. On Wed, Jul 31, 2013 at 12:25 PM, Timothy Baldridge tbaldri...@gmail.com wrote: You might want to consider switching to agents (or something else) I don't think it's possible to do what you want with refs. Timothy Baldridge On Wed, Jul 31, 2013 at 10:08 AM, Mike Drogalis madrush...@gmail.com wrote: Thanks for the link. :) I understand that the behavior I'm seeing is correct. Any idea how to achieve the desired behavior, though? On Wed, Jul 31, 2013 at 12:06 PM, Timothy Baldridge tbaldri...@gmail.com wrote: The answer is here: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LockingTransaction.java#L361 Agents and watches are dispatched outside of the transaction locking. This means that multiple transactions could be executing watches in parallel, and hence execute out of order. Timothy Baldridge On Wed, Jul 31, 2013 at 9:43 AM, Michael Drogalis madrush...@gmail.com wrote: I can precisely exemplify the behavior here: https://gist.github.com/MichaelDrogalis/6123177 On Wednesday, July 31, 2013 11:13:17 AM UTC-4, Michael Drogalis wrote: Aaron: Yep, I'm aware - and am using the value provided by the last parameter. This is going to be tough to show the problem without bringing more details of my concurrency set up. I'm not sure if this will exhibit the problem, but this is what it boils down to: https://gist.github.com/**MichaelDrogalis/6122834https://gist.github.com/MichaelDrogalis/6122834 When enough threads are trying to write to the queue, the watches triggered later can finish before watches triggered earlier. On Wednesday, July 31, 2013 11:05:16 AM UTC-4, Aaron Cohen wrote: A watcher fn has 4 parameters: key, reference, old-state, new-state If you use old-state and new-state rather than the reference, you should not see your problem. --Aaron On Wed, Jul 31, 2013 at 11:00 AM, Michael Drogalis madru...@gmail.com wrote: Problem: I have a ref representing a queue of people in line. I add a watch to the ref to print out the contents
[ANN] Tawny-OWL 0.12
I am pleased to announce the release of tawny-owl, Version 0.12. This package allows users to construct OWL ontologies in a fully programmatic environment, namely Clojure. This means the user can take advantage of programmatic language to automate and abstract the ontology over the development process; also, rather than requiring the creation of ontology specific development environments, a normal programming IDE can be used; finally, a human readable text format means that we can integrate with the standard tooling for versioning and distributed development. OWL is a W3C standard ontology representation language; an ontology is a fully computable set of statements, describing the things and their relationships. These statements can be reasoned over, inferences made and contradictions detected automatically using an off-the-shelf reasoner. 0.12 is planned to be the final, feature complete release before the 1.0 release. New features will not be added before 1.0. Key new features in 0.12 are: - Complete support for OWL 2, include data types - OWL documentation can be queries as normal clojure metadata - New namespaces, query and fixture - Completion of rendering functionality - Regularisation of interfaces: where relevant functions now take an ontology as the first argument. - Updated to Hermit 1.3.7.3, OWL API 3.4.5 Tawny is available at https://github.com/phillord/tawny-owl, or as a maven artifact from http://clojars.org. The development of tawny-owl is documented in my journal at http://www.russet.org.uk/blog/category/all/professional/tech/tawny-owl -- -- 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: In-order triggering of watches on mutable state
Unfortunately, my problem is not one where the operation is communitive. To be concrete, I am dealing with multiple threads plucking elements off the top of many different queues, and putting them into a new queue. So adding element A, then B results in line [A, B], whereas adding element B, then A results in line [B, A], which aren't equal. Maybe I'm misunderstanding my problem, perhaps it is communitive. I just don't see it though. On Thu, Aug 1, 2013 at 9:13 AM, Timothy Baldridge tbaldri...@gmail.comwrote: Try using an agent send from inside a transaction. Such sends are only dispatched if the transaction commits, and successive sends to the same agent from a single thread are run by the agent in the same order the thread sent them. That's not the problem. The problem is that agent sends (just like watchers) are dispatched outside of the transaction. So multiple threads accessing the same refs can be releasing sends to agents at the same time. This in turn means that the messages being sent to the agents can arrive out-of-order since one thread could pause allowing the other to send messages. Something to think about though is that you probably should be dealing with commutative operations. So instead of sending set bank account to X to refs/agents, instead send increment bank account by 10. In this way many of these race-conditions no longer exist. Timothy On Thu, Aug 1, 2013 at 6:54 AM, Mike Drogalis madrush...@gmail.comwrote: Cedric: Will agents give me the guarantee that if I have something in Agent A, and I want to move it to agent B, and I do this inside a transaction: - perceivers will see it in A at read point - perceivers will see it in B at write point - perceivers will never see it in neither nor both? If that's the case, which is effectively synchronous coordination (I think?), what do refs buy you that agents don't? On Thu, Aug 1, 2013 at 5:57 AM, Cedric Greevey cgree...@gmail.comwrote: Try using an agent send from inside a transaction. Such sends are only dispatched if the transaction commits, and successive sends to the same agent from a single thread are run by the agent in the same order the thread sent them. On Wed, Jul 31, 2013 at 1:12 PM, Mike Drogalis madrush...@gmail.comwrote: Good reasoning; that makes a lot of sense -- even if intuitively it doesn't follow through. I'll do some more thinking about my concurrency needs and come back with a follow up question later. Thanks man! On Wed, Jul 31, 2013 at 12:51 PM, Timothy Baldridge tbaldri...@gmail.com wrote: Deadlocks? Imagine a watch that ended up running a transaction against the ref it was triggered from. Sounds insane, but it could be fairly easy to do in a situation like this: ref - calls watchers - calls fn1 - calls fn 2 - calls fn3 - starts transaction on ref Since watchers are notified outside of a ref transaction deadlocking is impossible. Inside a transaction you'd have a instant deadlock. Timothy Baldridge On Wed, Jul 31, 2013 at 10:47 AM, Mike Drogalis madrush...@gmail.comwrote: I'll play around with agents for this when I get some more free time. I find it odd that, as the sole perceiver of an indentity, events are capable of being perceived out of order. If I were watching a line queue up in person, events are obviously dispatched in order through my visual perception. I trust there's a good reason it's designed this way, at any rate. On Wed, Jul 31, 2013 at 12:25 PM, Timothy Baldridge tbaldri...@gmail.com wrote: You might want to consider switching to agents (or something else) I don't think it's possible to do what you want with refs. Timothy Baldridge On Wed, Jul 31, 2013 at 10:08 AM, Mike Drogalis madrush...@gmail.com wrote: Thanks for the link. :) I understand that the behavior I'm seeing is correct. Any idea how to achieve the desired behavior, though? On Wed, Jul 31, 2013 at 12:06 PM, Timothy Baldridge tbaldri...@gmail.com wrote: The answer is here: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LockingTransaction.java#L361 Agents and watches are dispatched outside of the transaction locking. This means that multiple transactions could be executing watches in parallel, and hence execute out of order. Timothy Baldridge On Wed, Jul 31, 2013 at 9:43 AM, Michael Drogalis madrush...@gmail.com wrote: I can precisely exemplify the behavior here: https://gist.github.com/MichaelDrogalis/6123177 On Wednesday, July 31, 2013 11:13:17 AM UTC-4, Michael Drogalis wrote: Aaron: Yep, I'm aware - and am using the value provided by the last parameter. This is going to be tough to show the problem without bringing more details of my concurrency set up. I'm not sure if this will exhibit the problem, but this is what it boils down to: https://gist.github.com/**MichaelDrogalis/6122834https://gist.github.com/MichaelDrogalis/6122834 When enough threads are trying to write
[GSoC] core.matrix NDArray: after the first half
So it's the mid-point of GSoC and a good time to review what's already done and what is yet to be done. The main focus of first half of the summer was making NDArray work. NDArray is a new implementation of core.matrix protocols, intended to become the default one. It's implemented in pure Clojure as strided array over flat Java arrays, similar to NumPy's NDArray. Well, it works. Some highlights: - It works as as fully functional, N-dimensional array as part of core.matrix - It passes all current tests - A few bugs were fixed in core.matrix itself, uncovered during implementation testing. - An overview of implemented protocols is now generated from the code directly as html page and can be seen at [1]. - Some of the default implementations within core.matrix have been rewritten to be faster and use NDArray internally where it's appropriate. You can find examples of NDArray usage at [2]. An important issue in such libraries is performance. The first and most obvious step to win some is to use specialized primitive arrays instead of Object one; the trouble is that most of the code is duplicated many times. Clojure, with it's homoiconicity and ease of code juggling, is a big win here — after introduction of some magic main implementation of ndarray is almost completely free of boring repetition [3], despite generating code for 4 different types (and it's easily extensible). Then it's time for type hinting, little gory details of hidden type coercion, playing with memory access patterns. Matrix multiplication was a very important playground for me: it's fairly easy on the surface, well studied and easily checkable. Moreover, I have a reference point: Mike Anderson's Vectorz library [4]. After some time I've managed to beat it, at least at large matrices [5] (look at ndarray-double; ndarray now uses default implementation, which was based on persistent vectors in the past and became 2-3x faster after rewrite). There is plenty of room for improvement on small matrices, though. I'm writing a big post on this optimization experience, stay tuned :) What's next? A couple of interesting problems/tasks still await: - a lot of elementwise operations are very repetitive in code and are differentiated one from another only because of performance overhead of map-like dynamic solutions. They should really be a macro in case of NDArray; and what stops us from exposing this macro through an API so users can write very efficient custom elementwise operations? AFAIK, nothing. I'm very curious about how far this approach can be pushed. - for now there are some repetitive patterns with iterating index-wise over array and finding true index inside it by multiplicating indexes by strides. First benchmarks show that rewriting this loops to count true index, stepping by stride instead of by one, is beneficial to performance. An open question is whether it's possible to hide this in code generation without significantly hurting readability of code. - can we come up with better way to slice arrays in arbitrary ways (boolean vectors? boolean functions?) and in the same time make it efficient? - how hard it would be to port all this to CLJS and be efficient there too? Of course, there is also a huge pile of more mundane, but even more important work: documentation (will need to patch Marginalia, I suppose), tests (I'm very happy that simple-check [6] already exists, property-based testing is a giant leap forward, too often overlooked), infrastructure (currently I'm trying to find the best format to present performance test results at HTML page) and more optimization/protocol reimplementation. It has been a very interesting experience to day to work full-time on an open-source library. It was not so glossy and bleeding-edge, making the library work faster and more correct, but definitely very interesting. I've learned a lot about numerical programming and Clojure; I'm very pleased by a raise in my Clojure productivity during this project so far. It was also very enjoyable to work with my mentor, Mike Anderson. I'm looking forward to push core.matrix as far as I can during the time left. [1]: http://mikera.github.io/matrix-api/summary.html [2]: https://gist.github.com/si14/6131125 [3]: https://github.com/mikera/matrix-api/blob/develop/src/main/clojure/clojure/core/matrix/impl/ndarray.clj [4]: https://github.com/mikera/vectorz/ [5]: https://gist.github.com/si14/6127020 [6]: https://github.com/reiddraper/simple-check -- -- 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
Re: In-order triggering of watches on mutable state
Ding! You said the magic words! For queues, can I recommend one of the following? http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html According to Rich why doesn't Clojure provide queues? The Java ones are just fine! Use them Also, if you have a large number of queues and don't want to tie up threads, have a look a core.async (http://github.com/clojure/core.async) it's designed exactly for this sort of thing. With either of these you may still have some fun with having shared state between the threads, but perhaps these approaches may help a bit. Timothy On Thu, Aug 1, 2013 at 7:21 AM, Mike Drogalis madrush...@gmail.com wrote: Unfortunately, my problem is not one where the operation is communitive. To be concrete, I am dealing with multiple threads plucking elements off the top of many different queues, and putting them into a new queue. So adding element A, then B results in line [A, B], whereas adding element B, then A results in line [B, A], which aren't equal. Maybe I'm misunderstanding my problem, perhaps it is communitive. I just don't see it though. On Thu, Aug 1, 2013 at 9:13 AM, Timothy Baldridge tbaldri...@gmail.comwrote: Try using an agent send from inside a transaction. Such sends are only dispatched if the transaction commits, and successive sends to the same agent from a single thread are run by the agent in the same order the thread sent them. That's not the problem. The problem is that agent sends (just like watchers) are dispatched outside of the transaction. So multiple threads accessing the same refs can be releasing sends to agents at the same time. This in turn means that the messages being sent to the agents can arrive out-of-order since one thread could pause allowing the other to send messages. Something to think about though is that you probably should be dealing with commutative operations. So instead of sending set bank account to X to refs/agents, instead send increment bank account by 10. In this way many of these race-conditions no longer exist. Timothy On Thu, Aug 1, 2013 at 6:54 AM, Mike Drogalis madrush...@gmail.comwrote: Cedric: Will agents give me the guarantee that if I have something in Agent A, and I want to move it to agent B, and I do this inside a transaction: - perceivers will see it in A at read point - perceivers will see it in B at write point - perceivers will never see it in neither nor both? If that's the case, which is effectively synchronous coordination (I think?), what do refs buy you that agents don't? On Thu, Aug 1, 2013 at 5:57 AM, Cedric Greevey cgree...@gmail.comwrote: Try using an agent send from inside a transaction. Such sends are only dispatched if the transaction commits, and successive sends to the same agent from a single thread are run by the agent in the same order the thread sent them. On Wed, Jul 31, 2013 at 1:12 PM, Mike Drogalis madrush...@gmail.comwrote: Good reasoning; that makes a lot of sense -- even if intuitively it doesn't follow through. I'll do some more thinking about my concurrency needs and come back with a follow up question later. Thanks man! On Wed, Jul 31, 2013 at 12:51 PM, Timothy Baldridge tbaldri...@gmail.com wrote: Deadlocks? Imagine a watch that ended up running a transaction against the ref it was triggered from. Sounds insane, but it could be fairly easy to do in a situation like this: ref - calls watchers - calls fn1 - calls fn 2 - calls fn3 - starts transaction on ref Since watchers are notified outside of a ref transaction deadlocking is impossible. Inside a transaction you'd have a instant deadlock. Timothy Baldridge On Wed, Jul 31, 2013 at 10:47 AM, Mike Drogalis madrush...@gmail.com wrote: I'll play around with agents for this when I get some more free time. I find it odd that, as the sole perceiver of an indentity, events are capable of being perceived out of order. If I were watching a line queue up in person, events are obviously dispatched in order through my visual perception. I trust there's a good reason it's designed this way, at any rate. On Wed, Jul 31, 2013 at 12:25 PM, Timothy Baldridge tbaldri...@gmail.com wrote: You might want to consider switching to agents (or something else) I don't think it's possible to do what you want with refs. Timothy Baldridge On Wed, Jul 31, 2013 at 10:08 AM, Mike Drogalis madrush...@gmail.com wrote: Thanks for the link. :) I understand that the behavior I'm seeing is correct. Any idea how to achieve the desired behavior, though? On Wed, Jul 31, 2013 at 12:06 PM, Timothy Baldridge tbaldri...@gmail.com wrote: The answer is here: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LockingTransaction.java#L361 Agents and watches are dispatched outside of the transaction locking. This means that multiple transactions could be executing watches in parallel, and hence execute out of order.
[ANN] Immutant 1.0.0 released
Today we finally released Immutant 1.0.0! Read about it here: http://bit.ly/imm100 For those unfamiliar, Immutant is an application server for Clojure. It's an integrated platform providing web, messaging, caching, scheduling, XA transactions, clustering, and daemons built on JBoss AS7 that aims to reduce the incidental complexity found in real-world applications. Have fun! 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.
RPC over channels
With core.async, cljzmq https://github.com/zeromq/cljzmq, and now zmq-async https://github.com/lynaghk/zmq-async, there's an opportunity to link RPC to channels and be free of the underlying transport system. I'm proposing an RPC library that sends and receives data over channels. The idea is to have a two-way communication context as a map with a send-channel, receive-channel, serializer, and deserializer. The user would be responsible for the transport mechanism between the client and the server. When a user makes a request, the library would create a map to follow the JSON-RPC http://www.jsonrpc.org/specification and attach a UUID to it then send it down the send-channel. This UUID could be used in conjunction with pulling items off of the receive-channel to handle responses. The data flow would be: user-request - wrap-in-specification - client-serializer - client-send-channel - transport-provider - server deserializer - server-receive-channel - user-function - server-serializer - server-send-channel - transport-provider - client-deserializer - unwrap-specification - client-receive-channel - user-response-handling. The library would be responsible for wrapping the requests and responses according to the specification, but not the serialization mechanism nor the transport, since those could be very different depending on the problem. Utilities could be provided for a blocking call and managing cycling through responses on the receive-channel in order to find a specific response that has not yet been processed. As an example, the above workflow should be able to work seamlessly with the channels provided by zmq-async. The send-channels provided would be used as is, and the receive-channels would be used with an additional channel outside of it to take the responses off and deserialize them before returning to the user. The transport provider, of course, would be ZeroMQ. Are there any projects already doing this? Would people be interested? Any feedback? -ToBeReplaced -- -- 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: async java.jdbc
These are interesting code listings and questions, but they conflate the syntactic detail that core.async's go is implemented as a macro, with the semantic intention to support designs around lightweight data flow between independent code blocks. It might be of value to check out Go, the language, with its channels and go-routines, which were part of the inspiration for core.async. In Go, channels and go-routines are language rather than library features. Go also lacks macros. In that context, answers to these questions are clear: e.g. if you want to run an insert asynchronously and then run a select following the insert in the context of the same transaction, the only way to do it looks like Timothy's example, where the code implements a data flow- the particular data to insert and select is sent over a channel, handled by a function running in a go routine whose semantic purpose is to wait on an input channel, do the database operation, and stick the result on an output channel. From on the other thread, Go doesn't have exceptions, but error handling between go routines is usually handled with a separate error channel that again serves to support data flow, rather than control flow. Similarly, the reason that a special channel-aware throw wasn't included in core.async is that the idea isn't to use go blocks in a lexical, control-flow sense- even though that's what the implementation expands to- it's to support completely different data-flow oriented designs. Hope that helps... On Thu, Aug 1, 2013 at 5:57 AM, Alice dofflt...@gmail.com wrote: What if I want to run a select query in the middle of a transaction? On Thursday, August 1, 2013 3:33:29 AM UTC+9, tbc++ wrote: DB work is a IO operation, and IO shouldn't be done inside a go block (go blocks use limited thread pools). So what about something like this? (defn handle-db [chan] (thread (while true (let [[data result] (! c)] (run-db-transaction-as-normal data) (! result :done) Now spin up a few of these: (def db-chan (let [c (chan 4)] (dotimes [x 4] (handle-db c)) c)) Now it's trivial to use this from a go block: (defn db-async [data] (go (let [c (chan)] (! db-chan [data c]) (! c So this is the pattern: create processors using threads, then send data to those processors via a shared channel, passing in a response channel. Anyways, that's the way I'm thinking these days. Timothy On Wed, Jul 31, 2013 at 12:24 PM, Alice doff...@gmail.com wrote: I have an async http handler and I don't want it to consume a thread. On Thursday, August 1, 2013 3:16:52 AM UTC+9, tbc++ wrote: Why not use !! ? Timothy On Wed, Jul 31, 2013 at 11:58 AM, Alice doff...@gmail.com wrote: It doesn't produce a compile time error but I think it's not the correct code because the transaction can be committed while insert-async! is still executing. On Thursday, August 1, 2013 2:46:29 AM UTC+9, Sean Corfield wrote: On Wed, Jul 31, 2013 at 10:29 AM, Alice doff...@gmail.com wrote: (go (jdbc/db-transaction [t-con db-spec] (! (insert-async! t-con :fruit {:name apple} Does this work: (jdbc/db-transaction [t-con db-spec] (go (! (insert-async! t-con :fruit {:name apple} -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- -- 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 the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@**googlegroups.com. For more options, visit https://groups.google.com/**grou**ps/opt_outhttps://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 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
Re: RPC over channels
How would a blocking call be created? How would you implement this in a way that wouldn't lock one machine to another machine's performance. For quite some time now, RPC has been considered a very bad idea since it mixes reliable and unreliable semantics. With a network you're never actually sure that a message will arrive (see the messenger problem). And yet one expects procedure calls to be reliable. So what happens when you make a RPC call, and then the remote server dies? What are the semantics on the sender side? Secondly, RPC kind of flies in the face of Clojure in general. Sending procedure calls? Why not send data? I've been thinking about this a lot recently, and how the entire process can be made to be lock safe. That is, when a remote server dies, the system continues to respond as normal (see Joe Armstrong's thesis). I'm not completely convinced that the CSP style works well in this context, and that instead we should perhaps model these systems after unreliable message passing, as that's really all that you are promised by the network protocol anyways. Timothy Baldridge On Thu, Aug 1, 2013 at 9:32 AM, toberepla...@gmail.com wrote: With core.async, cljzmq https://github.com/zeromq/cljzmq, and now zmq-async https://github.com/lynaghk/zmq-async, there's an opportunity to link RPC to channels and be free of the underlying transport system. I'm proposing an RPC library that sends and receives data over channels. The idea is to have a two-way communication context as a map with a send-channel, receive-channel, serializer, and deserializer. The user would be responsible for the transport mechanism between the client and the server. When a user makes a request, the library would create a map to follow the JSON-RPC http://www.jsonrpc.org/specification and attach a UUID to it then send it down the send-channel. This UUID could be used in conjunction with pulling items off of the receive-channel to handle responses. The data flow would be: user-request - wrap-in-specification - client-serializer - client-send-channel - transport-provider - server deserializer - server-receive-channel - user-function - server-serializer - server-send-channel - transport-provider - client-deserializer - unwrap-specification - client-receive-channel - user-response-handling. The library would be responsible for wrapping the requests and responses according to the specification, but not the serialization mechanism nor the transport, since those could be very different depending on the problem. Utilities could be provided for a blocking call and managing cycling through responses on the receive-channel in order to find a specific response that has not yet been processed. As an example, the above workflow should be able to work seamlessly with the channels provided by zmq-async. The send-channels provided would be used as is, and the receive-channels would be used with an additional channel outside of it to take the responses off and deserialize them before returning to the user. The transport provider, of course, would be ZeroMQ. Are there any projects already doing this? Would people be interested? Any feedback? -ToBeReplaced -- -- 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: core.async: throwing an exception into the channel
My first thought was: Since channels can have arbitrary values, how would you distinguish your magical thrown exception value from an exception value put into a channel for normal delivery? And no matter how you annotate that, it'll still just be a regular value. So the only way you could have the behavior you want would be to add special logic into every get operation (and put operation, probably) so everyone would pay for a feature that few will likely use... (my second thought was Why don't get operations just get updated to throw if they get an exception value from the channel anyway? but I quickly realized this was the exact same problem!) Sean On Thu, Aug 1, 2013 at 3:19 AM, Alice dofflt...@gmail.com wrote: throw! is an explicit operation, and there's no special channel states involved. It's passing an exception like other data that just automatically throws it when taken. So it won't hurt anybody. You can use it when you need it, you can ignore it if you don't need it. Yet, it makes using async functions look almost identical to the sync functions. On Thursday, August 1, 2013 3:37:51 AM UTC+9, tbc++ wrote: The position of core.async is to not specify how exceptions should be done (instead leaving it up to the user). So if that method works well for you, write some macros and use it! Other methods may be the use of supervisor channels. In this model, go blocks that die would enqueue the exception into a global (or shared) channel and the go block would then be re-started by a monitor process. Both methods (and may more) are supported by core.async...it simply doesn't care how you handle exceptions, but it is up to you to specify how they are handled. Timothy On Wed, Jul 31, 2013 at 11:49 AM, Alice doff...@gmail.com wrote: It would be nice to have a function throw! that puts an exception into the channel and throws it when taken, so that I can write (let [c (chan)] (go (throw! c (Exception.))) (go (try (prn (! c)) (catch Throwable t (prn exception) instead of (let [c (chan)] (go (! c (Exception.))) (go (try (let [res (! c)] (if (instance? Throwable res) (throw res) (prn res))) (catch Throwable t (prn exception) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- “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. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- -- 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] Immutant 1.0.0 released
Excellent! I look forward to trying this! Any plans for a Clojure / Immutant cartridge for OpenShift? Sean On Wed, Jul 31, 2013 at 1:49 PM, Jim Crossley jcrossl...@gmail.com wrote: Today we finally released Immutant 1.0.0! Read about it here: http://bit.ly/imm100 For those unfamiliar, Immutant is an application server for Clojure. It's an integrated platform providing web, messaging, caching, scheduling, XA transactions, clustering, and daemons built on JBoss AS7 that aims to reduce the incidental complexity found in real-world applications. Have fun! 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. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- -- 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: faulty rebinding of loop-bindings in go blocks
It's a nasty bug, seems like a local symbol scope issue. I will take a look at it. Thanks for the report. On Thursday, August 1, 2013 6:05:59 AM UTC-4, Kemar wrote: There seems to be an issue with the rebinding of loop-bindings using loop/recur in go blocks, specifically when you are just changing the order of the original bindings in a recur call. Take this snippet for example: (require '[clojure.core.async :refer [go timeout]]) (go (loop [a :black, b :white] (println a b) (! (timeout 1000)) (recur b a))) Instead of repeatedly printing :black :white :white :black :black :white :white :black (...) it actually prints :black :white :white :white :white :white :white :white (...) Note however, that (require '[clojure.core.async :refer [go timeout]]) (go (loop [a :black, b :white] (println a b) (! (timeout 1000)) (recur (identity b) (identity a works correctly. Any ideas as to what's causing this? Cheers, Kevin -- -- 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] Immutant 1.0.0 released
Nice timing, Sean! :-) On Wednesday, I was able to finally get Immutant clustering successfully on OpenShift. Load-balanced messaging and web, failover for daemons and jobs, replication for caching, everything seems to work. This is with both HornetQ and Infinispan using JGroups so automatic peer discovery just works when I add a gear. I'm now working on the cartridge, though the quickstart will work (with a slight modification I need to push) if you want to play with it now. I'll blog about it soon. Jim On Thu, Aug 1, 2013 at 12:32 PM, Sean Corfield seancorfi...@gmail.comwrote: Excellent! I look forward to trying this! Any plans for a Clojure / Immutant cartridge for OpenShift? Sean On Wed, Jul 31, 2013 at 1:49 PM, Jim Crossley jcrossl...@gmail.com wrote: Today we finally released Immutant 1.0.0! Read about it here: http://bit.ly/imm100 For those unfamiliar, Immutant is an application server for Clojure. It's an integrated platform providing web, messaging, caching, scheduling, XA transactions, clustering, and daemons built on JBoss AS7 that aims to reduce the incidental complexity found in real-world applications. Have fun! 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. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- -- 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: RPC over channels
I'm thinking that a blocking call would be an ordinary call that subsequently continuously reads from the receive-channel and checks if the id matches, returns if it does, and puts the value back on the channel otherwise. In a blocking call, you are always locked to the performance of the server. The benefit here is that all you know about your server is that it is something sitting on the other side of your channel. With ZeroMQ, it might be a router that delivers your request to the machine it thinks is most likely to be able to handle the request. The system serving your requests could be a single process executing blocking calls to a third-party http rest api, or it could be a network of load-balancing machines. There would be no intent to solve the messenger problem explicitly -- those semantics are up to the user. By default, in the case of server death, the client side will just no longer receive responses on its receive-channel. In the case of a blocking call, this means that the client side will hang. It might be possible to have configurable semantics schemes included with the library -- This isn't an area I'm well-versed in, but maybe someone else could help explore that? Also, sometimes, your transport provider may be able to provide promises like delivery assurances (like Rabbit). There would be nothing to prevent a transport provider from enforcing its own semantics. In what ways are procedure calls different from data? It feels like a procedure call is just a data contract. This library would be doing the job of wrapping up two different queues -- one for outbound requests and one for inbound responses. It's true that you'd much rather only have the outbound queue, but sometimes you need both. -ToBeReplaced On Thursday, August 1, 2013 11:49:16 AM UTC-4, tbc++ wrote: How would a blocking call be created? How would you implement this in a way that wouldn't lock one machine to another machine's performance. For quite some time now, RPC has been considered a very bad idea since it mixes reliable and unreliable semantics. With a network you're never actually sure that a message will arrive (see the messenger problem). And yet one expects procedure calls to be reliable. So what happens when you make a RPC call, and then the remote server dies? What are the semantics on the sender side? Secondly, RPC kind of flies in the face of Clojure in general. Sending procedure calls? Why not send data? I've been thinking about this a lot recently, and how the entire process can be made to be lock safe. That is, when a remote server dies, the system continues to respond as normal (see Joe Armstrong's thesis). I'm not completely convinced that the CSP style works well in this context, and that instead we should perhaps model these systems after unreliable message passing, as that's really all that you are promised by the network protocol anyways. Timothy Baldridge On Thu, Aug 1, 2013 at 9:32 AM, tobere...@gmail.com javascript: wrote: With core.async, cljzmq https://github.com/zeromq/cljzmq, and now zmq-async https://github.com/lynaghk/zmq-async, there's an opportunity to link RPC to channels and be free of the underlying transport system. I'm proposing an RPC library that sends and receives data over channels. The idea is to have a two-way communication context as a map with a send-channel, receive-channel, serializer, and deserializer. The user would be responsible for the transport mechanism between the client and the server. When a user makes a request, the library would create a map to follow the JSON-RPC http://www.jsonrpc.org/specification and attach a UUID to it then send it down the send-channel. This UUID could be used in conjunction with pulling items off of the receive-channel to handle responses. The data flow would be: user-request - wrap-in-specification - client-serializer - client-send-channel - transport-provider - server deserializer - server-receive-channel - user-function - server-serializer - server-send-channel - transport-provider - client-deserializer - unwrap-specification - client-receive-channel - user-response-handling. The library would be responsible for wrapping the requests and responses according to the specification, but not the serialization mechanism nor the transport, since those could be very different depending on the problem. Utilities could be provided for a blocking call and managing cycling through responses on the receive-channel in order to find a specific response that has not yet been processed. As an example, the above workflow should be able to work seamlessly with the channels provided by zmq-async. The send-channels provided would be used as is, and the receive-channels would be used with an additional channel outside of it to take the responses off and deserialize them before returning to the user. The transport
Re: [ANN] Immutant 1.0.0 released
Great news! Every conference I've been to lately, I've been bugging the OpenShift guys - I know they have been rewriting the cartridge spec so I'm glad to hear an Immutant cartridge is coming. Once that cartridge is available, I'll have a play with it (I don't have time right now to do anything that isn't standard / turn key). Sean On Thu, Aug 1, 2013 at 9:48 AM, Jim Crossley j...@crossleys.org wrote: Nice timing, Sean! :-) On Wednesday, I was able to finally get Immutant clustering successfully on OpenShift. Load-balanced messaging and web, failover for daemons and jobs, replication for caching, everything seems to work. This is with both HornetQ and Infinispan using JGroups so automatic peer discovery just works when I add a gear. I'm now working on the cartridge, though the quickstart will work (with a slight modification I need to push) if you want to play with it now. I'll blog about it soon. Jim On Thu, Aug 1, 2013 at 12:32 PM, Sean Corfield seancorfi...@gmail.com wrote: Excellent! I look forward to trying this! Any plans for a Clojure / Immutant cartridge for OpenShift? Sean On Wed, Jul 31, 2013 at 1:49 PM, Jim Crossley jcrossl...@gmail.com wrote: Today we finally released Immutant 1.0.0! Read about it here: http://bit.ly/imm100 For those unfamiliar, Immutant is an application server for Clojure. It's an integrated platform providing web, messaging, caching, scheduling, XA transactions, clustering, and daemons built on JBoss AS7 that aims to reduce the incidental complexity found in real-world applications. Have fun! 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. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- -- 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. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- -- 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: RPC over channels
On Thu, Aug 1, 2013 at 1:09 PM, toberepla...@gmail.com wrote: There would be no intent to solve the messenger problem explicitly -- those semantics are up to the user. By default, in the case of server death, the client side will just no longer receive responses on its receive-channel. In the case of a blocking call, this means that the client side will hang. Ugh. At the *very* least it should eventually return with some kind of a timeout exception. -- -- 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: Emitting a proper line numbers in code generated by macro
On Jul 31, 2013, at 6:45 AM, Dmitry Groshev lambdadmi...@gmail.com wrote: Is there any proper way to preserve line numbers in stack traces with code generation? Midje goes to some effort to do this. It's not incredibly easy. src/midje/parsing/util/file_position.clj has the bulk of the code, but it's probably not easy to understand in isolation. Latest book: /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo -- -- 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: RPC over channels
A client could use a timeout channel as its receive channel to get timeouts on a blocking call, though I don't think that's the right way to do it. Alternatively, implementing a blocking call with an optional timeout wouldn't be difficult, it just can't be the default. I think if you disallowed nil as a response, then it would be easy to use a variety of different blocking calls -- wait forever, wait 30 seconds, wait until (f) returns truthy, etc. -ToBeReplaced On 08/01/2013 03:36 PM, Cedric Greevey wrote: On Thu, Aug 1, 2013 at 1:09 PM, toberepla...@gmail.com mailto:toberepla...@gmail.com wrote: There would be no intent to solve the messenger problem explicitly -- those semantics are up to the user. By default, in the case of server death, the client side will just no longer receive responses on its receive-channel. In the case of a blocking call, this means that the client side will hang. Ugh. At the *very* least it should eventually return with some kind of a timeout exception. -- -- 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/P95cOfuXBUs/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 clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Can a function determine it's own name at runtime?
Thanks Timothy/Stephen, that was very useful to me :) Op zondag 20 december 2009 23:50:05 UTC+1 schreef Timothy Pratley: Regarding current function, Stephen posted this code a whie ago so I don't think he'll mind me regurgitating it for you: (use 'clojure.contrib.str-utils) ; Stephen C. Gilardi (defn unmangle Given the name of a class that implements a Clojure function, returns the function's name in Clojure. Note: If the true Clojure function name contains any underscores (a rare occurrence), the unmangled name will contain hyphens at those locations instead. [class-name] (.replace (re-sub #^(.+)\$(.+)__\d+$ $1/$2 class-name) \_ \-)) ; Stephen C. Gilardi (defmacro current-function-name Returns a string, the name of the current Clojure function. [] `(- (Throwable.) .getStackTrace first .getClassName unmangle)) I imagine some similar unmangling could be applied to getting the class-name of an arbitrary function, something like (unmangle (.toString foo)) ;; but not exactly - this doesn't work - if you figure that out please post the answer :) Regards, Tim. -- -- 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.
Displaying objects in REPL: Clojure equivalent of Java's toString?
I have some custom types defined using deftype and I am trying to enable a human-friendly string representation of these types in repl. Something similar to #Atom@123 value. How to do that in Clojure without redefining toString? It seems that Clojure use a different way to achieve this for atoms and refs, I just can't find what. -- -- 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: Displaying objects in REPL: Clojure equivalent of Java's toString?
I think you have to provide methods for multimethods print-dup and print-method: https://github.com/clojure/clojure/blob/c6756a8bab137128c8119add29a25b0a88509900/src/clj/clojure/core.clj#L3311 2013/8/1 Dragan Djuric draga...@gmail.com: I have some custom types defined using deftype and I am trying to enable a human-friendly string representation of these types in repl. Something similar to #Atom@123 value. How to do that in Clojure without redefining toString? It seems that Clojure use a different way to achieve this for atoms and refs, I just can't find what. -- -- 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: YA regular expression tool
Thanks. This tool was really more or less for fun but I'd been thinking about it for a while. According to some benchmarks it appears the generated patterns are pretty fast. When I get some more time, I definitely want to see if converting the word trie to a DAWG and then to a regular expression will produce even better patterns. Of course, this means pattern construction will be slower. More or less I'd like some input on ways to improve the efficiency of the whole thing. On Tuesday, July 30, 2013 3:49:49 AM UTC-7, Mikera wrote: On Monday, 29 July 2013 21:20:49 UTC+1, Joel Holdbrooks wrote: I spent some time this weekend writing a little tool for generating regular expressions *from known inputs*. My goal is to produce regular expressions that backtrack as few times as possible along with a complete and total disregard for readability. :) The code for the tool is here https://github.com/noprompt/frak. Suggestions/ideas would be greatly appreciated. Nice - I like the fact that it has a very simple API that focuses on doing just one thing well! -- -- 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: Invalid token exception on a / operator
I've been stung by this too. One work around I use is *(:refer-clojure :exclude [/])* and *(:require [some.ns :refer [/])* in my *ns* form. Then refer to *clojure.core//* directly if needed. It's good to hear this will be fixed in 1.6. On Tuesday, July 30, 2013 5:26:23 AM UTC-7, Maik Schünemann wrote: Is / a valid clojure function name (valid, but not recommended)? I tought so because of clojure.core// in the repl there is also no problem with clojure.core//: clojure.core// ;=#core$_SLASH_ clojure.core$_SLASH_@6d996380 but if / is in another namespace, for example in core.matrix: clojure.core.matrix.operators// RuntimeException Invalid token: clojure.core.matrix.operators// clojure.lang.Util.runtimeException (Util.java:219) clearly this is an edge case, because / also separates namespaces but I think if clojure.core// is valid clojure.core.matrix.operators// should also be a valid token?! regards Maik Schünemann -- -- 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.
Two Dimensional Associative Map
I'm looking for an associative data structure that can be accessed by both rows and columns, and could potentially be sparse. Suppose the following table is called t: | | :A | :B | :C ||---+--+--+--|| 1 | | | '[x y z] || 2 | 2a | 2b | || 3 | | | || 3 | :3a | | Foo| Then (t :A) would return {2 2a, 3 :3a}, and (t 2) would return {:A 2a, :B 2b}. (t :A 2) or (t 2 :A) would return 2a. I'm thinking of implementing it as a simple map of maps with some extra functions, but I'm not sure if that would be the best option. -- -- 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.
Causeway - new web framework
Hey, Over the last few days I've been putting up a web framework of my own from all the experience I've gained for the last 19 months of intensive Clojure development. I would really enjoy any feedback. I am aware that I made little documentation, so it will not be easy to check it out, but I am going to improve on that in the next few days. This is my first open source Clojure contribution, so please be forgiving :). Causeway: https://github.com/cosmi/causeway/ Of course Causeway (I admit, I used some website with random words generator :) ) is not yet mature; the things that are done already (each part can be used separately, and I will separate them into different packages soon): - compilation and caching of website assets: right now LESS CSS, CoffeeScript and CSS+JS minimizers are supported, but it is super easy to add others - (this is something done already by dieter (https://github.com/edgecase/dieter), but I didn't like that project - it is unflexible, poorly supported and has a million or so LoC for something that should not take more than 150 when there is the whole JVM ecosystem available, including wro4j) - templates, more or less compatible with clabango (https://github.com/danlarkin/clabango) - I did not like the fact that clabango has poor performance and a lot of bugs, so I shamelessly rewrote it from scratch (and consider it mine;) ). Now the templates are compiled into a more or less optimized structure of clojure lambdas. - support for l10n/i18n/AB-testing or whatever you would like. You can have many variants of all the resources, templates and strings, and it will be selected accordingly if you just provide some logic for which variant should be used. - some more sensible project structure than luminus (http://www.luminusweb.net/), but this is only my humble opinion that htmls should not be in the same directory as .clj files. - as a bonus support for properties - that are more or less constant vars that can be modified by www admin panel and saved in MongoDB (I will add support for other DBs as needed). - forms validation (with compatibile forms generation coming soon as a bonus) That's it for now. Marcin -- -- 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: Displaying objects in REPL: Clojure equivalent of Java's toString?
Adding to that... have a look at the implemented methods in core_print.clj. The print-method will get called on print and println with your instance as the first argument. In this example prints a pair type; since elements can be anything it just calls print on each. (deftype Pair [fst snd]) (defmethod print-method Pair [r, ^java.io.Writer w] (.write w Pair() (print (.fst r)) (.write w ,) (print (.snd r)) (.write w ))) On Thursday, August 1, 2013 3:04:47 PM UTC-7, Laurent PETIT wrote: I think you have to provide methods for multimethods print-dup and print-method: https://github.com/clojure/clojure/blob/c6756a8bab137128c8119add29a25b0a88509900/src/clj/clojure/core.clj#L3311 2013/8/1 Dragan Djuric drag...@gmail.com javascript:: I have some custom types defined using deftype and I am trying to enable a human-friendly string representation of these types in repl. Something similar to #Atom@123 value. How to do that in Clojure without redefining toString? It seems that Clojure use a different way to achieve this for atoms and refs, I just can't find what. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
BigDecimal and ==, with a proposed fix
My understanding of == is that it is intended to establish numerical equivalence across types. But I think that basic contract fails with BigDecimal. For instance, (== 1M 1.0M) ; = false because the scale properties of these numbers are different. So then of course: [(== 1 1N 1.0) (== 1 1N 1.0 1M) (== 1 1N 1.0 1.0M) (== 1 1.0 1N 1.0M)] ; = [true true true false] and [(== 1.0M 1.0) (== 1.0 1) (== 1 1N) (== 1N 1.0M)] ; = [true true true false] I find your lack of transitivity (and commutativity) ... disturbing. The issue is that there are two notions of equality for BigDecimal, equals and compareTo, where equals compares value *and* scale while compareTo compares numerically. The other numeric types use equals for equivalence, quite reasonably. But in class BigDecimalOps in clojure/lang/Numbers.java, I propose that public boolean equiv(Number x, Number y){ return toBigDecimal(x).equals(toBigDecimal(y)); } should be public boolean equiv(Number x, Number y){ return toBigDecimal(x).compareTo(toBigDecimal(y)) == 0; } to give the proper sense of equivalence. I haven't had a chance yet to recompile with this change to test it, but we do have (zero? (. 1.0M (compareTo 1M))) ; = true (zero? (. 1.M (compareTo 1M))) ; = true (zero? (. 1.000M (compareTo 1.0M))) ; = true as desired. Reactions? Best, Chris -- -- 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: BigDecimal and ==, with a proposed fix
I agree, which is why I wrote a patch for the ticket http://dev.clojure.org/jira/browse/CLJ-1118 (Depending on when you read this, dev.clojure.org may not be accessible due to a recent DNS update made by the Clojure folks. Wait a while and try again.) It makes not only the change you suggest, but also another one to how hash is calculated for BigDecimal values, so that hash is still consistent with =. Take a look at it and see if you think it is correct. Andy On Thu, Aug 1, 2013 at 9:28 PM, CGAT genovese...@gmail.com wrote: My understanding of == is that it is intended to establish numerical equivalence across types. But I think that basic contract fails with BigDecimal. For instance, (== 1M 1.0M) ; = false because the scale properties of these numbers are different. So then of course: [(== 1 1N 1.0) (== 1 1N 1.0 1M) (== 1 1N 1.0 1.0M) (== 1 1.0 1N 1.0M)] ; = [true true true false] and [(== 1.0M 1.0) (== 1.0 1) (== 1 1N) (== 1N 1.0M)] ; = [true true true false] I find your lack of transitivity (and commutativity) ... disturbing. The issue is that there are two notions of equality for BigDecimal, equals and compareTo, where equals compares value *and* scale while compareTo compares numerically. The other numeric types use equals for equivalence, quite reasonably. But in class BigDecimalOps in clojure/lang/Numbers.java, I propose that public boolean equiv(Number x, Number y){ return toBigDecimal(x).equals(toBigDecimal(y)); } should be public boolean equiv(Number x, Number y){ return toBigDecimal(x).compareTo(toBigDecimal(y)) == 0; } to give the proper sense of equivalence. I haven't had a chance yet to recompile with this change to test it, but we do have (zero? (. 1.0M (compareTo 1M))) ; = true (zero? (. 1.M (compareTo 1M))) ; = true (zero? (. 1.000M (compareTo 1.0M))) ; = true as desired. Reactions? Best, Chris -- -- 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: BigDecimal and ==, with a proposed fix
You can also see the patch at this link, in case it is a while before JIRA is back up: https://github.com/jafingerhut/clj-prescreen/blob/master/eval-results/2013-08-01/ticket-info/CLJ-1118-attachments/clj-1118-make-double-equals-true-for-more-bigdecimals-patch-v3.txt On Thu, Aug 1, 2013 at 10:16 PM, Andy Fingerhut andy.finger...@gmail.comwrote: I agree, which is why I wrote a patch for the ticket http://dev.clojure.org/jira/browse/CLJ-1118 (Depending on when you read this, dev.clojure.org may not be accessible due to a recent DNS update made by the Clojure folks. Wait a while and try again.) It makes not only the change you suggest, but also another one to how hash is calculated for BigDecimal values, so that hash is still consistent with =. Take a look at it and see if you think it is correct. Andy On Thu, Aug 1, 2013 at 9:28 PM, CGAT genovese...@gmail.com wrote: My understanding of == is that it is intended to establish numerical equivalence across types. But I think that basic contract fails with BigDecimal. For instance, (== 1M 1.0M) ; = false because the scale properties of these numbers are different. So then of course: [(== 1 1N 1.0) (== 1 1N 1.0 1M) (== 1 1N 1.0 1.0M) (== 1 1.0 1N 1.0M)] ; = [true true true false] and [(== 1.0M 1.0) (== 1.0 1) (== 1 1N) (== 1N 1.0M)] ; = [true true true false] I find your lack of transitivity (and commutativity) ... disturbing. The issue is that there are two notions of equality for BigDecimal, equals and compareTo, where equals compares value *and* scale while compareTo compares numerically. The other numeric types use equals for equivalence, quite reasonably. But in class BigDecimalOps in clojure/lang/Numbers.java, I propose that public boolean equiv(Number x, Number y){ return toBigDecimal(x).equals(toBigDecimal(y)); } should be public boolean equiv(Number x, Number y){ return toBigDecimal(x).compareTo(toBigDecimal(y)) == 0; } to give the proper sense of equivalence. I haven't had a chance yet to recompile with this change to test it, but we do have (zero? (. 1.0M (compareTo 1M))) ; = true (zero? (. 1.M (compareTo 1M))) ; = true (zero? (. 1.000M (compareTo 1.0M))) ; = true as desired. Reactions? Best, Chris -- -- 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: BigDecimal and ==, with a proposed fix
Terrific, Andy, thanks. I will definitely take a look. On Friday, August 2, 2013 1:16:14 AM UTC-4, Andy Fingerhut wrote: I agree, which is why I wrote a patch for the ticket http://dev.clojure.org/jira/browse/CLJ-1118 (Depending on when you read this, dev.clojure.org may not be accessible due to a recent DNS update made by the Clojure folks. Wait a while and try again.) It makes not only the change you suggest, but also another one to how hash is calculated for BigDecimal values, so that hash is still consistent with =. Take a look at it and see if you think it is correct. Andy On Thu, Aug 1, 2013 at 9:28 PM, CGAT genov...@gmail.com javascript:wrote: My understanding of == is that it is intended to establish numerical equivalence across types. But I think that basic contract fails with BigDecimal. For instance, (== 1M 1.0M) ; = false because the scale properties of these numbers are different. So then of course: [(== 1 1N 1.0) (== 1 1N 1.0 1M) (== 1 1N 1.0 1.0M) (== 1 1.0 1N 1.0M)] ; = [true true true false] and [(== 1.0M 1.0) (== 1.0 1) (== 1 1N) (== 1N 1.0M)] ; = [true true true false] I find your lack of transitivity (and commutativity) ... disturbing. The issue is that there are two notions of equality for BigDecimal, equals and compareTo, where equals compares value *and* scale while compareTo compares numerically. The other numeric types use equals for equivalence, quite reasonably. But in class BigDecimalOps in clojure/lang/Numbers.java, I propose that public boolean equiv(Number x, Number y){ return toBigDecimal(x).equals(toBigDecimal(y)); } should be public boolean equiv(Number x, Number y){ return toBigDecimal(x).compareTo(toBigDecimal(y)) == 0; } to give the proper sense of equivalence. I haven't had a chance yet to recompile with this change to test it, but we do have (zero? (. 1.0M (compareTo 1M))) ; = true (zero? (. 1.M (compareTo 1M))) ; = true (zero? (. 1.000M (compareTo 1.0M))) ; = true as desired. Reactions? Best, Chris -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.