Re: Try/Catch Recur
Why does that work? The same recursion happens in the finally. There's a layer of indirection now, but the doseq was already a layer of indirection between the finally and doseq's internal recur. I see from the linked thread above that the basic issue is a known implementation issue with Clojure to limit complexity - given that, perhaps doseq (and any other out-of-the-box macros/functions that are internally implemented with recur, or otherwise trigger that exception) should be documented as having this effect. -- 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: Try/Catch Recur
doseq is a macro, not a function, and its expansion expands the loop right in place : Right. Why does it work (in the finally block) when wrapped up in a function, but not when doseq is called directly? -- 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
Try/Catch Recur
I have a function foo which uses tail recursion: (defn foo [] (recur)) I need to do some clean-up work after foo (there is an external binding that requires some post-foo processing), and this needs to happen even if foo fails. The naive approach was: (try (foo) (finally (clean-up)) However, foo recurs and you can't recur in a try/catch/finally. (java.lang.UnsupportedOperationException: Cannot recur from catch/ finally) So, my question is: does anyone have a pattern for exception checking (this same issue would work if I just wanted to catch an exception in foo) when the contents of the try block recur? I could just remove the tail recursion and go for straight recursion in foo, but there's got to be a better way... -- 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: Try/Catch Recur
Thanks to both of you for the replies. Adrian, I like the in-line loop- recur. Cuppo, that example is essentially the same one that I was describing but it was key to helping me, as I saw that it evaluated fine when I expected it to fail based on my original problem. Turns out that the problem was my finally clause contained a doseq, which apparently uses tail recursion internally. Replacing that with a for will solve the problem for me. -Greg -- 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: Try/Catch Recur
Actually, the for didn't work for me either but I believe that was a lazy evaluation issue. The doseq seems to use internal recursion, which breaks the try/finally. My final solution was to build up doseq functionality with reduce. See below: (defn foo1 [] (try (println body) (finally (doseq [x (range 3)] (println x) (defn foo2 [] (try (println body) (finally (for [x (range 3)] (println x) (defn foo3 [] (try (println body) (finally (reduce (fn [y x] (println x)) () (range 3) - The foo1 definition can't be evaluated b/c of java.lang.UnsupportedOperationException: Cannot recur from catch/ finally user= (foo2) body nil user= (foo3) body 0 1 2 nil -- 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: What are people using Clojure for?
I've been using Clojure for a great deal of what I code for the last 6 months or so, both professionally and personally. (And plan to make an appropriate donation through my company once we've monetized the Clojure-based product). In particular, we've created a data integration tool coded in Clojure, and running on top of a Hadoop stack. The concurrency safety has been helpful, and functional techniques keep it safe - we certainly could have written the code in Java, but functional technique would still help out with thread safety. The biggest benefit, though, has been the productivity of an interactive Lisp environment while still keeping compatibility with Java libraries. -Greg --~--~-~--~~~---~--~~ 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: Oracle and Clojure
Has anyone here been able to install Clojure on IcedTea? For what it's worth, I run Clojure on SoyLatte and have never had a problem. --~--~-~--~~~---~--~~ 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 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: Is Clojure production ready?
If you maintain some discipline in your engineering process, then there's very little risk due to the specific library (and if you don't keep a high level of discipline, then you're finished before you start). - Test the h*ll out of everything. If there are bugs in Clojure that affect you you'll find them just as if they were bugs in your own code. You could look at Clojure as just another Java library with the JVM being the base technology. - Don't let people use arbitrary versions of Clojure and Java (and Contrib, if you'll use it). Pick one, package it with your project, and then leave it alone. If your code works, you don't need the latest version of Clojure. If there's a feature or patch you need that requires an upgrade, do a full regression test. --~--~-~--~~~---~--~~ 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 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: Contribs with dependencies
Are there strong feelings against moving away from a centralized contrib repository in favor of a directory (probably on clojure.org) of independent projects? Seems to me that this simplifies the matter of getting just the libraries you need without having to worry about unrelated dependencies, and without imposing those dependencies on other unrelated libraries. Even without dependencies, I now have to include (without dicing up the jar repackaging) all the libraries in clojure contrib just to use one of them... --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
in-ns in bootstrap
I have a bootstrap file (executed either on the command line or via user.clj) that contains an in-ns call, along with other stuff that I have verified working (e.g. println statements). I'd like the bootstrap file to leave the REPL in whatever namespace I last specified with my in-ns. But I'm getting different (unexpected) results in two cases. Case 1: Slime: the in-ns is ignored (although expressions around it are evaluated), and my repl is in the user ns. Case 2: Command-line (java ... clojure.main -i ./bootstrap.clj -r) the repl prints user-, but is actually in the correct namespace (I can execute functions defined in that namespace directly, without explicitly in-ns from the repl command line). Any ideas how to get the repl to start in a different NS than user and why I'm seeing different behavior in my two cases? thanks, Greg --~--~-~--~~~---~--~~ 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 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: in-ns in bootstrap
On Apr 13, 4:50 pm, Stephen C. Gilardi squee...@mac.com wrote: % java -cp clojure.jar clojure.main -e (in-ns 'funky-ns) --repl #Namespace funky-ns funky-ns= Worked perfectly, thanks! Regarding your Case 2 where it appeared you were actually in a namespace other than the one shown in the prompt, that's very unlikely. *ns* is the one true place (in a given thread at a given time) where the current namespace is stored. Could it be some code you loaded referred to or used the non-user namespace thereby bringing its names into user? Yeah, that's it - I did have a use... sorry, should have caught that one myself! --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Static blocks via gen-class
Does anybody know if there's a way to coerce gen-class into creating a static block in the generated class? thanks, Greg --~--~-~--~~~---~--~~ 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 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: Gen-class, extending a parameterized type
That's exactly what I did; no issues. Thanks! On Mar 31, 1:47 pm, Stuart Sierra the.stuart.sie...@gmail.com wrote: As an interim solution, you could write a wrapper class in Java that extends the parameterized class, then extend that class in Clojure. -Stuart --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Gen-class, extending a parameterized type
I need to extend an abstract Java class with a generic type, ala: public abstract class FooT {} I tried the syntax (gen-class :name fooImpl :extends com.x.FooT) and get java.lang.ClassNotFoundException: com.x.FooT Without the T I'd get: a RuntimeException complaining that I'm extending the raw type instead of the parameterized type. Any suggestions? thanks, Greg --~--~-~--~~~---~--~~ 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 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: Setting up Clojure on OS X
Aquamacs is probably your editor of choice on OSX; then follow standard emacs/slime instructions as per the other links... On Mar 30, 8:59 am, Sean francoisdev...@gmail.com wrote: Mark, This is a great writeup on installing clojure. As an OSX nerd, my main problem is getting an editor up and running. Maybe you could add a section on setting up an editor? I know the wiki was a good place to start. On Mar 30, 7:02 am, Mark Reid mark.r...@gmail.com wrote: Hi, I've just written a blog post describing how I set up Clojure on my Mac: http://mark.reid.name/sap/setting-up-clojure.html My main aims were to make it easy to configure the classpath for various projects while still having a single Clojure command I can run from anywhere to open a interactive session or run a script. Hopefully others might find this useful as well. Feedback is appreciated as I am new to Clojure and acutely aware that I may not be doing things in the most elegant way. Mark --http://mark.reid.name --~--~-~--~~~---~--~~ 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 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: Request for Discussion: changing lib root directory calculation to improve load/:load
I see that a lib section has been added to the Clojure site since I was last there, which is a good major step. I think that it may be useful to add a section there explicitly describing the differences from standard Java packaging, perhaps adding a Java package example to compare against the lib example that's already there. Also, a link from the namespace section on the site to the lib section might help hammer home that the two are related. follow Java packages, but it is a subtle paradigm shift for people coming from Java that seems to regularly pop up as a point of confusion. That's good to keep in mind. Do you have any suggestions for the docs around this that would have been helpful to you or might be to others from a Java background? --Steve --~--~-~--~~~---~--~~ 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 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: Ways of making a Clojure program?
Hi Tim, The REPL is your tool for working with your program, debugging, tuning, etc. But it's not your primary source repository! You'll keep your source in a file hierarchy, organized by namespace (similar to a Java package, albeit with subtle differences). As you're working with the source, you can evaluate expressions, play with state, etc. directly in the REPL so that you can do iterative coding without having to stop and rebuild your application every time. Look into Clojure's namespace packaging; specifically, if you have a namespace called foo.on.you then you'd want a file that defines the namespace with a (ns foo.on.you) located at /foo/on/you.clj. That file can then load others that belong to the same namespace with something like (load bar) for the file /foo/on/bar.clj. When it comes to production deployment a REPL can be a handy tool to have (as per some other threads on this group), but your primary vector is to compile the clojure source into .class files and package it in a jar just as any other Java app (rather than running from REPL + source). Hope this helps, Greg On Jan 29, 8:03 am, timc timgcl...@gmail.com wrote: I'm struggling to understand exactly what form(s) a Clojure program can take. In particular, the empty section The REPL and main entry points on the clojure.org web site doesn't help. Obviously, interacting manually with the REPL is nice for learning the language, but this becomes tedious as the size of the source increases. So the question is: what are the different ways that one can run or package up a Clojure/Java program, so that it is invoked by running a shell (or DOS cmd) script? I have got the book by Stuart Holloway, but that does not address this issue (in its present revision). Are there any tools to perform this packaging up? I have been trying to use the clojure-dev Eclipse plugin but that does not seem to be working yet. I work on Windows (using Eclipse) and want to avoid using Emacs, which I find pretty vile (largely because there does not seem to be an explanation of it that works). I apologize if I'm being really dense! I really like the smell of this language and want to use it for real applications. Regards, Tim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Ways of making a Clojure program?
Oh, to make sure I answered your direct questions: increases. So the question is: what are the different ways that one can run or package up a Clojure/Java program, so that it is invoked by running a shell (or DOS cmd) script? Compile the clojure files (or not) and package them in a .jar. I typically leave a bootstrap.clj file in the jar as well (regardless of compilation) to perform initial function evaluations and run with: java -cp ./clojure.jar:./myapp.jar clojure.main -i ./bootstrap.clj -r That's not the only way - you could also use some of Clojure's gen- class capabilities to generate an entry point with a main() method... Are there any tools to perform this packaging up? Same choices as you would use for pure Java. I use Ant. I saw another thread on the group in recent days about an Ant wrapper implemented in Clojure that might be a good choice as well (I'm looking forward to trying this out when I have some time). --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Distributed Clojure
One of Clojure's big selling points (obviously) is the support for concurrent programming. However, the performance gains you get with this concurrency hits a scalability wall once you're fully utilizing all the cores available in your server. The next step, of course, is to add additional servers. So, I've been mulling over the idea of putting together a framework for distributed applications. I think it should deal with issues such as: * Locating, assessing, and registering CPUs * Division of large jobs into smaller sub-jobs * Dispatching of jobs, including optimization planning (send more jobs to faster CPUs) * Failure recovery * Seamless code integration (so that this can be retrofit as an optimization) both horizontally and vertically * Horizontal = take one time-consuming task and parallelize it * Vertical = take two sequential tasks and pipeline them across different servers Is anybody already working on something similar? Is this already on the Clojure language roadmap as something to be added after 1.0? Any design advice or feature requests if I were to put something like this together? -Greg --~--~-~--~~~---~--~~ 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 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: Distributed Clojure
Agreed; the communication layer needs to come first. Regarding serialization, specifically, I think we get that for free with s- exps (there may be some under-the-hood evaluation time necessary for remoted expressions, but [de]serialization is rarely a lightweight process). On Jan 29, 10:03 am, Konrad Hinsen konrad.hin...@laposte.net wrote: I think the very first step should be to implement the basics of distributed computing: - communication between nodes (including serialization of data) - synchronization - remote function calls --~--~-~--~~~---~--~~ 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 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: Distributed Clojure
Hank: I have looked at TC in the past, and took another look today at your suggestion. Terracotta certainly seems to have promise feature-wise, but I have to admit it's a heavier solution than I had been thinking of, and there are probably all sorts of gotchas (and reviewing old threads on the topic, a few are hinted at) when it comes to distributing some of Clojure's concurrency data structures in the shared-memory approach. Kevin: I hadn't heard of Hadoop before, but at first glance it's exactly what I'm looking for. (Thanks!) The problem I am working on is a processing pipeline for massive data sets, and that seems to be the advertised use case for Hadoop. On Jan 29, 7:14 pm, Kevin Downey redc...@gmail.com wrote: have you looked at the available java frameworks like hadoop? there is also some kind of java interface to erlang instead of reinventing the wheel again... On Thu, Jan 29, 2009 at 6:15 AM, Greg Harman ghar...@gmail.com wrote: One of Clojure's big selling points (obviously) is the support for concurrent programming. However, the performance gains you get with this concurrency hits a scalability wall once you're fully utilizing all the cores available in your server. The next step, of course, is to add additional servers. So, I've been mulling over the idea of putting together a framework for distributed applications. I think it should deal with issues such as: * Locating, assessing, and registering CPUs * Division of large jobs into smaller sub-jobs * Dispatching of jobs, including optimization planning (send more jobs to faster CPUs) * Failure recovery * Seamless code integration (so that this can be retrofit as an optimization) both horizontally and vertically * Horizontal = take one time-consuming task and parallelize it * Vertical = take two sequential tasks and pipeline them across different servers Is anybody already working on something similar? Is this already on the Clojure language roadmap as something to be added after 1.0? Any design advice or feature requests if I were to put something like this together? -Greg -- 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 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: Creating executable Jars?
A couple things: 1. I don't know about embedding jars... Instead, use the Class-Path manifest attribute to link in clojure.jar. 2. I noticed that your jar command was specifically packaging only compileexample.class. You need all 4 of those generated classes in the jar. -Greg On Jan 27, 11:01 pm, smarf haskell...@gmail.com wrote: (ns progs.comex.compileexample (:gen-class)) (defn -main [] (println (str Hello Sverker !))) (binding [*compile-path* C:\\clojure\\classes] (compile 'progs.comex.compileexample)) I compiled C:/clojure/progs/comex/compileexample.clj. I can run the program with: C:\clojure\classesjava -cp C:/clojure/clojure.jar; progs.comex.compileexample Hello Sverker! Manifest.txt says: Main-Class: compileexample.class and is finished with a newline. so how do I make it a jar? C:\clojure\classes\progs\comexdir Volume in drive C is Vista Volume Serial Number is DC46-FE33 Directory of C:\clojure\classes\progs\comex 2009-01-28 03:33 DIR . 2009-01-28 03:33 DIR .. 2009-01-27 23:47 1 101 compileexample$fn__554.class 2009-01-27 23:47 1 131 compileexample$_main__551.class 2009-01-27 23:47 1 812 compileexample.class 2009-01-27 23:47 2 431 compileexample__init.class 2009-01-28 03:31 34 manifest.txt 5 File(s) 6 509 bytes 2 Dir(s) 5 783 875 584 bytes free C:\clojure\classes\progs\comexjar cf Hmm.jar C:/clojure/clojure.jar manifest.tx t compileexample.class C:\clojure\classes\progs\comexHmm.jar C:\clojure\classes\progs\comex i get a popup : Java Virtual Machine Launcher Failed to load Main-class manifest attribute from C:\clojure --~--~-~--~~~---~--~~ 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 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: PermGen growth
I believe you, but I don't understand why. I'm doing nothing but evaluate my test function over and over. Since no new functions are being defined, why would this evaluation use any PermGen? On Jan 25, 5:57 am, Christian Vest Hansen karmazi...@gmail.com wrote: Clojure creates class not for every function call, but for every function definition. The PermGen growth you see is the REPL compiling your input, most likely. --~--~-~--~~~---~--~~ 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 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: Binding values in a list of symbols and evaluating as code
Thanks for the explanation, Meikel. My statement about anti-pattern was predicated on each call to fn[] creating a new class - I see from your explanation and from going back and re-reading Rich's old posts on this topic that I misunderstood it before. (If it did create a new class each time, I'd hold my stance on it being an anti-pattern...) However, in practical use I've found that in a deeply nested application similar to the OP's genetic programming system that removing inline function definitions in favor of explicitly defining them as top-level named functions provides a significant boost in speed and reducation in PermGen usage. I must be missing something simple, but I can't figure out why PermGen would be affected if no classes are created. I think this line of discussion might actually merge with another thread I started yesterday: http://groups.google.com/group/clojure/browse_thread/thread/67f9d2df248d3aa0 (thought they were related but I didn't want to hijack this thread...) -Greg On Jan 25, 3:38 am, Meikel Brandmeyer m...@kotka.de wrote: Every function in Clojure creates a class. So if one encounters a (fn [a b] (+ a b)) at runtime, there is simply a new class instance created, which is then .invoked with values for a and b. So the number of functions is known at compile time. Note: macros happen at compile-time, so functions generated by a macro are also known at compile-time. At runtime there is simply an instance which gets gc'd. So saying anonymous functions in general might be a sort of anti-pattern is equal to saying Vectors in general might be sort of anti-pattern, because there is nothing different happening. I didn't follow the thread in much detail, but that is what I have left in my memory: What might be an anti-pattern is using eval. Ok ok. I know eval has its uses, but using eval with fn might be an anti-pattern. From my point of view, the following is happening: One calls (eval '(fn )). Each and every call to eval creates a new class. Even for identical fn's. So what cloggs the memory are not the function instances themselves. They get gc'd. But the generated classes stay in memory. They don't go away. This is what brings down the system finally. (eval '(fn ..)) should not be a thing you should find in a long running server application. Maybe only in form of debug repl. But generating enough fn classes in that repl to bring down the server Does this make sense? Sincerely Meikel smime.p7s 5KViewDownload --~--~-~--~~~---~--~~ 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 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: PermGen growth
I see, so running (permGen) 10 times from the REPL is not the same as, say, (dotimes [_ 10] (permGen)), because there's an understood (eval) around anything executed directly in the REPL. Thanks. On Jan 25, 9:33 am, Christian Vest Hansen karmazi...@gmail.com wrote: When the reader has a top-level expression in the REPL, it gets evaluated. Evaluation goes through the Compiler which generates bytecode from your forms. Before the bytecode can be executed, it needs to be loaded into the JVM, and that happens by wrapping it in a class and loading that. On Sun, Jan 25, 2009 at 3:08 PM, Greg Harman ghar...@gmail.com wrote: I believe you, but I don't understand why. I'm doing nothing but evaluate my test function over and over. Since no new functions are being defined, why would this evaluation use any PermGen? On Jan 25, 5:57 am, Christian Vest Hansen karmazi...@gmail.com wrote: Clojure creates class not for every function call, but for every function definition. The PermGen growth you see is the REPL compiling your input, most likely. -- Venlig hilsen / Kind regards, Christian Vest Hansen. --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
PermGen growth
I'm trying to debug a problem in one of my programs in which PermGen usage grows with and during each run (cumulatively within the same REPL session) until I eventually run out get the out of memory JVM exception. So I wrote the following utility just to help me track usage while I hack: (defn permGen [] (let [beans (java.lang.management.ManagementFactory/ getMemoryPoolMXBeans)] (doseq [mx beans] (when (= Perm Gen (.getName mx)) (println (.getUsage mx)) I ran this several times in succession: gp= (permGen) #MemoryUsage init = 16777216(16384K) used = 11035288(10776K) committed = 16777216(16384K) max = 67108864(65536K) nil gp= (permGen) #MemoryUsage init = 16777216(16384K) used = 11036888(10778K) committed = 16777216(16384K) max = 67108864(65536K) nil gp= (permGen) #MemoryUsage init = 16777216(16384K) used = 11038488(10779K) committed = 16777216(16384K) max = 67108864(65536K) nil gp= (permGen) #MemoryUsage init = 16777216(16384K) used = 11040088(10781K) committed = 16777216(16384K) max = 67108864(65536K) The thing to notice is that the used PermGen has grown by 1-2K with each run (I ran it many more times than I pasted, and that growth rate seems pretty steady). What I don't understand is why. If I understand PermGen correctly, it holds class definitions. In Clojure classes are only generated with calls to fn (see http://groups.google.com/group/clojure/browse_thread/thread/2c66650b9057f760/11a09103da821264?lnk=gstq=permgen#11a09103da821264), and I don't have any sort of nested function creation inside my (permGen) function. I don't have any anonymous function definitions in my function, so what is causing the used PermGen growth? thanks, Greg --~--~-~--~~~---~--~~ 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 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: Agent as a processing queue
Thanks Tim, I'll have a look at that. To clarify my use case, I was thinking of events that can be processed sequentially but that may take a non-trivial amount of time to complete (both CPU and IO bound at different stages of processing) so it's ideal to have a thread pool to process different tasks in parallel, even though they are independent. (That's step one. Step two will be spreading that thread pool out over multiple JVMs running on different hardware). On Jan 22, 2:39 am, Timothy Pratley timothyprat...@gmail.com wrote: Hi Greg Here is a proof of concept of one approach you could take:http://groups.google.com/group/clojure/web/job-queue.clj A set of agents are maintained to represent computation jobs. When the results are gathered, the agent is thrown away. I think using multiple agents in this way could be quite convenient as it means the jobs can be done in parallel. If you run the script from the command line you should get something like this: C:\javaclj job-queue.clj (4 3) (0 nil Hi mum) Which are the results of multiple queued computations taken at two subsequent points in time. From your post it wasn't clear to me if your 'events' imply sequential processing (which could be achieved with a single agent). Regards, Tim. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Agent as a processing queue
I like the example, and I should be able to adapt it. I do have one question about the example (probably not related to agents: ; queue up some work to be done (defn add-job [func] (let [a (agent nil)] (send a (fn [_] (func))) (swap! jobs #(conj %1 a What is the notation fn [_]? I can't seem to find any documentation for what _ as a function argument means... On Jan 22, 6:14 am, Greg Harman ghar...@gmail.com wrote: Thanks Tim, I'll have a look at that. To clarify my use case, I was thinking of events that can be processed sequentially but that may take a non-trivial amount of time to complete (both CPU and IO bound at different stages of processing) so it's ideal to have a thread pool to process different tasks in parallel, even though they are independent. (That's step one. Step two will be spreading that thread pool out over multiple JVMs running on different hardware). On Jan 22, 2:39 am, Timothy Pratley timothyprat...@gmail.com wrote: Hi Greg Here is a proof of concept of one approach you could take:http://groups.google.com/group/clojure/web/job-queue.clj A set of agents are maintained to represent computation jobs. When the results are gathered, the agent is thrown away. I think using multiple agents in this way could be quite convenient as it means the jobs can be done in parallel. If you run the script from the command line you should get something like this: C:\javaclj job-queue.clj (4 3) (0 nil Hi mum) Which are the results of multiple queued computations taken at two subsequent points in time. From your post it wasn't clear to me if your 'events' imply sequential processing (which could be achieved with a single agent). Regards, Tim. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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 -~--~~~~--~~--~--~---
Agent as a processing queue
I'd like to implement a processing queue in which I'll asynchronously drop events (represented by, say, a structmap) onto a queue, and retrieve the results later. One possible approach to this could be using an agent to store the results (the agent's controlled state is a collection of results from previously processed events), and letting the agent's natural queueing when receiving near-simultaneous send/send-offs be my queue of new to- be-processed events. The function that I would have each send/send-off apply to the agent would process my structmap event and replace the agent's state with a new collection that contains the new result. Are there any gotchas with this approach - specifically with utilizing the agent's queueing (looks like a controlled-access ArrayList under the hood) and thread management as my event dispathcer, rather than getting into something more traditional like the Executor framework? I'm hoping that this is a kosher usage model... thanks, Greg --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Clojure.zip/next behavior
Take the following data structure, wrapped up with clojure.zip/seq- zip: '(+ (- 1 2) (* 3 4)) Repeatedly calling clojure.zip/next produces these nodes: + (- 1 2) - 1 2 ... The (- 1 2) is what's throwing me off. Drawing out a tree structure, I see that my nodes are + - 1 2 * 3 4 and the structure (- 1 2) is a group of nodes (arranged as a subtree), but shouldn't be a node itself. To continue what I actually want to accomplish: if I call next while loc is currently on the +, I expect to see - as my node. If I then call remove, I expect it to remove the whole sub-tree (- 1 2), since minus is a parent of 1 and 2. Am I just not understanding the node/tree paradigm the zipper implementation uses? --~--~-~--~~~---~--~~ 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 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.zip/next behavior
Christophe, thanks for your explanation. I certainly agree that is what is happening but I find it unintuitive, especially when the structure I was walking was an S-expression in which the first member of a list is understood to be an operator to which the following members are passed as arguments. As I dust off my memories of how e.g. linked lists work I see that the (- 1 2) list itself would be the first link, and then the that list has links to the -, the 1, and the 2. I guess that perhaps the takeaway from this is that an example illustrating this would be a useful addition to the API doc (the doc does discuss branch but it wasn't clear what the definition of branch was - as per my misunderstanding). On Jan 18, 4:36 pm, Christophe Grand christo...@cgrand.net wrote: Greg Harman a écrit : Take the following data structure, wrapped up with clojure.zip/seq- zip: '(+ (- 1 2) (* 3 4)) Repeatedly calling clojure.zip/next produces these nodes: + (- 1 2) - 1 2 ... The (- 1 2) is what's throwing me off. Drawing out a tree structure, I see that my nodes are + - 1 2 * 3 4 and the structure (- 1 2) is a group of nodes (arranged as a subtree), but shouldn't be a node itself. + - 1 2 * 3 4 are leaves (nodes with no children) (- 1 2) is a node with 3 children: -, 1 and 2. (+ (- 1 2) (* 3 4)) is a node with 3 children: +, (- 1 2) and (* 3 4). To continue what I actually want to accomplish: if I call next while loc is currently on the +, I expect to see - as my node. You can test with branch? to test if a node has children or not. Something like (first (drop-while branch? (iterate next loc))) must yield the next leaf. If I then call remove, I expect it to remove the whole sub-tree (- 1 2), since minus is a parent of 1 and 2. minus is a sibling of 1 and 2. If you call remove while on it, the resulting tree is: (+ (1 2) (* 3 4)) To remove (- 1 2) you have to be on the node (- 1 2). Hope this helps. Christophe --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Eval with local bindings
Meta: This thread is a revival and continuation of last month's discussion at: http://groups.google.com/group/clojure/browse_thread/thread/e1226810b6ac7bfc/8e0f53c141c26fcc?lnk=gstq=eval+binding#8e0f53c141c26fcc --- Nathan, did you ever come up with a better way to do this than using a global var? One solution is to use (binding), which still requires a global var, but gives each eval it's own binding of that var: user= (def x) #'user/x user= (def expr '(+ x 4)) #'user/expr user= (binding [x 3] (eval expr)) 7 user= x java.lang.IllegalStateException: Var user/x is unbound. (NO_SOURCE_FILE:0) --~--~-~--~~~---~--~~ 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 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: Eval with local bindings
Nathan, Just to confirm two things in eval-expr: 1. Should seq be seq? 2. It looks like you still need to a. have a global x defined to evaluate eval-expr and b. need to wrap the call to eval-expr with binding in order to get a non-global binding for x (let doesn't seem to do the trick). -Greg On Jan 17, 2:15 pm, Nathan Kitchen nathan.kitc...@gmail.com wrote: On Sat, Jan 17, 2009 at 11:06 AM, Greg Harman ghar...@gmail.com wrote: Meta: This thread is a revival and continuation of last month's discussion at: http://groups.google.com/group/clojure/browse_thread/thread/e1226810b... --- Nathan, did you ever come up with a better way to do this than using a global var? One solution is to use (binding), which still requires a global var, but gives each eval it's own binding of that var: user= (def x) #'user/x user= (def expr '(+ x 4)) #'user/expr user= (binding [x 3] (eval expr)) 7 user= x java.lang.IllegalStateException: Var user/x is unbound. (NO_SOURCE_FILE:0) I tried this approach with (binding) and I also tried creating anonymous functions from the expressions: (eval (list 'fn '[x] expr)) Creating functions didn't work for me because I used up the PermGen space in the garbage collector with all the classes created to implement them. As best I remember, I got the same outcome with (binding), even though I wasn't creating new functions. The approach that worked for me was to create my own recursive evaluation function: (defn eval-expr [expr] (cond (seq expr) (let [[op args] expr] (apply @(resolve op) (map eval-expr args))) (= expr 'x) x :else expr)) I'm still using the var x, but it's not inherent to the approach; you could easily add a map of symbols to values as an additional argument. -- Nathan --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Possible minor bug in gen-class: method name character escaping?
I think I may have found a minor issue with gen-class, but wanted to confirm with the group that I'm not just doing something stupid... (gen-class :name mypkg.foo :prefix :methods [[my-method [Object] Object]]) Results in the following method signature in the .class file: public Object my_2D_method(Object obj) { - is being written out as _2D_ -Greg --~--~-~--~~~---~--~~ 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 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: Possible minor bug in gen-class: method name character escaping?
Ah, that'll do it. Thanks. On Jan 16, 1:02 pm, Kevin Downey redc...@gmail.com wrote: - is not a Java letter or digit so it is not allowed in java method names. http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8 user= (Character/isJavaIdentifierPart (int \-)) false user= On Fri, Jan 16, 2009 at 9:56 AM, Greg Harman ghar...@gmail.com wrote: I think I may have found a minor issue with gen-class, but wanted to confirm with the group that I'm not just doing something stupid... (gen-class :name mypkg.foo :prefix :methods [[my-method [Object] Object]]) Results in the following method signature in the .class file: public Object my_2D_method(Object obj) { - is being written out as _2D_ -Greg -- 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 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: Possible minor bug in gen-class: method name character escaping?
2. If I want the Clojure functions that underlie the methods in the generated class used directly by my Clojure code as well (which I do), then I'm stuck having to either violate standard Clojure/Lisp function naming conventions in favor of Java-friendly naming or I have to write wrapper functions like: (defn myMethod [obj] (my-method obj)) Other than using the prefix and keeping the method names to one word, is there a better way? Since gen-class is used to create Java classes, it's sensible that the naming convention within the generated class be Java's. I agree that the convention inside the generated class should be a Java convention (my original post was more of an experiment than an attempt to create a working class with that signature). However, I find myself wanting to write a clojure function that can be exposed to both Clojure and Java code, and I'd like to keep them in their respective paradigms. That is, in Clojure, I don't want to have to call (.myMethod foo) when I already have (my-method) defined. And in Java, I want to just use foo.myMethod(), not have to wrap up a call to RT.var().invoke(). I know I'm being picky, but it just seems cleaner this way... --~--~-~--~~~---~--~~ 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 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: How To Load Source File
For more than just experimentation with one file, you might also want to look into lib packaging so that you can 'require' or 'use' rather than have to go down to the level of 'load' or 'load-file'. Quick summary, if your file has namespace foo.bar then package it in file / foo/bar.clj (relative to your classpath) and you can then just (require 'foo.bar) or (use 'foo.bar) See this thread for more discussion (I had this question not too long ago): http://groups.google.com/group/clojure/browse_thread/thread/f29913ee38e7930a/910434de5dc460cf?lnk=gstq=bootstrap#910434de5dc460cf -Greg 2009/1/14 Onorio Catenacci catena...@gmail.com Hi all, I'm new to Clojure and new to Lisp but not new to software development. And I feel very dumb for having to ask what seems like a very noob question but I can't seem to figure this out. If I want to load a source file into REPL it seems that I should be able to do this: (load-file filename) but when I try this with a source file in a folder on my Windows XP box, (load-file /cljhack/test1.clj) I get java.lang.Exception: Invalid token: /cljhack/test1.clj (less the quotes of course). --~--~-~--~~~---~--~~ 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 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: when performance matters
Asbjxrn, One thing that leaps out to me performance-wise is the 3 nested loops (dotimes, dotimes, loop/recur). Whatever's inside the inner loop is getting run a lot of times! General advice about reducing loop depth and computation required inside the innermost loop aside... have you looked at clojure.parallel? Seems like it might be a good fit since your algorithm is doing a lot of array processing... -Greg On Jan 14, 11:27 am, Asbjørn Bjørnstad asbj...@gmail.com wrote: I'm not complaining, but I find the topic interesting as I just tried translating a fluid dynamics algorithm to clojure. (http://www.dgp.toronto.edu/people/stam/reality/Research/pdf/ GDC03.pdf) I got no experience with this kind of stuff, it's just something I tried out for fun. So the performance I get may be as expected. Or there may be obvious ways of speeding it up that I don't see. Anyway, here is a core part of the algorithm. It's a diffusion step, this gets called 3 times and in total this takes up more than one second of cpu time on my machine which makes framerates very slow. If anyone got any improvements I'd be happy to hear about it: (def grid-size 300) (defn make-grid [] (make-array Float/TYPE (* (+ grid-size 2) (+ grid-size 2 (defn diffuse [grid diff-ratio dt] (let [a (float (* dt diff-ratio grid-size grid-size)) a4-1 (float (+ 1 (* 4 a))) grid #^floats (deref grid) diffused-grid #^floats (make-grid) line-length (int (+ grid-size 2))] (dotimes [n 20] (dotimes [y grid-size] (let [line-offset (* (inc y) line-length)] (loop [x (int 1) c (+ x line-offset)] (aset diffused-grid c (float (/ (+ (aget grid c) (* a (+ (+ (aget diffused-grid (dec c)) (aget diffused-grid (inc c))) (+ (aget diffused-grid (- c line-length)) (aget diffused-grid (+ c line-length)) a4-1))) (when ( x grid-size) (recur (inc x) (inc c))) diffused-grid)) (def foo (ref (make-grid))) (time (diffuse foo 0.00025 0.002)) -- -asbjxrn --~--~-~--~~~---~--~~ 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 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: Parameterized query with clojure.contrib.sql
Steve, Thanks much for your work. The new with-query-results seems to work quite well. Your timing is impeccable with this set of changes: I had just finished hacking out a (much uglier) version of update-values as well. (I'll switch over to using the clojure.contrib.sql versions now for a number of reasons). One suggestion/request for your next set of updates: insert-or-update- values, which will determine whether the given row exists in the database already, and then issue the appropriate insert/update statement as the case may be. This is a common paradigm that I find myself doing manually all the time with database coding in any language. I had hacked up a version of insert-or-update-values that worked (with my version of update-values I mentioned above), but it's much too ugly to post here. :-) -Greg On Jan 14, 12:03 am, Stephen C. Gilardi squee...@mac.com wrote: Hi Greg, I checked in changes to clojure.contrib.sql that are intended to address this. If you get a chance to try the updated lib, I'd appreciate hearing how it works for you and any suggestions or bug reports you may have. Thanks, --Steve smime.p7s 3KViewDownload --~--~-~--~~~---~--~~ 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 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: Parameterized query with clojure.contrib.sql
You're my personal Santa Claus today! :-) Confirmed present and working for both insert and update, using a 2 field where clause. On Jan 14, 5:14 pm, Stephen C. Gilardi squee...@mac.com wrote: I've added update-or-insert-values. I'd appreciate hearing how it works for you. --~--~-~--~~~---~--~~ 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 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: Parameterized query with clojure.contrib.sql
I couldn't figure out how to do this with the included functions/ macros in clojure.contrib.sql so I massaged with-results and do- prepared together to get this macro (with supporting fn), which seems to work. Useful addition for contrib.sql? ;; query-with-results should work just like with-results, only parameterizing query variables. (defn- get-ps Generate a prepared statement with a vector of parameters to support the query. [sql params] (let [ps (.prepareStatement (connection) sql)] (doseq [[index value] (map vector (iterate inc 1) params)] (.setObject ps index value)) ps)) (defmacro query-with-results Executes a query with parameterized results and then evaluates body with results bound to a seq of the results. Example usage: (with-connection db (query-with-results res \select * from mytable where name = ? or id = ?\ [\Foo\ 3] (println res))) [results sql params body] `(with-open [stmt# (get-ps ~sql ~params) rset# (.executeQuery stmt#)] (let [~results (resultset-seq rset#)] ~...@body))) I would have liked to eliminate the helper function and just get this all into the macro, but I burned my allotted time on it before I got that working... -Greg On Jan 9, 5:05 pm, Greg Harman ghar...@gmail.com wrote: Would someone mind posting an example of a parameterized query using clojure.contrib.sql? There are examples in the source of non- parameterized queries, and do-prepared is used to parameterize values for inserts, but I can't seem to get my form quite right for a query. thanks, Greg --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Parameterized query with clojure.contrib.sql
Would someone mind posting an example of a parameterized query using clojure.contrib.sql? There are examples in the source of non- parameterized queries, and do-prepared is used to parameterize values for inserts, but I can't seem to get my form quite right for a query. thanks, Greg --~--~-~--~~~---~--~~ 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 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: Gen-interface signature
A little time with the Clojure source and a debugger has been illuminating. In genclass.clj:gen-interface, the line: (let [options-map (apply hash-map options) results in this value for options-map: {:methods [[(quote foo) [] []]], :name mypkg.ICompileTest} It looks like (quote foo) is being taken as the literal string name, rather than evaluating to foo. And it happens that the hex ascii in the generated method name translates to: [](quote foo). Seems suspiciously like a macro-time vs fn-time thing... I will submit an issue on this see if I can work out a patch. On Jan 7, 10:39 pm, Greg Harman ghar...@gmail.com wrote: I'm playing around with gen-interface, and compiled the following: (ns mypkg.compiletest) (gen-interface :name mypkg.ICompileTest :methods [['foo [] []]]) I then used a java .class decompiler to look at the resulting .class file expecting to see an interface with a single method called foo but instead I see this: package mypkg; public interface ICompileTest { public abstract _5B__5D_ _28_quote_20_foo_29_(); } My questions: 1. Why is the method name _5B__5D_ _28_quote_20_foo_29_ instead of foo? 2. Why is the method abstract? I'm not aware of any meaning for the abstract keyword in an interface - not that that means there isn't a meaning... :-) -Greg --~--~-~--~~~---~--~~ 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 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: File organization bootstrapping
Nevermind, with a fresh start today (and perhaps more importantly, perhaps, a fresh environment) compiling seems to work fine. It works for require and for calling functions in the package(s), but the problem now is that it doesn't work for AOT from the REPL. (compile 'package1) crashes with: java.io.IOException: No such file or directory (package.clj:4) Where line 4 is the first load operation (and the load works fine if I execute it directly). If I remove the load operation altogether as a test (making a single-file package), now I get: java.io.IOException: No such file or directory (NO_SOURCE_FILE:0) As far as I can tell, this is now identical to the example that Rich gave in one of the two threads that I referenced in my earlier post. I'm not really sure how go about tracing NO_SOURCE_FILE:0... --~--~-~--~~~---~--~~ 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 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: File organization bootstrapping
This is frustrating - with a fresh REPL I'm back to the compile problem. I can't think of anything I changed that would cause it to work intermittently, and I don't know what file it's looking for... the source files are on the classpath (it requires just fine) and the directory in *compile-path* is also on the cp (via add- classpath). It's not the load operation that caused it - I removed that entirely and just put a placeholder (defn foo [] true), and the compilation still crashes on this line. On Jan 7, 10:17 am, Greg Harman ghar...@gmail.com wrote: Nevermind, with a fresh start today (and perhaps more importantly, perhaps, a fresh environment) compiling seems to work fine. --~--~-~--~~~---~--~~ 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 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: File organization bootstrapping
One solution would be to load a single file and then have that file use add-classpath to set the classpath, but add-classpath is unreliable; I've had problems getting it to work consistently and have been told in #clojure that I shouldn't be using it. Possibly the cause of the compile problem I had in my last message(s)? I'll dig around and see if I can find that thread understand what the issue with add-classpath is. My solution for the time being is to always launch via SLIME and consider that method of launching it canonical, essentially deprecating the method of launching it from the shell. But obviously this is not ideal because for some reason not everyone uses Emacs. =) Clearly the classpath belongs in the codebase so it can be used independently of how the application was launched. Beyond not using emacs, if you want something that's deployable in a server environment and not just on a development box it has to run with no human intervention ala emacs bootstrapping. I realize that emacs could be configured to automatically launch the clojure app, but that seems too hokey for a real production deployment. -Greg --~--~-~--~~~---~--~~ 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 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: File organization bootstrapping
Bingo - *compile-path* was a relative dir. Defining it as the full path did the trick. Thanks! Also, make sure the directory named by *compile-path* exists on the file system. Compilation creates subdirs, but not *compile-path* itself. --~--~-~--~~~---~--~~ 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 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: Adding user-defined state to classes created with (proxy ...)
Chouser, Do you have an example of gen-interface + proxy working together? Take a look at the following. Proxy works fine for a Java-provided interface, but not for the generated one (ICompileTest.class is being generated and is in the filesystem/classpath where expected.) (ns compiletest) (gen-interface :name ICompileTest) (proxy [java.io.InputStream] []) ; Just to make sure proxy works by itself (line 3) (proxy [ICompileTest] []) ; Line 4 --- user= (binding [*compile-path* *fusion-compile-path*] (compile 'compiletest)) java.lang.NullPointerException (compiletest.clj:4) thanks, Greg On Jan 4, 11:39 am, Chouser chou...@gmail.com wrote: It may be, but let me again mention the option of gen-interface plus proxy. Sometimes you need to produce a physical .class files of concrete types (for servlet containers, for use with android, etc.). But if that's not the case, you may prefer the simplicity of gen-interface. Then you can implement your interface in as many ways as needed using 'proxy'. --~--~-~--~~~---~--~~ 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 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: Adding user-defined state to classes created with (proxy ...)
You're calling my bluff, eh? Well, no I don't yet. Although I have been known to do some bluff-calling, in this case I was actually hoping you had done it because I need this for a project I'm working on. :-) I think the problem with your example is trying to work with classes or namespaces without any package names. This sometimes works a bit, but it's not really supported. So I put your example code into a file named my_ns/compiletest.clj, and changed it to: (ns my-ns.compiletest) (gen-interface :name my_ns.ICompileTest) (proxy [java.io.InputStream] []) ; Just to make sure proxy works by itself (line 3) (proxy [my_ns.ICompileTest] []) ; Line 4 Now compiling works fine for me: user= (compile 'my-ns.compiletest) my-ns.compiletest Yep, that works for me too. Thx. -Greg --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Gen-interface signature
I'm playing around with gen-interface, and compiled the following: (ns mypkg.compiletest) (gen-interface :name mypkg.ICompileTest :methods [['foo [] []]]) I then used a java .class decompiler to look at the resulting .class file expecting to see an interface with a single method called foo but instead I see this: package mypkg; public interface ICompileTest { public abstract _5B__5D_ _28_quote_20_foo_29_(); } My questions: 1. Why is the method name _5B__5D_ _28_quote_20_foo_29_ instead of foo? 2. Why is the method abstract? I'm not aware of any meaning for the abstract keyword in an interface - not that that means there isn't a meaning... :-) -Greg --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
File organization bootstrapping
Hi all, I'm struggling a bit with how best to organize and bootstrap a multiple-source file project so that it can be run either command-line (java -cp clojure.jar:myapp.jar ...) or by running a load method from the REPL without having to explicitly change the classpath in my user.clj before running. Currently my file structure looks like this: /bootstrap.clj /package1/foo.clj /package2/bar.clj And bootstrap.clj looks something like: (def *namespaces* '(package1/foo package2/bar)) (defn load [] (for [namespace *namespaces*] (load namespace))) This seems to work sometimes, if my REPL's working directory is / (relative to my project), but not if it's anything else (get a java.io.FileNotFoundException). So, I guess my question is: is this whole approach silly and is there a better way to bootstrap a multiple file/package project? If not, how best to tweak this? -Greg --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Website: REPL Main section?
The REPL Main section of the website doesn't have any content... not written yet, or accidental omission? http://clojure.org/repl_and_main -Greg --~--~-~--~~~---~--~~ 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 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: File organization bootstrapping
In partial answer to my own question, I found these threads helpful: http://groups.google.com/group/clojure/browse_thread/thread/bf9672989524a1bf/1f35a50643bd6325?lnk=raot http://groups.google.com/group/clojure/msg/58e3f8e5dfb876c9 Everything seems to work well, except compilation. I'll post any modifications when I solve this issue (which I may start in another thread if I remain stuck). --~--~-~--~~~---~--~~ 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 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: File organization bootstrapping
Thanks Stuart, That's a good simplification, and everything seem kosher in terms of loading from the REPL. I would like to structure my libs (package1, package2 in the example) such that they span multiple files. So the main file for the namespace/lib still needs to have load operations to get the other files for that namespace (clojure/core.clj does this, for example). It works for require and for calling functions in the package(s), but the problem now is that it doesn't work for AOT from the REPL. (compile 'package1) crashes with: java.io.IOException: No such file or directory (package.clj:4) Where line 4 is the first load operation (and the load works fine if I execute it directly). If I remove the load operation altogether as a test (making a single-file package), now I get: java.io.IOException: No such file or directory (NO_SOURCE_FILE:0) As far as I can tell, this is now identical to the example that Rich gave in one of the two threads that I referenced in my earlier post. I'm not really sure how go about tracing NO_SOURCE_FILE:0... -Greg On Jan 6, 7:56 pm, Stuart Sierra the.stuart.sie...@gmail.com wrote: Hi Greg, I think you may be working at too low a level with load. You should be able to accomplish the same thing with: (ns my-app (:require package1 package2)) (package2/start-app) my_app, package1, and package2 all need to be immediately under a directory (or JAR file) on the Java classpath. Also check out the Ant build.xml files from Clojure core and clojure-contrib. -Stuart Sierra On Jan 6, 1:11 pm, Greg Harman ghar...@gmail.com wrote: Hi all, I'm struggling a bit with how best to organize and bootstrap a multiple-source file project so that it can be run either command-line (java -cp clojure.jar:myapp.jar ...) or by running a load method from the REPL without having to explicitly change the classpath in my user.clj before running. Currently my file structure looks like this: /bootstrap.clj /package1/foo.clj /package2/bar.clj And bootstrap.clj looks something like: (def *namespaces* '(package1/foo package2/bar)) (defn load [] (for [namespace *namespaces*] (load namespace))) This seems to work sometimes, if my REPL's working directory is / (relative to my project), but not if it's anything else (get a java.io.FileNotFoundException). So, I guess my question is: is this whole approach silly and is there a better way to bootstrap a multiple file/package project? If not, how best to tweak this? -Greg --~--~-~--~~~---~--~~ 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 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: Swank in Tomcat via JSP: classpath issues
Thanks, Mike - although we had already looked at the context classloader, your explanation did provide some inspiration for a workaround. The correct classloader should be available in the JSP and so it should be possible to grab it there and pass it into Clojure as a variable (or a binding?) in the same section of the code that launches Swank. I've been hacking on this approach some tonight, although I'm not able to get an external JSP-sourced variable recognized within my slime repl (probably I'm doing something stupid here), but I'll keep poking at it as I have time. -Greg --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Swank in Tomcat via JSP: classpath issues
I tried creating a JSP to let Slime connect to a REPL running in Tomcat, as was posted here: http://groups.google.com/group/clojure/browse_thread/thread/d73efa2943179a36/dd1c84dcf658436e?lnk=gstq=jsp#dd1c84dcf658436e The JSP works in that there is an instance of swank running in Tomcat's JVM, and I can connect to it with Slime. However, the swank instance does not have any of tomcat's jars or my webapp jars (the JSP can see them, but Clojure can't). Checking the classloader's reported path in the repl, it looks like the same path I'd get if I just started swank in a new process, straight from emacs. Some initial discussion is on Anton Vodonosov's blog, as I was trying to do a diff between the version he got working and what I have, but we didn't find the answer. http://avodonosov.blogspot.com/2008/12/simpler-clojureslime-embedding.html I'm using the current builds of Clojure (1162) and Swank-Clojure. Any thoughts on what to try next? thanks, Greg --~--~-~--~~~---~--~~ 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 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: Swank in Tomcat via JSP: classpath issues
Thanks for that - I'm all up to date now. The bad news is that it didn't seem to affect my problem at all. On Dec 28, 6:58 pm, Michael Wood esiot...@gmail.com wrote: The current version of Clojure is 1185. Clojure was recently moved to Google Code: http://groups.google.com/group/clojure/browse_thread/thread/6b4a5284d... I don't know if that has anything to do with your problem, though. --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---