Re: logging
Hi ataggart, thanks for responding. For one it made me realize that the reason I wasn't getting any output by default is because I happened to have log4j in my classpath for the current project (sucked in as a dep for a sub-dependency). It's a bit frustrating that the behavior is different depending on which libraries are present, but I can see how many of these issues are the consequence of being the greatest-common-denominator for a variety of back-end libs. This is probably nice for compatibility with the Java world, bit it isn't an important requirement for me so I think I'll look into doing something else. Cheers, Jeff On Sep 15, 2:38 am, ataggart wrote: > First, c.c.logging was intended as a wrapper around some java logging > lib. There's a plethora of them, so I saw no reason to add another. > > As for "simple out of the box logging", it's there (sort of) via > java.util.logging, and it defaults writing to stdout at INFO level. > That said, I'm inclined to use log4j. > > Also take a look at the master branch[1]. There are a number of > improvements (e.g., spy now optionally takes a logging level), and the > way underlying implementations are wired in has changed entirely. > > As for a set-level, I began work on adding it, but the java logging > libraries aren't really designed to accept programmatic changes to > logging level. For example, some wrapper libraries (turtles all the > way down), like SLF4J don't even expose the implementation it wraps so > you can't drill down and fiddle with it. Or worse, in > java.util.logging the Logger object has a setLevel method, but that > won't do anything unless you alter the level of the handlers that > actually do the logging, and those handlers might actually be hanging > off of a Logger higher up in the hierarchy. > > Which brings up another problem: most logging libs support a > hierarchical model and multiple logging targets (e.g., console, > rolling file). When one is in the "com.example" namespace, and calls > (set-level! :debug) should that apply to all namespaces, only that > namespace, all subordinate namespaces? Should all handlers be > updated, only the ones that write to console? What if someone's using > a tailed a log? Which ones you choose may or may not be supportable > depending on the underlying logging implementation. > > In the end, java logging libs were designed to be configured by a file > at start-up, and there's enough complexity involved that c.c.logging > leaves that to you. On the upside, some libs (e.g., log4j) will allow > you to reload the logging configuration file. > > But as always, patches welcome. ;) > > [1]http://clojure.github.com/clojure-contrib/branch-master/logging-api.html > > On Sep 14, 10:17 am, Jeff Rose wrote: > > > > > Hi, > > I've been using my own wrapper for Java's built-in logging so far, > > but today I took a look at clojure.contrib.logging because I would > > like to start using spy. It really seems like Clojure should have > > some simple logging out of the box, but this is not the case yet. Can > > we make it a bit more user friendly? For example, why can't it log to > > the terminal with log level INFO by default? Then we could just > > require c.c.logging and use (log/info ...) or (log/spy ...). Also, > > there doesn't seem to be a clear way to set the log level. How about a > > (log/set-level :debug) type of function? > > > I'm happy to write these functions and post them on assembla or share > > a git repository, but I'm not sure how the process works. Or maybe > > I'm doing something strange. Is everyone dropping into Java interop > > to setup logging for every script? > > > -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: simplest graphics?
On Sep 14, 2010, at 4:59 PM, Alan wrote: > I think you could just keep a vector of (color,shape) pairs as an > atom, and reify a subclass of JPanel whose paint() method closes > around that atom, calling (.draw shape color). Then as long as you > call repaint every time you modify the atom, you should be done. Seems > like it's hard to see a library making this much easier, as there's > not much incidental complexity to begin with. And alpha will be > trivial, since java.awt.Color supports alpha values - you won't even > have to know about it. Thanks Alan. Following is one of my current versions, which does something similar to what you suggest, although it differs in some details. It also differs somewhat from what I originally requested insofar as it just sticks size limits and the panel object in vars, rather than allowing them to be set dynamically in a window-creating function call (although that could easily be fixed in various ways). It also has a single draw-shape function that takes a shape name as its first arg, rather than having separate functions for rectangles and ovals -- just because that also made things a little more concise. And I haven't added line-drawing to this yet. All of this could be fixed easily, but I think that this is enough for me to ask my question about minimality more concretely. The code below is still more than I would like, and I'm wondering if there's a more concise way to do this (again, without additional libraries). One way to reframe my question is to imagine that you're in front of a class (as I will be in a couple of hours :-), and you want to say "And here's how you can draw a circle in a graphics window..." and (for pedagogical reasons into which I won't digress here) you don't want to use any additional libraries or open a file with pre-written code that does magic that you haven't explained. You want to start with an empty file and literally type in the code needed to draw shapes, from scratch. You want to provide functionality sufficient to do the kind or random-shape-drawing example that I have at the bottom of the code. How little code can you get away with writing to do this? The sources of "more code than I would like" in my code below include: - All that stuff in the initialization value of my panel var. Is that really the simplest way to create a graphics window and store the reference that allows me to draw to it? - The code to store and redraw all of my shapes. I know I could clean up my representation a bit (and probably will do so to add lines, since they will have a different number of parameters), but is there some different kind of java graphics canvas that buffers automatically so that I don't have to do this explicitly myself? - The "case" in render-shape, which is there because the various more concise approaches that I thought of all founder on the fact that I can't seem to treat methods like functions, passing them and applying them, etc. Is there a more elegant approach to this? Any advice would be appreciated. Thanks! ;;; simple shape drawing code (def max-x 500) (def max-y 500) (def shapes (atom ())) (defn render-shape [g [shape-name x y h w color]] (.setColor g color) (case shape-name rect (.fillRect g x y h w) oval (.fillOval g x y h w))) (def panel (let [jp (proxy [javax.swing.JPanel] [] (getPreferredSize [] (java.awt.Dimension. max-x max-y)) (paint [g] (doall (map #(render-shape g %) @shapes] (doto (new javax.swing.JFrame "My graphics window") (.setSize max-x max-y) (.add jp) (.setVisible true)) jp)) (defn draw-shape [shape-name x y h w color] (swap! shapes concat (list (list shape-name x y h w color))) (.paint panel (.getGraphics panel))) ;; test it out by drawing a bunch of random shapes (dotimes [_ 20] (draw-shape (rand-nth '(rect oval)) (rand-int 400) (rand-int 200) (rand-int 400) (rand-int 400) (new java.awt.Color (rand-int 256) (rand-int 256) (rand-int 256) (rand-int 256 -- Lee Spector, Professor of Computer Science School of Cognitive Science, Hampshire College 893 West Street, Amherst, MA 01002-3359 lspec...@hampshire.edu, http://hampshire.edu/lspector/ Phone: 413-559-5352, Fax: 413-559-5438 Check out Genetic Programming and Evolvable Machines: http://www.springer.com/10710 - http://gpemjournal.blogspot.com/ -- 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 ensure
Encounter time. I am sitting next to Rich as I write this. Stu > Ok, I have a 1 and 2 :) > > So is it pessimistic or optimistic? So encounter time ensure or commit > time ensure? > > On Sep 14, 9:36 pm, Stuart Halloway wrote: >> Actually, the second one is basically it. (Except that I don't know the >> Oracle reference, so can't speak to that.) >> >> Stu >> >>> The first one is correct. >> >>> On Tue, Sep 14, 2010 at 3:22 PM, peter veentjer >>> wrote: >>> I have got a question about the Clojure ensure and how it actually >>> works and the documentation doesn't provide enough information. >> >>> I see a few different solutions: >> >>> 1) An optimistic approach: Once a ref is 'ensured' it is included in >>> the conflict detection set. This means that the approach is still >>> completely optimistic because 2 concurrent transactions that have the >>> same ensured ref, one of them is going to fail when the transaction >>> wants to commit. This is a commit time ensure. >> >>> 2) The other approach is a more pessimistic approach where a ref can >>> be protected against writes made by other transaction as soon as it is >>> ensured. It still allows reads to happen, but a write/ensure is going >>> to fail. It could be compared to a oracle 'select.. for update'. This >>> is an encounter time ensure. >> >>> -- >>> 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 -- 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: simplest graphics?
On Sep 15, 2010, at 8:32 AM, Lee Spector wrote: > > The code below is still more than I would like, and I'm wondering if there's > a more concise way to do this (again, without additional libraries). One way > to reframe my question is to imagine that you're in front of a class (as I > will be in a couple of hours :-), and you want to say "And here's how you can > draw a circle in a graphics window..." and (for pedagogical reasons into > which I won't digress here) you don't want to use any additional libraries or > open a file with pre-written code that does magic that you haven't explained. > You want to start with an empty file and literally type in the code needed to > draw shapes, from scratch. You want to provide functionality sufficient to do > the kind or random-shape-drawing example that I have at the bottom of the > code. How little code can you get away with writing to do this? > > [etc removed] > > ;;; simple shape drawing code > > [removed] I neglected to clear the window prior to each re-render, which shows up with intermediate alpha values. Easily remedied (changed fragment below) but this is yet another thing moving away from the "code minimality" that I'm angling for. -Lee (def panel (let [jp (proxy [javax.swing.JPanel] [] (getPreferredSize [] (java.awt.Dimension. max-x max-y)) (paint [g] (render-shape g (list 'rect 0 0 max-x max-y java.awt.Color/WHITE)) (doall (map #(render-shape g %) @shapes] (doto (new javax.swing.JFrame "My graphics window") (.setSize max-x max-y) (.add jp) (.setVisible true)) jp)) -- Lee Spector, Professor of Computer Science School of Cognitive Science, Hampshire College 893 West Street, Amherst, MA 01002-3359 lspec...@hampshire.edu, http://hampshire.edu/lspector/ Phone: 413-559-5352, Fax: 413-559-5438 Check out Genetic Programming and Evolvable Machines: http://www.springer.com/10710 - http://gpemjournal.blogspot.com/ -- 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 ensure
On Wed, Sep 15, 2010 at 10:44 AM, Stuart Halloway wrote: > Encounter time. I am sitting next to Rich as I write this. > Guaranteed or implementation detail? -- 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: simplest graphics?
This looks a lot like what I would do - I'm afraid I don't have any brilliant insights for you. I do have a couple ways you could make this smaller, though: - Instead of (atom ()) and convoluted swap! logic, what about (atom []) and (swap! shapes conj new-shape)? - Similarly don't use (list shape-name...), try [shape-name...] -- (defn render-shape [shape-name [x y w h] color]) -- (render-shape 'rect (take 4 (repeatedly #(rand-int 400))) blue) The last two combine to let you avoid writing rand-int so many times. On Sep 15, 5:32 am, Lee Spector wrote: > On Sep 14, 2010, at 4:59 PM, Alan wrote: > > > I think you could just keep a vector of (color,shape) pairs as an > > atom, and reify a subclass of JPanel whose paint() method closes > > around that atom, calling (.draw shape color). Then as long as you > > call repaint every time you modify the atom, you should be done. Seems > > like it's hard to see a library making this much easier, as there's > > not much incidental complexity to begin with. And alpha will be > > trivial, since java.awt.Color supports alpha values - you won't even > > have to know about it. > > Thanks Alan. Following is one of my current versions, which does something > similar to what you suggest, although it differs in some details. It also > differs somewhat from what I originally requested insofar as it just sticks > size limits and the panel object in vars, rather than allowing them to be set > dynamically in a window-creating function call (although that could easily be > fixed in various ways). It also has a single draw-shape function that takes a > shape name as its first arg, rather than having separate functions for > rectangles and ovals -- just because that also made things a little more > concise. And I haven't added line-drawing to this yet. All of this could be > fixed easily, but I think that this is enough for me to ask my question about > minimality more concretely. > > The code below is still more than I would like, and I'm wondering if there's > a more concise way to do this (again, without additional libraries). One way > to reframe my question is to imagine that you're in front of a class (as I > will be in a couple of hours :-), and you want to say "And here's how you can > draw a circle in a graphics window..." and (for pedagogical reasons into > which I won't digress here) you don't want to use any additional libraries or > open a file with pre-written code that does magic that you haven't explained. > You want to start with an empty file and literally type in the code needed to > draw shapes, from scratch. You want to provide functionality sufficient to do > the kind or random-shape-drawing example that I have at the bottom of the > code. How little code can you get away with writing to do this? > > The sources of "more code than I would like" in my code below include: > > - All that stuff in the initialization value of my panel var. Is that really > the simplest way to create a graphics window and store the reference that > allows me to draw to it? > > - The code to store and redraw all of my shapes. I know I could clean up my > representation a bit (and probably will do so to add lines, since they will > have a different number of parameters), but is there some different kind of > java graphics canvas that buffers automatically so that I don't have to do > this explicitly myself? > > - The "case" in render-shape, which is there because the various more concise > approaches that I thought of all founder on the fact that I can't seem to > treat methods like functions, passing them and applying them, etc. Is there a > more elegant approach to this? > > Any advice would be appreciated. > > Thanks! > > ;;; simple shape drawing code > > (def max-x 500) > (def max-y 500) > (def shapes (atom ())) > > (defn render-shape [g [shape-name x y h w color]] > (.setColor g color) > (case shape-name > rect (.fillRect g x y h w) > oval (.fillOval g x y h w))) > > (def panel > (let [jp (proxy [javax.swing.JPanel] > [] > (getPreferredSize [] (java.awt.Dimension. max-x max-y)) > (paint [g] (doall (map #(render-shape g %) @shapes] > (doto (new javax.swing.JFrame "My graphics window") > (.setSize max-x max-y) > (.add jp) > (.setVisible true)) > jp)) > > (defn draw-shape [shape-name x y h w color] > (swap! shapes concat (list (list shape-name x y h w color))) > (.paint panel (.getGraphics panel))) > > ;; test it out by drawing a bunch of random shapes > (dotimes [_ 20] > (draw-shape (rand-nth '(rect oval)) > (rand-int 400) (rand-int 200) (rand-int 400) (rand-int 400) > (new java.awt.Color > (rand-int 256) (rand-int 256) (rand-int 256) (rand-int 256 > > -- > Lee Spector, Professor of Computer Science > School of Cognitive Science, Hampshire College > 893 West Street, Amherst, MA 01002-3359 > lspec...@hampshire.edu,http://hampshire.edu/lspector/ > Ph
Feature idea: meta-macros
The ability to use macros to do code generation and transformation is extremely useful. However, you still have to explicitly "call" the macro everywhere you want it to be used. In many scenarios, it might be desirable to do code transformation/generation on code, without explicitly modifying that code to call the macro. This could be accomplished by declaring a "meta-macro", which combines a normal macro with a function which takes a form and tests whether the macro ought to be applied. Then, somewhere in the compilation pipeline, every form is passed to the test function, and the macro applied if it returns true. Sort of like aspect-oriented programming in Java. For example, say I have a codebase that makes frequent calls to a (sql ...) function to make a query to the database. I'm tracking down an obscure performance bug, and I decide I want to log all calls to (sql...), and time how long they took. But I don't want to modify the sql function itself (it's in a third-party library), and it'd be a major pain to find and replace all the hundreds of calls to it in my codebase with a normal macro call, particularly as I'm going to want to remove it all again after I finish my analysis. Enter metamacros: (defmacro my-logger [sqlform] (do...)) ;standard macro body, wrapping a form with timing and logging code. (def-meta-macro log-sql (fn [form] (if (= sql (first form ; test function my-logger) ; macro to apply Recompile, and, poof. I've instrumented my entire program with additional functionality in a handful of lines, without impact to my existing codebase. Of course, this would be tremendously susceptible to abuse, and if used inappropriately could lead to some very, very hard-to-debug errors. I'd think long and hard before using it in production code at all (maybe even enable metamacros only with a specific compiler flag, turned off by default?) But it's also very powerful, and allows one to try new things across a codebase very easily. It's also incredibly powerful... you could run it over a whole codebase to do static analysis and transformations to improve performance, or to catch stylistic errors. Hell, in theory, you could implement the entire compiler just in metamacros ;) Any thoughts? I grant you, the potential for abuse is huge. Would the benefits outweigh it? Thanks, -Luke V. -- 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: Feature idea: meta-macros
My guess is no. It would remove a huge benefit of Clojure, which is that you can tell, without having to look over the whole codebase, exactly what a given form does. (my-thing 20 [x y]) invokes my-thing, a function or macro, with 20 as its first argument, and then a vector of locals. No need to hunt down x and y, they're in the lexical scope; no need to guess at the syntax for my-thing. If you can have magical functions that transparently adjust forms all over the codebase, it becomes extremely difficult to be sure of what some code is doing, even without "abuse". Also, metamacros would be very hard to write *right*. Two of them might compete over a chunk of code, accidentally falling into infinite co-recursion. Layering them would be very tricky, too: do you apply them before or after regular macros? If you try to do both you may end up compiling forever, alternating between different types of macro expansions. But suppose you want to write your logging function to modify all function definitions, and someone has written this code: (def call-listish (fn [fn elem] (fn [elem] 10))) How on earth will you know that the first instance of (fn [x] y) is a function declaration, and the second isn't? On Sep 15, 11:03 am, Luke VanderHart wrote: > Any thoughts? I grant you, the potential for abuse is huge. Would the > benefits outweigh it? > > Thanks, > -Luke V. -- 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: Feature idea: meta-macros
Your example can be solved with (binding ...) For the proposal, I think it's a bad idea : huge potential for abuse (and importing abuse from other namespaces written by other people) and little benefit. I wouldn't be so strongly against it if it was in a delimited scope. In any case, you can probably implement it as a library on top of the compiler, with a code walker. -- 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: Feature idea: meta-macros
Unless I misunderstand something, (binding...) wouldn't work for this because I'd have to wrap all of the code I wanted to be "modified" within a (binding...) form. Fine if it's one source file, not so fine if I have dozens... Or am I missing something? On Sep 15, 2:26 pm, Nicolas Oury wrote: > Your example can be solved with (binding ...) > > For the proposal, I think it's a bad idea : huge potential for abuse > (and importing abuse from other namespaces written by other people) > and little benefit. > > I wouldn't be so strongly against it if it was in a delimited scope. > > In any case, you can probably implement it as a library on top of the > compiler, with a code walker. -- 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: Feature idea: meta-macros
Binding uses dynamic scope, not lexical scope, right? So any functions called before the binding expires will be affected by the new bindings, not just the code explicitly within its lexical scope. On Sep 15, 11:35 am, Luke VanderHart wrote: > Unless I misunderstand something, (binding...) wouldn't work for this > because I'd have to wrap all of the code I wanted to be "modified" > within a (binding...) form. Fine if it's one source file, not so fine > if I have dozens... Or am I missing something? > > On Sep 15, 2:26 pm, Nicolas Oury wrote: > > > Your example can be solved with (binding ...) > > > For the proposal, I think it's a bad idea : huge potential for abuse > > (and importing abuse from other namespaces written by other people) > > and little benefit. > > > I wouldn't be so strongly against it if it was in a delimited scope. > > > In any case, you can probably implement it as a library on top of the > > compiler, with a code walker. > > -- 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: Feature idea: meta-macros
Oh, you're right, of course. Still, that doesn't quite meet the case I described, since the bindings won't effect any spawned threads/agents. On Sep 15, 2:47 pm, Alan wrote: > Binding uses dynamic scope, not lexical scope, right? So any functions > called before the binding expires will be affected by the new > bindings, not just the code explicitly within its lexical scope. > > On Sep 15, 11:35 am, Luke VanderHart > wrote: > > > > > Unless I misunderstand something, (binding...) wouldn't work for this > > because I'd have to wrap all of the code I wanted to be "modified" > > within a (binding...) form. Fine if it's one source file, not so fine > > if I have dozens... Or am I missing something? > > > On Sep 15, 2:26 pm, Nicolas Oury wrote: > > > > Your example can be solved with (binding ...) > > > > For the proposal, I think it's a bad idea : huge potential for abuse > > > (and importing abuse from other namespaces written by other people) > > > and little benefit. > > > > I wouldn't be so strongly against it if it was in a delimited scope. > > > > In any case, you can probably implement it as a library on top of the > > > compiler, with a code walker. -- 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: Feature idea: meta-macros
On Wed, Sep 15, 2010 at 3:35 PM, Luke VanderHart wrote: > Unless I misunderstand something, (binding...) wouldn't work for this > because I'd have to wrap all of the code I wanted to be "modified" > within a (binding...) form. Fine if it's one source file, not so fine > if I have dozens... Or am I missing something? > Hi Luke, I share this same need very often, that is, to intercept functions on the fly. For now, using (binding ..) seems to suffice because an application normally has explicit entry points, such as http request, and transformations can be placed there. We can always create wrappers to call other functions with specific bindings (for threads, etc). It's less magical, but it may be benefitial.. But it does seem less "powerfull" than javascript or AOP, where one can redefine everything. (cheers) -- 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: Feature idea: meta-macros
My suggestion is inline with other commenters: use binding. If that doesn't satisfy you, consider using or writing a preprocessor like m4. -- 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: logging
On Sep 15, 3:29 am, Jeff Rose wrote: > Hi ataggart, thanks for responding. For one it made me realize that > the reason I wasn't getting any output by default is because I > happened to have log4j in my classpath for the current project (sucked > in as a dep for a sub-dependency). If you really need logging, then log4j is probably your best bet anyway. The master branch c.c.logging docs provide a brief log4j configuration to get people going. Though the fact that deps are directly referencing log4j is a bit of a problem since you may not be using log4j, thus to benefit from the log output of the dep, you need to go through separate configuration. Solving this was ostensibly the point of apache commons-logging (and continued in c.c.logging), to allow library writers to emit logs agnostically, leaving the actual log implementation/configuration to the runtime environment. > It's a bit frustrating that the > behavior is different depending on which libraries are present, but I > can see how many of these issues are the consequence of being the > greatest-common-denominator for a variety of back-end libs. The classpath thing is an ease-of-use consideration, and was a way to allow people to keep whatever implementation they've been using (it's also how commons-logging works). You make a good point about expecting/ configuring for one implementation but another being picked up, though this would be a problem with commons-logging as well. That said, in the master branch version it's quite easy to control which implementation will be used by calling binding or alter-var-root to change the *log-factory* var, e.g.: user=> (use 'clojure.contrib.logging) nil user=> (alter-var-root #'*log-factory* (fn [& _](java-util-logging))) # >This is > probably nice for compatibility with the Java world, bit it isn't an > important requirement for me so I think I'll look into doing something > else. It's part about compatibility (in that people may already be using logging in their java code) and part about the fact that no one has written a fully functional, production-ready logging library. The latter makes sense considering there are plenty of java libs, but if you find a clojure logging implementation please let me know. The only pain-point that I've found is changing the level while in the repl, and log4j can reload the config file so it hasn't really been an issue for me. > > Cheers, > Jeff > > On Sep 15, 2:38 am, ataggart wrote: > > > > > First, c.c.logging was intended as a wrapper around some java logging > > lib. There's a plethora of them, so I saw no reason to add another. > > > As for "simple out of the box logging", it's there (sort of) via > > java.util.logging, and it defaults writing to stdout at INFO level. > > That said, I'm inclined to use log4j. > > > Also take a look at the master branch[1]. There are a number of > > improvements (e.g., spy now optionally takes a logging level), and the > > way underlying implementations are wired in has changed entirely. > > > As for a set-level, I began work on adding it, but the java logging > > libraries aren't really designed to accept programmatic changes to > > logging level. For example, some wrapper libraries (turtles all the > > way down), like SLF4J don't even expose the implementation it wraps so > > you can't drill down and fiddle with it. Or worse, in > > java.util.logging the Logger object has a setLevel method, but that > > won't do anything unless you alter the level of the handlers that > > actually do the logging, and those handlers might actually be hanging > > off of a Logger higher up in the hierarchy. > > > Which brings up another problem: most logging libs support a > > hierarchical model and multiple logging targets (e.g., console, > > rolling file). When one is in the "com.example" namespace, and calls > > (set-level! :debug) should that apply to all namespaces, only that > > namespace, all subordinate namespaces? Should all handlers be > > updated, only the ones that write to console? What if someone's using > > a tailed a log? Which ones you choose may or may not be supportable > > depending on the underlying logging implementation. > > > In the end, java logging libs were designed to be configured by a file > > at start-up, and there's enough complexity involved that c.c.logging > > leaves that to you. On the upside, some libs (e.g., log4j) will allow > > you to reload the logging configuration file. > > > But as always, patches welcome. ;) > > > [1]http://clojure.github.com/clojure-contrib/branch-master/logging-api.html > > > On Sep 14, 10:17 am, Jeff Rose wrote: > > > > Hi, > > > I've been using my own wrapper for Java's built-in logging so far, > > > but today I took a look at clojure.contrib.logging because I would > > > like to start using spy. It really seems like Clojure should have > > > some simple logging out of the box, but this is not the case yet. Can > > > we make it a bit more user friendly? For ex
Re: Feature idea: meta-macros
You can also use binding eval evil brother : alter-var-root. On Wed, Sep 15, 2010 at 8:04 PM, Richard Newman wrote: > My suggestion is inline with other commenters: use binding. If that doesn't > satisfy you, consider using or writing a preprocessor like m4. > > -- > 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 -- Sent from an IBM Model M, 15 August 1989. -- 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
stm vs. gc question
hi, people have likened stm to gc. what would then be likened to memory region inference? hrm. -- 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: stm vs. gc question
beware pushing analogies too far ? :) 2010/9/15 Raoul Duke > hi, > > people have likened stm to gc. what would then be likened to memory > region inference? > > hrm. > > -- > 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: logging
On Wed, Sep 15, 2010 at 12:23 PM, ataggart wrote: > If you really need logging, then log4j is probably your best bet > anyway. Or SLF4J, which seems to be the way many (most?) java libraries depend on a some logging library. -- 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: Feature idea: meta-macros
> consider using or writing a preprocessor like m4 Could you elaborate on that? -- 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: simplest graphics?
On Sep 15, 2010, at 1:57 PM, Alan wrote: > This looks a lot like what I would do - I'm afraid I don't have any > brilliant insights for you. I do have a couple ways you could make > this smaller, though: > > - Instead of (atom ()) and convoluted swap! logic, what about (atom > []) and (swap! shapes conj new-shape)? > - Similarly don't use (list shape-name...), try [shape-name...] > -- (defn render-shape [shape-name [x y w h] color]) > -- (render-shape 'rect (take 4 (repeatedly #(rand-int 400))) blue) > > The last two combine to let you avoid writing rand-int so many times. Thanks Alan. Using vectors instead of lists does clean things up a little. I've spent a lot of my life in other Lisps and so lists spring to mind first. FYI below is a slightly nicer version that uses vectors and also adds line drawing. I didn't follow your other suggestions because I was interested in minimizing the tool, not the example. I'd still be quite interested in any advise anyone has on minimizing the code for initializing/buffering the window (using only core, contrib, and built-in java libraries -- but maybe different built-in java libraries? I'm coming from Lisp, not from Java, and I'm not sure what's in there.) Also, this would have a smaller impact but I'm curious about it: is there a way to treat method names as data and then make calls to them, as one can with clojure functions? Then I could pass things like fillRect, or map rect to fillRect, etc. This would make things slightly simpler here but be handy in other cases... but I don't see how to do it. Thanks, -Lee -- (def max-x 500) (def max-y 500) (def shapes (atom [])) (defn render-shape [graphics [shape-name x y w h r g b a]] (.setColor graphics (java.awt.Color. r g b a)) (case shape-name rect (.fillRect graphics x y w h) oval (.fillOval graphics x y w h) line (.drawLine graphics x y w h))) (def panel (let [jp (proxy [javax.swing.JPanel] [] (getPreferredSize [] (java.awt.Dimension. max-x max-y)) (paint [g] (render-shape g ['rect 0 0 max-x max-y 255 255 255 255]) (doall (map #(render-shape g %) @shapes] (doto (new javax.swing.JFrame "My graphics window") (.setSize max-x max-y) (.add jp) (.setVisible true)) jp)) (defn draw-shape [& shape] "Adds a shape to the current drawing. The first argument should be one of the following symbols: rect, oval, or line. For rect or oval this should be followed by: x, y, width, height, red, green, blue, alpha. The x and y coordinates specify the upper right corner. Color values (including alpha, which is opacity) should range from 0 to 255. For line the arguments are the remaining arguments are x-start, y-start, x-end, y-end, red, green, blue, alpha." (swap! shapes conj shape) (.paint panel (.getGraphics panel))) ;; test it out by drawing a bunch of shapes (draw-shape 'rect 20 20 460 80 255 128 0 255) (draw-shape 'oval 120 120 300 100 100 100 0 20) (draw-shape 'oval 300 50 100 300 10 100 200 20) (draw-shape 'line 0 0 500 500 255 0 0 255) -- Lee Spector, Professor of Computer Science School of Cognitive Science, Hampshire College 893 West Street, Amherst, MA 01002-3359 lspec...@hampshire.edu, http://hampshire.edu/lspector/ Phone: 413-559-5352, Fax: 413-559-5438 Check out Genetic Programming and Evolvable Machines: http://www.springer.com/10710 - http://gpemjournal.blogspot.com/ -- 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: logging
We are speaking of two different things. SLF4J is a facade, like commons-logging (and to some extent c.c.logging). Their intent is to allow *libraries* to make logging calls, but leave the actual logging implementation up to the runtime application. This in principle allows multiple libraries' log messages to get routed using whatever implementation the ultimate application wishes. If you're the only one that's ever going to run your code, then writing java calls directly to log4j is fine, though doing that in clojure is a bit of a hassle, hence c.c.logging benefitting from delayed evaluation, etc. My earlier comment about log4j was in terms of what actually gets configured to do the work of logging messages. On Sep 15, 5:10 pm, Daniel Simms wrote: > On Wed, Sep 15, 2010 at 12:23 PM, ataggart wrote: > > If you really need logging, then log4j is probably your best bet > > anyway. > > Or SLF4J, which seems to be the way many (most?) java libraries depend > on a some logging library. -- 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