Re: Hierarchical logs
Unfortunately it doesn't call the functions/macros that the pprint code says are meant for custom dispatch: pprint-logical-block pprint-newline pprint-indent etc Wish I could find an example of those being used in a custom dispatch, I made a lame attempt and for some reason my custom dispatch printed nothing at all :) I can dig in and figure it out, but it would be quicker if someone has already been there. Surely someone has done this :) -jeff On Feb 15, 3:02 am, Kevin Downey redc...@gmail.com wrote: https://gist.github.com/1314616is a small example of a custom dispatch, doesn't do custom indenting though On Tue, Feb 14, 2012 at 6:33 PM, jweiss jeffrey.m.we...@gmail.com wrote: It occurred to me that ultimately what I want is just a pretty-printed output that I can put on a webpage and apply syntaxhighlighter to. I should be able to use a custom pprint dispatch to take this [[(+ 5 (- 4 2 (* 9 3)) (* 5 (+ 6 3))) nil] [(- 4 2 (* 9 3)) nil] [(* 9 3) nil] [27 true] [-25 true] [(* 5 (+ 6 3)) nil] [(+ 6 3) nil] [9 true] [45 true] [25 true]] and print something like this: (+ 5 (- 4 2 (* 9 3)) (* 5 (+ 6 3))) (- 4 2 (* 9 3)) (* 9 3) 27 -25 (* 5 (+ 6 3)) (+ 6 3) 9 45 25 Without even converting it into a tree. But I am having a hard time finding an example of custom dispatch, or docs on how to write one. I really just want things printed the same as pprint currently does, but being able to specify extra indent for the whole block. I had originally planned to output html where each item was properly nested as html divs, but I think that is getting overly complex. -jeff On Feb 14, 10:14 am, jweiss jeffrey.m.we...@gmail.com wrote: Thanks, Alan, The solution I used looks exactly like yours: (defn mktree [vz [i out?]] (if out? (- vz (zip/append-child i) zip/up ) (- vz (zip/append-child [i]) zip/down zip/rightmost))) (defn as-tree [tracelist] (zip/root (reduce mktree (zip/vector-zip []) tracelist))) Thinking about it some more, I don't think I'm going to come up with a solution that's any more efficient or easy to code as this one. The real work is figuring out where the next element needs to be inserted. Zipper keeps that information as part of the data structure so it doesn't have to be re-calculated every iteration. My previous solution using loop had kept an accumulator (a list of indices to pass to assoc-in). -jeff On Feb 12, 3:42 am, Alan Malloy a...@malloys.org wrote: I toyed with some simple ways of doing this, but I don't think any of them will actually work out. I think the advice you got in #clojure to use zippers is probably correct. Here's a sketch I bashed out that seems to do roughly what you want:https://gist.github.com/1807340(I took the liberty of wrapping the whole thing in another [] under the assumption you'd want to record multiple top-level calls; if not you can just call first on the result). On Feb 11, 8:39 pm, jweiss jeffrey.m.we...@gmail.com wrote: I've been working on a tracing library, that works much like clojure.contrib.trace (based on it, actually). One sticky problem I've found is, hierarchical logs are really crappy to try to stream to a file. You can't just keep writing to the end of the file - new data needs to be inserted before existing end-tags. So what I'm doing is storing the data as a list, until I know the data is complete, and then i turn it back into a tree to write the file. However I can't think of a simple way to do it, even though it seems like a simple operation. I want to turn this list of pairs (first item is the fn call or return value, the second is a truthy value marking whether it's a call or return) '[[(+ 1 (- 5 2) nil] [(- 5 2) nil] [3 true] [4 true]] I want to turn that into [(+ 1 (- 5 2)) [(- 5 2) 3] 4] Is there a simple way to do this? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? -- 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
Re: Hierarchical logs
Thanks, Alan, The solution I used looks exactly like yours: (defn mktree [vz [i out?]] (if out? (- vz (zip/append-child i) zip/up ) (- vz (zip/append-child [i]) zip/down zip/rightmost))) (defn as-tree [tracelist] (zip/root (reduce mktree (zip/vector-zip []) tracelist))) Thinking about it some more, I don't think I'm going to come up with a solution that's any more efficient or easy to code as this one. The real work is figuring out where the next element needs to be inserted. Zipper keeps that information as part of the data structure so it doesn't have to be re-calculated every iteration. My previous solution using loop had kept an accumulator (a list of indices to pass to assoc-in). -jeff On Feb 12, 3:42 am, Alan Malloy a...@malloys.org wrote: I toyed with some simple ways of doing this, but I don't think any of them will actually work out. I think the advice you got in #clojure to use zippers is probably correct. Here's a sketch I bashed out that seems to do roughly what you want:https://gist.github.com/1807340(I took the liberty of wrapping the whole thing in another [] under the assumption you'd want to record multiple top-level calls; if not you can just call first on the result). On Feb 11, 8:39 pm, jweiss jeffrey.m.we...@gmail.com wrote: I've been working on a tracing library, that works much like clojure.contrib.trace (based on it, actually). One sticky problem I've found is, hierarchical logs are really crappy to try to stream to a file. You can't just keep writing to the end of the file - new data needs to be inserted before existing end-tags. So what I'm doing is storing the data as a list, until I know the data is complete, and then i turn it back into a tree to write the file. However I can't think of a simple way to do it, even though it seems like a simple operation. I want to turn this list of pairs (first item is the fn call or return value, the second is a truthy value marking whether it's a call or return) '[[(+ 1 (- 5 2) nil] [(- 5 2) nil] [3 true] [4 true]] I want to turn that into [(+ 1 (- 5 2)) [(- 5 2) 3] 4] Is there a simple way to do this? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Hierarchical logs
It occurred to me that ultimately what I want is just a pretty-printed output that I can put on a webpage and apply syntaxhighlighter to. I should be able to use a custom pprint dispatch to take this [[(+ 5 (- 4 2 (* 9 3)) (* 5 (+ 6 3))) nil] [(- 4 2 (* 9 3)) nil] [(* 9 3) nil] [27 true] [-25 true] [(* 5 (+ 6 3)) nil] [(+ 6 3) nil] [9 true] [45 true] [25 true]] and print something like this: (+ 5 (- 4 2 (* 9 3)) (* 5 (+ 6 3))) (- 4 2 (* 9 3)) (* 9 3) 27 -25 (* 5 (+ 6 3)) (+ 6 3) 9 45 25 Without even converting it into a tree. But I am having a hard time finding an example of custom dispatch, or docs on how to write one. I really just want things printed the same as pprint currently does, but being able to specify extra indent for the whole block. I had originally planned to output html where each item was properly nested as html divs, but I think that is getting overly complex. -jeff On Feb 14, 10:14 am, jweiss jeffrey.m.we...@gmail.com wrote: Thanks, Alan, The solution I used looks exactly like yours: (defn mktree [vz [i out?]] (if out? (- vz (zip/append-child i) zip/up ) (- vz (zip/append-child [i]) zip/down zip/rightmost))) (defn as-tree [tracelist] (zip/root (reduce mktree (zip/vector-zip []) tracelist))) Thinking about it some more, I don't think I'm going to come up with a solution that's any more efficient or easy to code as this one. The real work is figuring out where the next element needs to be inserted. Zipper keeps that information as part of the data structure so it doesn't have to be re-calculated every iteration. My previous solution using loop had kept an accumulator (a list of indices to pass to assoc-in). -jeff On Feb 12, 3:42 am, Alan Malloy a...@malloys.org wrote: I toyed with some simple ways of doing this, but I don't think any of them will actually work out. I think the advice you got in #clojure to use zippers is probably correct. Here's a sketch I bashed out that seems to do roughly what you want:https://gist.github.com/1807340(I took the liberty of wrapping the whole thing in another [] under the assumption you'd want to record multiple top-level calls; if not you can just call first on the result). On Feb 11, 8:39 pm, jweiss jeffrey.m.we...@gmail.com wrote: I've been working on a tracing library, that works much like clojure.contrib.trace (based on it, actually). One sticky problem I've found is, hierarchical logs are really crappy to try to stream to a file. You can't just keep writing to the end of the file - new data needs to be inserted before existing end-tags. So what I'm doing is storing the data as a list, until I know the data is complete, and then i turn it back into a tree to write the file. However I can't think of a simple way to do it, even though it seems like a simple operation. I want to turn this list of pairs (first item is the fn call or return value, the second is a truthy value marking whether it's a call or return) '[[(+ 1 (- 5 2) nil] [(- 5 2) nil] [3 true] [4 true]] I want to turn that into [(+ 1 (- 5 2)) [(- 5 2) 3] 4] Is there a simple way to do this? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Hierarchical logs
I've been working on a tracing library, that works much like clojure.contrib.trace (based on it, actually). One sticky problem I've found is, hierarchical logs are really crappy to try to stream to a file. You can't just keep writing to the end of the file - new data needs to be inserted before existing end-tags. So what I'm doing is storing the data as a list, until I know the data is complete, and then i turn it back into a tree to write the file. However I can't think of a simple way to do it, even though it seems like a simple operation. I want to turn this list of pairs (first item is the fn call or return value, the second is a truthy value marking whether it's a call or return) '[[(+ 1 (- 5 2) nil] [(- 5 2) nil] [3 true] [4 true]] I want to turn that into [(+ 1 (- 5 2)) [(- 5 2) 3] 4] Is there a simple way to do this? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: clojure.contrib.prxml broken in Clojure 1.3.0
It might not make a lot of practical difference, but my understanding is that CDATA isn't parsed as XML, so if you have a lot of non-xml data, it's probably better to use CDATA so that it is not parsed when it's read back in. On Jan 17, 11:12 pm, Alan Malloy a...@malloys.org wrote: It doesn't need CDATA - data.xml just automatically escapes XML special-characters if it sees them. On Jan 17, 4:12 pm, jweiss jeffrey.m.we...@gmail.com wrote: By the way, the reason I stuck with prxml is its handling of CDATA, which as far as I know, the newer lib doesn't do yet. On Jan 17, 8:10 am, cassiel n...@cassiel.com wrote: This is straight from the doc string: (with-out-str (p/prxml [:p {:class greet} [:i Ladies gentlemen]])) Works in Clojure 1.2.1: (:ok \p class=\\\greet\\\iLadies amp; gentlemen/i/p\) (that's pasted from the slime event buffer, hence the superfluous armour.) Fails in Clojure 1.3.0: clojure.lang.Numbers.lt(II)Z [Thrown class java.lang.NoSuchMethodError] Is prxml still being supported? If not, is there a better Clojure-DSL- to-XML package? -- 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
Re: clojure.contrib.prxml broken in Clojure 1.3.0
I fixed up clojure.contrib.prxml to work with 1.3, at least it's working fine for me. You can get the jar from clojars with [weissjeffm/clojure.prxml 1.3.0-SNAPSHOT] source is here: https://github.com/weissjeffm/clojure.prxml On Jan 17, 8:10 am, cassiel n...@cassiel.com wrote: This is straight from the doc string: (with-out-str (p/prxml [:p {:class greet} [:i Ladies gentlemen]])) Works in Clojure 1.2.1: (:ok \p class=\\\greet\\\iLadies amp; gentlemen/i/p\) (that's pasted from the slime event buffer, hence the superfluous armour.) Fails in Clojure 1.3.0: clojure.lang.Numbers.lt(II)Z [Thrown class java.lang.NoSuchMethodError] Is prxml still being supported? If not, is there a better Clojure-DSL- to-XML package? -- 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
Re: clojure.contrib.prxml broken in Clojure 1.3.0
By the way, the reason I stuck with prxml is its handling of CDATA, which as far as I know, the newer lib doesn't do yet. On Jan 17, 8:10 am, cassiel n...@cassiel.com wrote: This is straight from the doc string: (with-out-str (p/prxml [:p {:class greet} [:i Ladies gentlemen]])) Works in Clojure 1.2.1: (:ok \p class=\\\greet\\\iLadies amp; gentlemen/i/p\) (that's pasted from the slime event buffer, hence the superfluous armour.) Fails in Clojure 1.3.0: clojure.lang.Numbers.lt(II)Z [Thrown class java.lang.NoSuchMethodError] Is prxml still being supported? If not, is there a better Clojure-DSL- to-XML package? -- 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
Re: Really loving Clooj but..
I use a modified version of tools.trace (or rather the old version called clojure.contrib.trace, but works with 1.3), you might be interested in some of the additions (sorry not well doc'd at the moment): 1) Don't blow up if a function throws an exception (return value shown in the trace will be the exception object). 2) option to trace a multi-threaded app - output is to a separate file for each thread 3) Trace entire namespaces, multiple namespaces, exclude fn's from traced namespaces. 4) ability to pretty print the trace to html with syntax highlighter. 1 3 are probably the only ones useful at the repl. Jeff https://github.com/weissjeffm/fn.trace/ On Dec 30, 11:52 am, Erlis Vidal er...@erlisvidal.com wrote: Hi Jonas, That's what I was looking for. Thanks for your reply On Fri, Dec 30, 2011 at 8:16 AM, Jonas jonas.enl...@gmail.com wrote: You should take a look at tools.trace [1]. A minimal example: (ns trc.core (:use [clojure.tools.trace :only [deftrace]])) (deftrace fib [n] (if (or (= n 0) (= n 1)) 1 (+ (fib (- n 1)) (fib (- n 2) the following is printed when (fib 4) is evaluated: TRACE t2302: (fib 4) TRACE t2303: | (fib 3) TRACE t2304: | | (fib 2) TRACE t2305: | | | (fib 1) TRACE t2305: | | | = 1 TRACE t2306: | | | (fib 0) TRACE t2306: | | | = 1 TRACE t2304: | | = 2 TRACE t2307: | | (fib 1) TRACE t2307: | | = 1 TRACE t2303: | = 3 TRACE t2308: | (fib 2) TRACE t2309: | | (fib 1) TRACE t2309: | | = 1 TRACE t2310: | | (fib 0) TRACE t2310: | | = 1 TRACE t2308: | = 2 TRACE t2302: = 5 [1]:https://github.com/clojure/tools.trace -- 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 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
Re: Could be my favourite improvement in 1.4
Even if they did, it's pretty easy to surround the paste with (read- json ... ). On Dec 20, 10:36 am, Alex Baranosky alexander.barano...@gmail.com wrote: For what it's worth, I think colon's as whitespace in maps adds confusion, without, imo adding a ton of power or readability. In terms of power, it gives you the ability to paste JSON into a Clojure REPL; I wonder how often that use case comes up? In terms of readability, any benefit it gives you in readability would be counterweighted by the additional syntax rules it adds. The only way I could see this as worth it, would be if people wanted to paste 'foreign' map data into a Clojure REPL a ton more frequently than I imagine they do. Alex -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Concurrency design
I'm having some trouble figuring out what clojure concurrency tools I can use to solve my problem. The application I'm trying to build is a functional test harness, like TestNG but for clojure. It takes an input a tree of tests to run (where child tests don't run unless the parent passed), and runs the tests in parallel (as much as possible) on a fixed number of threads. Each tree node contains a promise, where the test results are placed. A report runs at the end, and naturally blocks until all the promises are delivered. The problem comes where some kinds of testing require some per-thread setup/teardown. For instance, selenium opens a browser and drives it to run tests. Obviously you can't have multiple tests running in the same browser at the same time. So you need multiple browsers being driven by one thread each. Each thread has to rebind the selenium client var to a new value. So to sum up, I need a thread pool, and thread-local bindings so that clients like selenium can run multithreaded. java.util.concurrent.Executors fail because I can't get thread-local bindings. I haven't been able to find a way to run the entire worker thread with a (binding ...) form, that would apparently involve changing the implementation of the java lib, and too much of that stuff is marked private to proxy it. Agents seemed like a possibility (just for use as a thread pool), but my use-case does not seem to match. I have a single work queue, not many. And the agents value would have to be the local bindings, which would never change. And agents don't have any way of reporting if they are busy or not, so they'd have to pull in their work rather than having it sent to them. My app seems like it would be a rather gross abuse of agents. Futures don't work because I need to limit the number of threads, I can't have 500 browsers open at once. Can someone suggest a direction I should go? Thanks, Jeff -- 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
Re: Concurrency design
If I may reply to myself: Sometimes just stating the problem for someone else makes the solution clear. My false assumption was that I needed something as fancy as agents or ThreadPoolExecutor. The solution was simple Just queue up the tests with a BlockingQueue, start some plain java threads with a consume fn. The consume fn does the binding, polls the queue and exits when a done flag is set. The done flag is set to true when the report finishes. Jeff On Aug 8, 12:59 pm, jweiss jeffrey.m.we...@gmail.com wrote: I'm having some trouble figuring out what clojure concurrency tools I can use to solve my problem. The application I'm trying to build is a functional test harness, like TestNG but for clojure. It takes an input a tree of tests to run (where child tests don't run unless the parent passed), and runs the tests in parallel (as much as possible) on a fixed number of threads. Each tree node contains a promise, where the test results are placed. A report runs at the end, and naturally blocks until all the promises are delivered. The problem comes where some kinds of testing require some per-thread setup/teardown. For instance, selenium opens a browser and drives it to run tests. Obviously you can't have multiple tests running in the same browser at the same time. So you need multiple browsers being driven by one thread each. Each thread has to rebind the selenium client var to a new value. So to sum up, I need a thread pool, and thread-local bindings so that clients like selenium can run multithreaded. java.util.concurrent.Executors fail because I can't get thread-local bindings. I haven't been able to find a way to run the entire worker thread with a (binding ...) form, that would apparently involve changing the implementation of the java lib, and too much of that stuff is marked private to proxy it. Agents seemed like a possibility (just for use as a thread pool), but my use-case does not seem to match. I have a single work queue, not many. And the agents value would have to be the local bindings, which would never change. And agents don't have any way of reporting if they are busy or not, so they'd have to pull in their work rather than having it sent to them. My app seems like it would be a rather gross abuse of agents. Futures don't work because I need to limit the number of threads, I can't have 500 browsers open at once. Can someone suggest a direction I should go? Thanks, Jeff -- 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
Re: Concurrency design
Ken, Thanks for your response! Those are some great suggestions. Some look quite promising, a few don't fit my purposes. For instance, I can't use pcalls because the user needs to be able to control the number of threads. Your method to skip tests using 'and' works, and is interesting, but I want the tree of tests to be easily printable and for users to be able to write them that way (nested map/vector), so that dependencies are visible at a glance without skipping around in the code. Part of the reason I embarked on this project was that midje, lazytest etc are used almost exclusively for unit testing. I need to do black box testing, where the app being tested is remote and it is only accessible via HTTP or some other network protocol. Some of the features I wanted are: * Self-documenting tests. There should be no need to write english testcases AND automate them, the automation IS the testcase. However, management likes to know that tests can be read and run by someone besides the person who wrote them, even when they are automated. So I want (defn duplicate-name-disallowed-test [] (let [name testitem] (create-widget name) (expect NameTakenError (create-widget name))) to be the canonical testcase. If necessary I can process the form into more human readable text (although to me it's plenty readable already, but non programmers might disagree). Unfortunately automating a testcase doesn't absolve it from being in the testcase tracking db. * Self-logging (I use clojure.contrib.trace with some modification - writing log4j statements is a waste of time IMO). Automated tests are software, and so is the app under test. The automation simply flags when it doesn't get what it expects. The engineer's job is to figure out which software is wrong, so logs are important. * Fast execution (hence multithreaded) - the more often tests can run, the fewer suspects you have for the cause of the breakage. * Ability to control depth of testing (this is why I used a tree structure where dependent tests are children - it forces the automator to lay out tests such that the most severe bugs are found first. If you can't log in, the whole app is broken, so login test goes at the root of the tree. In most cases, bug severity = depth in tree. Quick testing means maxdepth = 2 or 3, detailed testing means maxdepth = unlimited). On Aug 8, 2:12 pm, Ken Wesson kwess...@gmail.com wrote: If the local bindings will never change, then why not just use (binding [whatever-setup ...] ...) wrapping the individual test bodies that need such setup? (Where explicit tear-down is required, you'd need try ... finally as well, or better yet a macro like with-open, but using binding instead of let, to abstract out the repeated aspects of such code. Common setups could become more macros, e.g. (with-foo-whatsit [some-symbol some-other-symbol] ...).) If the bindings are to stateful stuff that a sequence of tests will alter, though, you have more problems. Possible improvements: * Redesign the whole thing to be more functional and less stateful. * At least, move as much into pure functions as possible; the pure functions are easy to test. * The (remaining) sequences of tests on state will have to run sequentially, so combine them into a single test that calls the smaller ones. You'll end up with something like: (def results (atom {})) (def tests (atom [])) (def foo nil) (def bar nil) (defmacro deftest ... ) (deftest foo nil [foo (initialize-some-resource) bar (initialize-another)] (the test goes here))) and that produces something like (do (defn foo [] (binding [foo (initialize-some-resource)] (try (binding [bar (initialize-another)] (try (deliver (@results foo) (the test goes here)) (finally (.close bar (catch Throwable _ (deliver (@results foo) false)) (finally (.close foo) (swap! results assoc foo (promise)) (swap! tests conj foo)) whereas (deftest bar foo ...) is similar, but with foo instead of nil for the second argument the bar function body gets wrapped in: (if @(@results foo) (do (body that would have been) (with nil second arg)) (deliver (@results bar) false)) so when bar is run it blocks until foo has run, and short-circuits to failing if foo failed, but runs if foo succeeded. And then there'd be (deftest baz :subtest ...) which expands without swap!s or a wrapper -- it just becomes a function like foo and nothing else. A later test body can do setup, call baz as a function along with several other subtests, and do teardown, e.g. (deftest quux ... ... (and (baz) (baz2) (baz3))) which, obviously, short-circuits to failure if any of these fails and otherwise runs them all and returns baz3's result. Lastly, you'd have (doall (apply pcalls @tests)) to run the tests and (report) after that, with (defn report (doseq
Re: Anyone on Google+ yet?
http://gplus.to/weissjeffm -- 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
Re: Anyone on Google+ yet?
This does bring up an interesting flaw in G+. If I add Clojure people who I don't know personally, how will they know to add me to a Clojure circle? G+ (rightfully) doesn't automatically tell them what circle I added them to. It doesn't appear to be optional to tell them, either. On Jul 14, 7:56 pm, Kyle Root k...@kylert.com wrote: gplus.to/Kylert On Thu, Jul 14, 2011 at 7:00 PM, ianp ian.phill...@gmail.com wrote: Ian Looks like G+ is pretty popular with the Clojure crowd :-) -- 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 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
Re: another question on macros defining functions
If you are connected to a swank server, have you tried C-c C-k to compile the file you're editing? On Jun 4, 1:15 am, nil ache...@gmail.com wrote: Mark, it turns out that everything I need is known and static at hack- time. (Sorry for making it sound otherwise) I know all the names, values, *and* behaviors that I want to use when I'm writing the code for my tests. I just want my clojurebox symbol completion to work after having written a bunch of one-liners to declare families of functions. I think it forces me to eval certain files before I edit others. Am I making you all cringe? -- 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
Re: another question on macros defining functions
As Ken said, you have to remember macros expand at compile time. Think of a macro call as folded up code that the compiler unfolds for you. A macro saves you from writing repetitive code. But if you are trying to define a function whose name isn't known until runtime, that's a whole different thing. Doesn't really make sense to me, since the reason you want to define a var for your fn is presumably because you have code elsewhere that calls it. But if both the definition and call to the fn aren't known until runtime, I don't see the need for a var. Perhaps you could just use a map of names (either strings or keywords or even symbols) to anonymous fn's? At runtime you can add fns to the map, and later pick the fn and call it? (def fns (atom {}) (defn add-fn [name f] (swap! fns assoc name f)) (defn call-fn [name] ((@fns name))) something like that. No macros needed. On Jun 2, 10:34 pm, Ken Wesson kwess...@gmail.com wrote: On Thu, Jun 2, 2011 at 10:06 PM, nil ache...@gmail.com wrote: Hi Here's another macro-noob question. (Thanks for the help on the previous question and please do let me know if stackoverflow is a more appropriate place to ask noob questions.) I'm trying to write a macro (or a function) that defines/declares specifically named functions. In (let [eff gee] (foo eff)) I want the macro foo to define/declare a function called foo-gee, not foo- eff. What should I do differently? The problem here is that macros run at compile time, but let bindings exist at run time. If you need the name to be determined at run time you will need to use eval. If you don't need the name at run time, why are you using (let [eff gee] (foo eff)) and not simply (foo gee)? Please state your requirements clearly. -- Protege: What is this seething mass of parentheses?! Master: Your father's Lisp REPL. This is the language of a true hacker. Not as clumsy or random as C++; a language for a more civilized age. -- 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
Re: macro says Can't use qualified name as parameter
On May 27, 1:46 pm, nil ache...@gmail.com wrote: I was looking athttp://saucelabs.com/blog/index.php/2009/12/running-your-selenium-tes... and in the comments, :Scott suggested that a macro could reduce some of the boilerplate that you see here: (def test-google { :name google :test (fn [client] (doto client (.open http://www.google.com;) (.type q Sauce Labs) (.click btnG) (.waitForPageToLoad 5000)) (.isTextPresent client Selenium))}) (def test-yahoo { :name yahoo :test (fn [client] (doto client (.open http://yahoo.com;) (.type p Sauce Labs) (.click search-submit) (.waitForPageToLoad 5000)) (.isTextPresent client Selenium))}) You can see the boilerplate of defining the map, typing the names of the two keys, calling the thing test-name ... So I tried writing a macro for this. But when I use my first attempt, it says Can't use qualified name as parameter. Here's my first attempt: (defmacro deftest [name body] (let [test-n (symbol (str test- name)) n (str name)] `(def ~test-n {:name ~n :test (fn [client] ~@body)}))) The macro expansion of the following looks good, but actually running it yields the complaint mentioned above: (deftest google (doto client (.open http://www.google.com;) (.type q Sauce Labs) (.click btnG) (.waitForPageToLoad 5000)) (.isTextPresent client Selenium)) My second attempt works .. (defmacro deftest [name client body] (let [test-n (symbol (str test- name)) n (str name)] `(def ~test-n {:name ~n :test (fn [~client] ~@body)}))) ... but now the user has to mention the client twice: (deftest google client (doto client (.open http://www.google.com;) (.type q Sauce Labs) (.click btnG) (.waitForPageToLoad 5000)) (.isTextPresent client Selenium)) How do I get around this? I think what others are getting at is that you shouldn't have the macro define the 'frame' of the (fn ...) form. Just pass it in whole in your macro call like (deftest google (fn [client] (doto client (.open http://www.google.com;) (.type q Sauce Labs) (.click btnG) (.waitForPageToLoad 5000)) (.isTextPresent client Selenium))) It is a bit more boilerplate but you're less likely to shoot yourself in the foot. One thing i've done in macros, (and I don't know how advisable or good clojure this is), but, *if* you're sure all your (fn...) forms you pass in will be explicit fn forms, and not just the symbol of an existing function, you can extract the parameter name and use it as your name field. In the macro you'd do something like (- (second body) first name), which would return the string client. It's probably not the best idea since it *would* prevent you from passing in symbols of existing functions, rather than (fn ...) forms. I'm not sure if you really require vars defined for each test, or if you can just put them in a single map like so: (def tests {:google (fn [client] ...) :yahoo (fn [client] ...)}) and then it'd be easy to process that map: (defn generate [m] (zipmap (keys m) (for [[k v] m] {:name (name k) :test v}))) and finally (run-tests (generate tests)) HTH, Jeff -- 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
Re: macro says Can't use qualified name as parameter
Oops, ignore the part about extracting the parameter name from the fn form. I meant to delete that part, I misunderstood your problem at first. I say just use functions - you don't need macros here. The boilerplate of typing (fn [client] multiple times is not enough to justify their use, IMO. Jeff On May 28, 2:04 pm, jweiss jeffrey.m.we...@gmail.com wrote: On May 27, 1:46 pm, nil ache...@gmail.com wrote: I was looking athttp://saucelabs.com/blog/index.php/2009/12/running-your-selenium-tes... and in the comments, :Scott suggested that a macro could reduce some of the boilerplate that you see here: (def test-google { :name google :test (fn [client] (doto client (.open http://www.google.com;) (.type q Sauce Labs) (.click btnG) (.waitForPageToLoad 5000)) (.isTextPresent client Selenium))}) (def test-yahoo { :name yahoo :test (fn [client] (doto client (.open http://yahoo.com;) (.type p Sauce Labs) (.click search-submit) (.waitForPageToLoad 5000)) (.isTextPresent client Selenium))}) You can see the boilerplate of defining the map, typing the names of the two keys, calling the thing test-name ... So I tried writing a macro for this. But when I use my first attempt, it says Can't use qualified name as parameter. Here's my first attempt: (defmacro deftest [name body] (let [test-n (symbol (str test- name)) n (str name)] `(def ~test-n {:name ~n :test (fn [client] ~@body)}))) The macro expansion of the following looks good, but actually running it yields the complaint mentioned above: (deftest google (doto client (.open http://www.google.com;) (.type q Sauce Labs) (.click btnG) (.waitForPageToLoad 5000)) (.isTextPresent client Selenium)) My second attempt works .. (defmacro deftest [name client body] (let [test-n (symbol (str test- name)) n (str name)] `(def ~test-n {:name ~n :test (fn [~client] ~@body)}))) ... but now the user has to mention the client twice: (deftest google client (doto client (.open http://www.google.com;) (.type q Sauce Labs) (.click btnG) (.waitForPageToLoad 5000)) (.isTextPresent client Selenium)) How do I get around this? I think what others are getting at is that you shouldn't have the macro define the 'frame' of the (fn ...) form. Just pass it in whole in your macro call like (deftest google (fn [client] (doto client (.open http://www.google.com;) (.type q Sauce Labs) (.click btnG) (.waitForPageToLoad 5000)) (.isTextPresent client Selenium))) It is a bit more boilerplate but you're less likely to shoot yourself in the foot. One thing i've done in macros, (and I don't know how advisable or good clojure this is), but, *if* you're sure all your (fn...) forms you pass in will be explicit fn forms, and not just the symbol of an existing function, you can extract the parameter name and use it as your name field. In the macro you'd do something like (- (second body) first name), which would return the string client. It's probably not the best idea since it *would* prevent you from passing in symbols of existing functions, rather than (fn ...) forms. I'm not sure if you really require vars defined for each test, or if you can just put them in a single map like so: (def tests {:google (fn [client] ...) :yahoo (fn [client] ...)}) and then it'd be easy to process that map: (defn generate [m] (zipmap (keys m) (for [[k v] m] {:name (name k) :test v}))) and finally (run-tests (generate tests)) HTH, Jeff -- 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
Re: Weening myself off of global state - what's the idiomatic way to solve this?
I'd start by making functions that take arguments. For instance (defn draw-ball [ball] ...) On Apr 13, 1:22 pm, Brandon Ferguson bnfergu...@gmail.com wrote: I'm not sure if this is the place to ask this but I've been struggling with a few things in the world of Clojure. I've been using Processing to learn Clojure (since I'm somewhat familiar with Processing) but the tough part has been dealing with things like x, y positions of objects without keeping some global state (I'm not sure if it's even possible). The code in question is:https://gist.github.com/887256 All this does is bounce a ball around a screen, for every frame Processing calls draw which moves the ball one frame. Since I'm not the one driving the loop I ended up using atoms to update some bits of global state but that feels really dirty. If I could drive the frames it would be easy to use recur or some other bit of state passing as I render each successive frame. I've considered using sequences and passing a frame number (which would be stored in a global as well) in but then it'd (I assume) have to run through every number up to that the one I passed it. Seems like performance would degrade the longer it ran. There's also this idea rattling around in my head where I'd just rewrite the function everytime with the new state - but seems like you couldn't scale that to multiple balls bouncing around (which is the next step) - and God knows what, if any, performance implications that would have. So I'm not sure where that leaves me - learning functional stuff can be wonderfully mind breaking but sometimes I feel like I don't even have the tools in my head to work some things out. Is there some technique I'm missing for dealing with state between successive calls of a function? How would you solve something like this? -Brandon -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Weird nested macro problem
If I remember right from looking at clojure.contrib.condition's source (which I did because I wrote a similar error handling lib, which has a few extra features but isn't ready for prime time)... handle doesn't actually exist as a function or macro. It doesn't expand - the handler-case macro looks for it and basically drops the symbol handle and uses the rest of the form to create a function. I would think the unquote-quote should leave handle unqualified and do the right thing, but apparently not. https://github.com/richhickey/clojure-contrib/blob/ec6a7579d6b1c0bfa42e3666cfad196cffc966fe/src/main/clojure/clojure/contrib/condition.clj#L71 I believe somehow the (= 'handle (first %)) comparison on line 92 is returning false on your handle form. I am not sure why. But that might be worth exploring at the repl. Jeff On Feb 1, 4:09 pm, Straszheim, Jeff jstra...@akamai.com wrote: So, I have a macro that looks something like this: (defmacro test-failure [ forms] `(handler-case :type ~@forms (~'handle :error/error (println error happened (My real macro is more complex, but this gives the idea.) If I eval (test-failure (println test)) I get: = Unable to resolve symbol: handle in this context However, if I macroexpand-1 the thing, I get: (macroexpand-1 '(test-failure (println test))) = (clojure.contrib.condition/handler-case :type (println test) (handle :error/error (clojure.core/println error happened))) That is correct, and if I eval just that it works fine. Here is an interesting thing: if I do this: (macroexpand '(test-failure (println test))) I get = (try (println test) (handle :error/error (clojure.core/println error happened)) (catch clojure.contrib.condition.Condition c__19__auto__ (clojure.core/binding [clojure.contrib.condition/*condition-object* c__19__auto__ clojure.contrib.condition/*condition* (clojure.core/meta c__19__auto__) clojure.contrib.condition/*selector* (:type (clojure.core/meta c__19__auto__))] (clojure.core/cond :else (clojure.contrib.condition/raise) It's expanded the handler-case part, but the handle is still there. That seems wrong to me. I've tried lots of different ways to specify handle besides ~'handle, but they all seem to fail. Any suggestions? -- 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
Error handling implementation - looking for criticisms and suggestions
I'd been shopping around for an error handling kit for Clojure. What I needed was: * The ability to specify error handlers at the caller's level, that are accessible all the way up the stack from them. * Ability to include more data in an error than just a message and stack trace. That data should be accessible to handlers. * The ability to specify pre-defined methods of recovering from an error, at any point on the stack between the caller and the origin of the error. The caller can select the recovery method by name. * Ability to handle errors by type, in a hierarchical fashion, similar to java's catch. * Compatibility with java exceptions. * Ability to nest hander forms * No AOT compilation if I can help it. Chouser's error-kit offers this, but Chouser himself told me I probably shouldn't use it unless I needed all the features, like continue-with. I didn't need continue-with, and I figure if the author warns you away from a lib, probably best to listen :) I also took a look at clojure.contrib.condition, but it doesn't allow you to specify pre-defined recoveries, and requires AOT compilation. So I took a stab at it myself: https://gist.github.com/745223 It's not polished at all yet - please don't use it for anything important! I wanted to see if you all had any suggestions or criticisms before I went any further. Changes to the gist are most welcome :) Some notes: * Uses javax.naming.NamingException internally - because it is an existing exception class that has a getter/setter that takes Object. This is just a hack to store clojure types in the exception and have them travel down the stack. I wanted to avoid adding my own java exception class like clojure.contrib.condition had to do. I could still do that without a lot of changes. * Makes use of 'binding' internally to store handlers. That allows nested with-handler forms. * Adding recoveries to a java exception is not working, but it should be a simple fix once i track down the problem. Jeff -- 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
Re: parameters destructuring sets?
On Dec 5, 2:10 pm, Alex Ott alex...@gmail.com wrote: Re jweiss at Sun, 5 Dec 2010 10:29:41 -0800 (PST) wrote: j I'm no expert on this, but i'll take a crack at it. j I think it's because sets don't (necessarily) impose any order, so j there's no concept of first or nth. So destructuring would j essentially be assigning a random item to x, or for join, joining them j in random order. Sometimes, order doesn't matter, for example, I want to print data from set (or any collection that is transformable into sequence), using some separator between elements... For some operations we can't also predict order, for example, conj behaves differently for lists and vectors -- With best wishes, Alex Ott, MBAhttp://alexott.blogspot.com/ http://alexott.net/http://alexott-ru.blogspot.com/ Skype: alex.ott If you wanted to, for example, print a set with separators in between, would you need to use destructuring? I'd just do (apply str (interpose , #{:a :b :c}) - :a,:b,:c I don't think conj adding to the front for lists and the end for vectors is unpredictable at all. I know that (conj '(1 2) 3)) - (3 1 2) and (conj [1 2] 3) - [1 2 3] before I even type it on a REPL. That's totally different than nth for a set being undefined. It's undefined on purpose. Now, if you are using a sorted-set, then you have a point there, I would expect that nth means something then. But yeah, clojure doesn't let you call nth on it directly, you have to make a seq out of it first. Not sure what the performance implication is there, but it's not much effort to write: (nth (sequence (sorted-set 1 3 2)) 2) - 3 I will let people who are more knowledgeable comment on why there's no nth on a sorted-set. -- 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