Re: swank-clojure bug fix
Hi Phil: I guess it's swank night tonight! The newer versions of slime.el changed the name of the frame-source- location-for-emacs slimefn to frame-source-location, which breaks stack trace source file viewing. This patch fixes that and adds support for finding java files in addition to the clojure ones already supported. I've also sent you a pull request. George diff --git a/swank/commands/basic.clj b/swank/commands/basic.clj index d668d2d..a1721a2 100644 --- a/swank/commands/basic.clj +++ b/swank/commands/basic.clj @@ -330,8 +330,12 @@ that symbols accessible in the current namespace go first." (defn source-location-for-frame [frame] (let [line (.getLineNumber frame) -frame-ns ((re-find #"(.*?)\$" (.getClassName frame)) 1) -filename (str (namespace-to-path (symbol frame-ns)) File/ separator (.getFileName frame)) + filename (if (.. frame getFileName (endsWith ".java")) + (.. frame getClassName (replace \. \/) (concat ".java")) + (str (namespace-to-path +(symbol ((re-find #"(.*?)\$" + (.getClassName frame)) 1))) + File/separator (.getFileName frame))) path (slime-find-file-in-paths filename (slime-search- paths))] `(:location ~path (:line ~line) nil))) @@ -373,7 +377,7 @@ that symbols accessible in the current namespace go first." (defslimefn frame-catch-tags-for-emacs [n] nil) (defslimefn frame-locals-for-emacs [n] nil) -(defslimefn frame-source-location-for-emacs [n] +(defslimefn frame-source-location [n] (source-location-for-frame (nth (.getStackTrace *current-exception*) n))) On Jul 6, 7:54 pm, Sudish Joseph wrote: > Hi, > > The patch below fixes the computation of swank-version, which broke when > (clojure-version) was defined to returned a string. The bug only > manifests itself if swank-clojure-compile-p is set to t. > > -Sudish Joseph > > From: Sudish Joseph > Date: Mon, 1 Jun 2009 19:18:11 -0400 > Subject: [PATCH] clojure-version is now a string, tweak swank-version to > match. > > --- > swank/loader.clj | 4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/swank/loader.clj b/swank/loader.clj > index 5f079f1..8a79025 100644 > --- a/swank/loader.clj > +++ b/swank/loader.clj > @@ -55,8 +55,8 @@ > (defn swank-version > "A likely bad way of calculating a version number for swank clojure" > ([] > - (+ (reduce + (map file-last-modified (swank-source-files > *swank-source-path*))) > - (clojure-version > + (str (reduce + (map file-last-modified (swank-source-files > *swank-source-path*))) > + "+" (clojure-version > > (defn delete-file-recursive [& paths] > (when-not (empty? paths) > -- > 1.6.3.1 --~--~-~--~~~---~--~~ 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: Penumbra, a new set of OpenGL bindings
On Jul 1, 8:16 am, ztellman wrote: > Most of the OpenGL code I've seen has been a fairly literal > translation of the corresponding Java, so as a way of getting my feet > wet in Clojure I've written something that tries to be a little more > idiomatic. It can be found athttp://github.com/ztellman/penumbra/tree/master > > The only really novel thing it brings to the table is intra-primitive > transformations, which means that you can update the transformation > matrix while defining a shape. It's always bothered me that OpenGL > doesn't allow this, so I added an additional transform step before > passing the coords to glVertex. This can be bypassed, but if you use > call lists it doesn't affect your performance at all. > > If anyone has any questions or thoughts, I'd be happy to hear them. Nice work. I hope you don't mind if I copy some ideas when I get around to making cloggle more idiomatic. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
logging
I've been playing around with java.util.logging - comments welcome: http://github.com/timothypratley/strive/blob/5a6d406750f3531bb1b406e528e95a8f8bdd6e75/clj/timothypratley/logging.clj http://github.com/timothypratley/strive/blob/5a6d406750f3531bb1b406e528e95a8f8bdd6e75/clj/timothypratley/test-logging.clj [2009/07/07 21:17:12 INFO]: Hello from println [main timothypratley.logging$logging-output-stream--76/fn] [2009/07/07 21:17:12 INFO]: Hello from stdout [main timothypratley.logging$logging-output-stream--76/fn] [2009/07/07 21:17:12 WARNING]: Hello from *err* [main timothypratley.logging$logging-output-stream--76/fn] [2009/07/07 21:17:12 WARNING]: Hello from stderr [main timothypratley.logging$logging-output-stream--76/fn] [2009/07/07 21:17:12 FINEST]: Hello from :finest [main test-logging/ fn] [2009/07/07 21:17:12 FINE]: DEBUG (+ 1 2)=3 [main test-logging/fn] [2009/07/07 21:17:12 FINE]: DEBUG *out*=java.io.outputstreamwri...@182bcde [pool-2-thread-1 test-logging $fn--102/fn] --~--~-~--~~~---~--~~ 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: loneclojurian at ICFP programming contest
On Tuesday 07 July 2009 02:08:57 Bradbev wrote: > On Jul 6, 4:30 pm, fft1976 wrote: > > On Jul 5, 11:42 pm, Bradbev wrote: > > > more to modern x86 chips. After you have the best algorithm for the > > > job, you very quickly find that going fast is entirely bound by memory > > > speed (actually latency) - cache misses are the enemy. > > > > IME (outside JVM), this depends strongly on the kind of problem you > > are solving as well as your implementation (you need to know how to > > cache-optimize). One can easily think of problems that would fit > > entirely in cache, but take an enormous amount of time. > > What sort of problems did you have in mind? Anything that I can think > of quickly spills the cache. There are many examples in scientific computing where many small problems are attacked instead of one large problem. For example, practical use of FFTs fall into this category with most users performing many transforms with no more than 1,024 elements rather than fewer longer transforms. Time frequency analysis usually takes n samples and produces an nxn grid over time and frequency representing the signal where each frequency is computed from a separate FFT. So you can get away with naive distribution of FFTs across cores with no regard for cache coherence and still get very good performance. This is somewhat reflected in the SciMark2 benchmark, which has small and large variants. Most people are interested in the in-cache small variant because it is more practically relevant. Cache coherence is still relevant in some of the subtasks even in the "small" case but it is a much smaller effect. I am in the process of reimplementing stock numerical algorithms (Cholesky, LU, QR, Eigenvalues) for our F# for Numerics product, written entirely in F# and parallelized using the TPL. Surprisingly, some of my F# code is 3x faster than the equivalent MATLAB for small (e.g. 100x100 matrices) problems even though MATLAB is calling directly into vendor-tuned code. For larger problems (e.g. 1000x1000 matrices), MATLAB is usually 10x faster because it is using code that was carefully optimized for cache issues. I would actually say that intercore cache effects are more important than conventional cache coherence today because you get massive performance degradation if you cock it up and it is not at all obvious when that might occur because it depends upon things like where the allocator places your data. For example, if you have cores mutating global counters then you must make sure they are spaced out enough in memory that none share cache lines. -- Dr Jon Harrop, Flying Frog Consultancy Ltd. http://www.ffconsultancy.com/?e --~--~-~--~~~---~--~~ 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: loneclojurian at ICFP programming contest
On Sunday 05 July 2009 23:19:31 fft1976 wrote: > On Jul 5, 10:53 am, igorrumiha wrote: > > I think it's safe to say that once again it's proved that Clojure > > easily matches the Java level of performance. > > I think one shouldn't generalize from one [unverified] example. > > Personally, I'll wait for Jon Harrop or someone to port the relevant > Shootout benchmarks or his "Ray tracing" benchmark to Clojure and see > what time they get and what the code looks like. That's a fantastic idea! Let's try porting my ray tracer to Clojure. Incidentally, Java's performance was extremely variable on the ray tracer benchmark. All of the other submissions I received were substantially slower than the one currently on the site. I forget why but I remember thinking it was an innocuous-looking tweak at the time... -- Dr Jon Harrop, Flying Frog Consultancy Ltd. http://www.ffconsultancy.com/?e --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Help with example from "A Field Guide to Genetic Programming"
I'm trying to write the first basic GP example in this free book: http://www.lulu.com/items/volume_63/2167000/2167025/2/print/book.pdf I've gotten a lot of the suppor methods working correctly (like fitness) but I'm having problem convering the pseudocode on page 14 for generating random expressions to make up my initial population. Here's what I have so far: (defn gen-rand-expr [functions terminals max-depth arity method] (if (or (= max-depth 0) (and (= method :grow) (< (rand) (/ (count terminals) (+ (count terminals) (count functions)) (rand-element terminals) (let [arg1 (gen-rand-expr functions terminals (- max-depth 1) arity method) arg2 (gen-rand-expr functions terminals (- max-depth 1) arity method) func (rand-element functions)] (func arg1 arg2 First, how can I print out the definition of a function in clojure? For example, if I do (defn add [x y] (+ x y)) how can inspect this definition, like (show-def add) -> (defn add [x y] (+ x y)). This would help a lot in debugging the random programs I'm trying to generate. Second, I believe the last line is the problem in my code. Let's assume the function randomly selected was +, it will run (+ 1 2) and the entire function returns 3 instead of a randomly generated syntax tree like I need. I then tried '(func arg1 arg2) hoping it would prevent evaluation, but then it will always just return (func arg1 arg2) which isn't what I need either. I need it to actually return a syntax tree made up of expressions like (+ 1 2) but unevaluated. I am guessing I need to start reading and using macros at this point? Rob --~--~-~--~~~---~--~~ 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: Mysterious ClassFormatError after simple code change.
On Mon, Jul 6, 2009 at 7:50 PM, Richard Newman wrote: > > > Since it's not apparently a simple bug in my function above, but > > something about a combination of that version of that function and > > some other part of my code, I can't think of a way to track the > > cause down short of the very tedious method of commenting out > > functions or replacing them with dummy functions (if they're called > > by the above function) and seeing which one has the property that > > commenting it out or dummy-izing it makes the error go away. > > > > That will probably take all afternoon, unfortunately; there are > > dozens of functions and over 1600 lines of code in that source file. > > Have you tried simpler things like splitting the offending function > into a separate namespace, or seeing what happens with (or without) > AOT compilation? I didn't get around to that because I accidentally fixed the bug somehow. I moved a few functions that I realized were general purpose over to a separate utils project and recompiled everything. The source file with the problem contained some of the functions I moved, and now loads correctly. It looks like one of those functions conflicted in some way with the newer version of the function posted to this thread, though I'm baffled as to how or why. None were directly called by it, or otherwise directly referenced by it, nor vice versa. --~--~-~--~~~---~--~~ 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: Mysterious ClassFormatError after simple code change.
On Mon, Jul 6, 2009 at 11:25 PM, John Harrop wrote: > On Mon, Jul 6, 2009 at 7:50 PM, Richard Newman wrote: > >> Have you tried simpler things like splitting the offending function >> into a separate namespace, or seeing what happens with (or without) >> AOT compilation? > > > I didn't get around to that because I accidentally fixed the bug somehow. I > moved a few functions that I realized were general purpose over to a > separate utils project and recompiled everything. The source file with the > problem contained some of the functions I moved, and now loads correctly. It > looks like one of those functions conflicted in some way with the newer > version of the function posted to this thread, though I'm baffled as to how > or why. None were directly called by it, or otherwise directly referenced by > it, nor vice versa. > And now it's mysteriously back after I implemented a few more functions. I can't find any obvious errors in any of the new code. Weirdly, if I copy the entire source file, paste it at the REPL, and hit enter, the error does not occur! Somehow, code that is treated as valid when compiled a function at a time is treated as invalid when compiled all at once. That pretty much proves it's an implementation bug, since the same code can't both be buggy and be fine at the same 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 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: Is this unquote dangerous?
On Jul 6, 4:00 pm, Chouser wrote: > On Mon, Jul 6, 2009 at 3:47 PM, Sean Devlin wrote: > > > I think your unquote is okay. ClojureQL does something similar. > > > However, my gut says this should be in a doseq, not a for statement. > > Could be totally wrong, tough. > > I think the OP is trying to build and return a list, not > trying to execute a series of operations. If I'm right, > then 'for' is better than 'doseq'. [snip] > I can't think of any way in which it's dangerous. Is it > important to you that the symbol become fully-qualified? If > so, then what you've got is fine -- are you writing a macro? Yes, I am! I'm slowly getting my head back into lispyness by diving head-first into writing a macro. =) I'm working on something that will approximately do: (take-ordered [3 0 1 2] coll) -> (interleave (take-nth 4 (drop 3 coll)) (take-nth 4 coll) (take-nth 4 (drop 1 coll)) (take-nth 4 (drop 2 coll))) This is a "rearranging" lazy seq operation, and the vector provided for the "pick-list" is of variable length. So I'm trying to build up a variable-length list of take-nth and drop applications in the macro substitution. There probably is an easier way to do this just with a function. I looked at interleave in core.clj and was surprised to see it wasn't a macro. So I may be making a mountain out of a mole hill, but it's all part of the learning process, right? =) Thanks for the help guys... Mike --~--~-~--~~~---~--~~ 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: Is this unquote dangerous?
(not sure where my reply to Chouser et al. went, but basically I said that I was writing a macro and I might be overdoing it. I was right!) Here's what I was trying to accomplish, but in functions, not macros: (defn slice "Returns a lazy sequence composed of every nth item of coll, starting from offset." [n offset coll] (if (= offset 0) (take-nth n coll) (take-nth n (drop offset coll (let [take-helper (fn [n slices coll] (apply interleave (map #(slice n % coll) slices)))] (defn take-slices "Returns a lazy sequence of items from coll. Items are rearranged according to non-negative indexes contained in collection slices, in blocks of size n (which defaults to (+ 1 (apply max slices)). Ex: (take-slices [3 2 1] (range 14)) -> (3 2 1 7 6 5 11 10 9) (take-slices 5 [2 0] (range 20)) -> (2 0 7 5 12 10 17 15)" ([slices coll] (take-helper (+ 1 (apply max slices)) slices coll)) ([n slices coll] (take-helper n slices coll Thanks again to everyone who replied! Mike --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Questions / guidelines for adopting Clojure
Hi all! I've been playing around with Clojure in the last couple of days. Very interesting! However, I have never used a non-OO, lispy, pure functional language before and several questions popped up while digging deeper into the Clojure world. I hope you don't mind if I post them together in one mail. Even though I will use some scala snippets for comparison, this mail is not meant to be a scala vs. clojure flamewar ;-) I think clojure is a great language and I simply want to improve my adoption path with your help ;-) * Syntax * I never used a LISP-like language before and I can't read the clojure code as fluent as code from different languages. Take for example this scala snippet: (0 until 100) map (_ * 2) filter (_ % 3 == 0) I can easily read this line from left to right (just like english) and instantly see whats going on. By contrast, I have to read the clojure version a couple of times to understand it: (filter #(= 0 (rem % 3)) (map #(* 2 %) (range 100))) Is this just a matter of pratice? Do you find it easy to read the clojure version? Also, would it make sense to have a function like this: (apply-chain (range 100) (map #(* 2 %)) (filter #(= 0 (rem % 3 apply-chain could evaluate each parameter and pass the results from left to right. Each parameter (except the first one) would be a partially applied function (if this works in clojure). I know that I could write a macro and adopt clojure to how I would like it to be. But this seems to be more a design question and I don't think that different clojure apps should use different approaches on this level. * Parametrization of "function groups" * Lets say I have a bunch of functions that provide database operations (read, write, delete, ...). They all share information about the database the operate on. In an OO language, I would define these methods in the same class and an instance variable would define the database. The advantage is, that the caller side does not need to be aware of the database name. I can create an instance somewhere and pass around the object. I can also create several objects with different database configurations. Currently I can think of 2 approaches to implement this in clojure: a) Each function also defines a database parameter The downside is that the caller needs to fill in the value every time. b) The function invocation needs be part of something else, e.g. (do- with-db "mydbname" (db-write) (db-read) ... ). Here, the caller still needs to be aware of this setting. What is the clojure way of dealing with this? Do I overvalue this problem because of my OO background? I am not asking for OO features like inheritance. My goal is simply to avoid repetition and scattering. * Dynamic typing * How would you compare the dynamic typing of clojure to e.g. Python or Ruby? I am wondering if it may be easier in clojure since the logic is not based so much on types (less structures to deal with?). I could imagine that macros help as well to minimize the typical errors people make in dynamic languages. What's your opinion? * Real-world macros * Correct me if I am wrong, but it seems that people often use macros for lazy evaluation of parameters. In Scala, it is quite easy to accomplish the same via by-name parameters. E.g. def maybe(lazyarg: => Unit) = if (...) lazyarg lazyarg will be evaluated in the if clause, not when the method 'maybe' gets invoked. I know that macros in clojure are much more powerful. But what are selling points in pratice? What is a unique feature of clojure's macro that you don't want to miss? Sorry for the long posting and thanks a lot for reading it ;-) Cheers, Roman --~--~-~--~~~---~--~~ 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: Mysterious ClassFormatError after simple code change.
On Jul 7, 2009, at 5:51 AM, John Harrop wrote: Somehow, code that is treated as valid when compiled a function at a time is treated as invalid when compiled all at once. That pretty much proves it's an implementation bug, since the same code can't both be buggy and be fine at the same time. :( It sounds a lot like you're running into limits on the size or count of something in a class file: http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html (section 4.10 limitations of the JVM) If that's true, I think Clojure should be detecting the problem and reporting it in a way that's helpful rather than generating a bad class file. Are you able and willing to make the entire Clojure source file that's failing for you available so it's feasible to track down the problem? --Steve smime.p7s Description: S/MIME cryptographic signature
Re: procedural docstring attachment
On Jul 7, 5:11 am, Timothy Pratley wrote: > I have a function that relies on a keyword being supplied. The keyword > is used to find something in a static map. I want to put in the doc- > string: > (str "blah blah blah, arg1 must be one of " (keys map)) > Suggestions? You can put the docstring directly in the metadata of the function name, where it will get evaluated: (defn #^{:doc (str "blah blah blah, arg1 must be one of " (keys map))} my-fn ...) --~--~-~--~~~---~--~~ 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: Questions / guidelines for adopting Clojure
On Tue, Jul 7, 2009 at 6:08 AM, Roman Roelofsen < roman.roelof...@googlemail.com> wrote: > > Hi all! Hello! Welcome to the group. * Syntax * > > I never used a LISP-like language before and I can't read the clojure > code as fluent as code from different languages. Take for example this > scala snippet: > > (0 until 100) map (_ * 2) filter (_ % 3 == 0) > > I can easily read this line from left to right (just like english) and > instantly see whats going on. By contrast, I have to read the clojure > version a couple of times to understand it: > > (filter #(= 0 (rem % 3)) (map #(* 2 %) (range 100))) > > Is this just a matter of pratice? Do you find it easy to read the > clojure version? I find it easier to read Clojure code when I don't have everything on one line. In other languages I've been able to put everything on one line and survive, but in CL and Clojure it has always read better on multiple lines. For instance, the code you provided could be written like: (filter #(= 0 (rem % 3)) (map #(* 2 %) (range 100))) Then the parts of the code and their relations can be easier to find. Now I can easily tell that whatever comes out of the call to map is being filtered - without caring about what is 'under' the call to map. This ability to ignore the parts that are 'inside' some deeper code has helped me in reading Clojure code. > > Sorry for the long posting and thanks a lot for reading it ;-) I don't mind the long posting. You had everything sectioned out nicely. Cheers, > > Roman Good luck with learning Clojure, I hope you continue to enjoy it.. -Rich --~--~-~--~~~---~--~~ 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: Questions / guidelines for adopting Clojure
Let me take a stab at you parametrization question > * Parametrization of "function groups" * > > Lets say I have a bunch of functions that provide database operations > (read, write, delete, ...). They all share information about the > database the operate on. In an OO language, I would define these > methods in the same class and an instance variable would define the > database. The advantage is, that the caller side does not need to be > aware of the database name. I can create an instance somewhere and > pass around the object. I can also create several objects with > different database configurations. > > Currently I can think of 2 approaches to implement this in clojure: > > a) Each function also defines a database parameter > The downside is that the caller needs to fill in the value every time. > > b) The function invocation needs be part of something else, e.g. (do- > with-db "mydbname" (db-write) (db-read) ... ). > Here, the caller still needs to be aware of this setting. > > What is the clojure way of dealing with this? Do I overvalue this > problem because of my OO background? I am not asking for OO features > like inheritance. My goal is simply to avoid repetition and > scattering. My current solution to this is to use the macro system, closures (I can never spell this right now...) and namespaces to solve this problem. Again, let's use your database question as an example. Assume we have a db with three tables *articles *comments *users We want to be able to perform CRUD on these tables. Let's start by designing a crud-utils namespace (ns crud-utils (:use clojure.contrib.with-ns)) (defn *create* [con table & params] ...) (defn *read* [con table & params] ...) (defn *update* [con table & params] ...) (defn *destroy* [con table & params] ...) Okay, assume each of those function wrap SQL as you see fit. Now, we'll add a macro to help wrap the tables. (This macro isn't complete. It's only an outline) (defmacro defmodel [con table a-ns] (let [fn-params (gensym "params_")] `(with-ns (quote ~ns) (do (def create (fn [& ~fn-params] (apply *create* ~con ~table ~fn- params))) (def read (fn [& ~fn-params] (apply *read* ~con ~table ~fn- params))) (def update (fn [& ~fn-params] (apply *update* ~con ~table ~fn- params))) (def destroy (fn [& ~fn-params] (apply *destroy* ~con ~table ~fn- params))) This macro gives us a way of currying the CRUD functions, and storing them in a namespace. Simply call the macro to create crud for each table (defmodel db-con "articles" model.articles) (defmodel db-con "comments" model.comments) (defmodel db-con "users" model.users) Now, for the last part. Switch to another ns (ns my-app (require [models [articles :as articles] [comments :as comments] [users :as users]])) (articles/create ...) ;This now inserts a record into the articles table. I have a more full fledged example working here: http://github.com/francoisdevlin/devlinsf-clojure-utils/tree/master Check out the namespace lib.devlinsf.model-utils It's still a work in progress, in desperate need of cleanup. Still, the defmodel macro works as described. Happy Hacking Sean --~--~-~--~~~---~--~~ 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: Questions / guidelines for adopting Clojure
On Tue, Jul 7, 2009 at 8:08 AM, Roman Roelofsen wrote: > > (0 until 100) map (_ * 2) filter (_ % 3 == 0) > > I can easily read this line from left to right (just like english) and > instantly see whats going on. By contrast, I have to read the clojure > version a couple of times to understand it: > > (filter #(= 0 (rem % 3)) (map #(* 2 %) (range 100))) > > Is this just a matter of pratice? Do you find it easy to read the > clojure version? Practice, yes. It often helps if you try to not get too much detail out of the initial left-to-right read, but instead just a sense of what's going on. Something like "filter something from a map over a range". Now you know where you're headed, and can read inside-out (or right-to-left) for the details. FWIW, I think it takes less knowledge to read most Clojure snippets. As with most syntaxy languages, that Scala example requires knowledge of precedence rules, grouping rules, etc. > Also, would it make sense to have a function like this: > > (apply-chain (range 100) (map #(* 2 %)) (filter #(= 0 (rem % 3 Perhaps. The idea has certainly been kicked around some. http://groups.google.com/group/clojure/browse_thread/thread/66ff0b89229be894/2e206c645c2c34e2 > * Parametrization of "function groups" * (snip) > > Currently I can think of 2 approaches to implement this in clojure: > > a) Each function also defines a database parameter > The downside is that the caller needs to fill in the value every time. > > b) The function invocation needs be part of something else, e.g. (do- > with-db "mydbname" (db-write) (db-read) ... ). > Here, the caller still needs to be aware of this setting. (a) is most like OO, and a perfectly valid option. Instead of mydb.read(x) the user would call (db-read mydb x) -- same args, just bit different order. (b) is also reasonable, and not an option in most OO languages. This allows you to mention mydb once for a whole group of calls to db-* functions. The same functions could even allow both -- (db-read x) with one arg would use *the-db* and (db-read mydb x) with two args would use mydb. > * Real-world macros * > > Correct me if I am wrong, but it seems that people often use macros > for lazy evaluation of parameters. In Scala, it is quite easy to > accomplish the same via by-name parameters. E.g. > > def maybe(lazyarg: => Unit) = if (...) lazyarg > > lazyarg will be evaluated in the if clause, not when the method > 'maybe' gets invoked. I know that macros in clojure are much more > powerful. But what are selling points in pratice? What is a unique > feature of clojure's macro that you don't want to miss? Lazy args are an approachable example, but probably not my main usage of macros. If that's all you want, 'delay' might be a better option. I use macros anytime I have patterns in my code that I want to factor out but for which functions are insufficient. I know that's a bit vague, but I'm not sure how else to generalize it. Another common use case is to move certain kinds of lookups or computation from runtime to compile time. --Chouser --~--~-~--~~~---~--~~ 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: Questions / guidelines for adopting Clojure
Hi, 2009/7/7 Chouser : > > On Tue, Jul 7, 2009 at 8:08 AM, Roman > Roelofsen wrote: >> >> (0 until 100) map (_ * 2) filter (_ % 3 == 0) >> >> I can easily read this line from left to right (just like english) and >> instantly see whats going on. By contrast, I have to read the clojure >> version a couple of times to understand it: >> >> (filter #(= 0 (rem % 3)) (map #(* 2 %) (range 100))) >> >> Is this just a matter of pratice? Do you find it easy to read the >> clojure version? > > Practice, yes. It often helps if you try to not get too > much detail out of the initial left-to-right read, but > instead just a sense of what's going on. Something like > "filter something from a map over a range". Now you know > where you're headed, and can read inside-out (or > right-to-left) for the details. > > FWIW, I think it takes less knowledge to read most Clojure > snippets. As with most syntaxy languages, that Scala > example requires knowledge of precedence rules, grouping > rules, etc. > >> Also, would it make sense to have a function like this: >> >> (apply-chain (range 100) (map #(* 2 %)) (filter #(= 0 (rem % 3 > > Perhaps. The idea has certainly been kicked around some. > http://groups.google.com/group/clojure/browse_thread/thread/66ff0b89229be894/2e206c645c2c34e2 > >> * Parametrization of "function groups" * > (snip) >> >> Currently I can think of 2 approaches to implement this in clojure: >> >> a) Each function also defines a database parameter >> The downside is that the caller needs to fill in the value every time. >> >> b) The function invocation needs be part of something else, e.g. (do- >> with-db "mydbname" (db-write) (db-read) ... ). >> Here, the caller still needs to be aware of this setting. > > (a) is most like OO, and a perfectly valid option. Instead > of mydb.read(x) the user would call (db-read mydb x) -- same > args, just bit different order. > > (b) is also reasonable, and not an option in most OO > languages. This allows you to mention mydb once for a whole > group of calls to db-* functions. The same functions could > even allow both -- (db-read x) with one arg would use > *the-db* and (db-read mydb x) with two args would use mydb. > >> * Real-world macros * >> >> Correct me if I am wrong, but it seems that people often use macros >> for lazy evaluation of parameters. In Scala, it is quite easy to >> accomplish the same via by-name parameters. E.g. >> >> def maybe(lazyarg: => Unit) = if (...) lazyarg >> >> lazyarg will be evaluated in the if clause, not when the method >> 'maybe' gets invoked. I know that macros in clojure are much more >> powerful. But what are selling points in pratice? What is a unique >> feature of clojure's macro that you don't want to miss? > > Lazy args are an approachable example, but probably not my > main usage of macros. If that's all you want, 'delay' might > be a better option. > > I use macros anytime I have patterns in my code that I want > to factor out but for which functions are insufficient. > I know that's a bit vague, but I'm not sure how else to > generalize it. Higher order functions, multimethods, etc. are already doing a great job of making Design Patterns (as per "the gang of four") a non issue in clojure. And macros can be seen as the ultimate tool to help remove the extra boiler plate, making the last x % of Design Patterns (note I wrote x and not xx, since I guess most Design Patterns issues will be solved by just using higher order functions and multimethods, so x is probably < 10%) vanishing as well. I'm still not using clojure on a daily basis at work, but one of the promises one can also get from a lisp is this real opportunity to endlessly build abstraction levels over abstraction levels, without the need to quit the language and switch to new ones. Ultimately, one could entirely get rid of all those UML *editors* + XSLT/Velocity,etc. XMI-to-Java transformers just to have the "big picture" expressed in an hypothetically more readable and maintainable "high level language" (UML graphics). With clojure, you could still find values in UML *viewers* by automating the creation of "high level pictures" of your code. But stay with one language (clojure) for high level and low level parts of your application. -- Laurent --~--~-~--~~~---~--~~ 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: Questions / guidelines for adopting Clojure
On Tue, Jul 7, 2009 at 11:47 AM, Chouser wrote: > > On Tue, Jul 7, 2009 at 8:08 AM, Roman > Roelofsen wrote: > > * Real-world macros * > > > > Correct me if I am wrong, but it seems that people often use macros > > for lazy evaluation of parameters. In Scala, it is quite easy to > > accomplish the same via by-name parameters. E.g. > > > > def maybe(lazyarg: => Unit) = if (...) lazyarg > > > > lazyarg will be evaluated in the if clause, not when the method > > 'maybe' gets invoked. I know that macros in clojure are much more > > powerful. But what are selling points in pratice? What is a unique > > feature of clojure's macro that you don't want to miss? > > Lazy args are an approachable example, but probably not my > main usage of macros. If that's all you want, 'delay' might > be a better option. > > I use macros anytime I have patterns in my code that I want > to factor out but for which functions are insufficient. > I know that's a bit vague, but I'm not sure how else to > generalize it. I would generalize that by saying you can use a macro to extract a pattern involving language keywords, or, in the case of Clojure, special forms, that are otherwise difficult to manipulate without passing a fn. For example, Java doesn't have language support like C#'s using statement for executing some block of code and deterministically cleaning up an object at the end. You could implement that as a function (in many languages) and call it like this: (defn do-and-close [o f] (try (f) (finally (.close o (let [file (FileInputStream. "todo.txt"] (do-and-close file (fn [] (do stuff with file In Clojure this was made cleaner with a simple macro, clojure.core/with-open. Usage: (with-open [file (FileInputStream. "todo.txt"] (do stuff with file)) You could write the macro yourself if it wasn't included. Programming Clojure does a good job of explaining this, as well as when not to use macros. Shawn --~--~-~--~~~---~--~~ 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: I/O in Nailgun
George Jahad writes: > I think it is just an input stream encoding problem. I think if you > change this line: > (copy (-> context .in) out) > > to this: > (copy (-> context .in InputStreamReader.) out) > > it will work. Thanks, but that gives the same result. =\ Contributing to the problem is the fact that nailgun swallows all exceptions silently, so I wrapped the call to copy in a try/catch that prints the exceptions, and I get a number of different exceptions: # # # The EOFException is the most common. -Phil --~--~-~--~~~---~--~~ 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: I/O in Nailgun
Hmmm. I'm seeing different behaviour. When I run your code untouched, I never get the "unchunked" error. Instead, I see a bunch of garbage printed after the echoed "hello" like so: echo "hello" | ng nailgun.Example hello ^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@ With the change I suggested it seems to work fine for me. I never see any "Unexpected chunk type" error or broken pipes or garbage characters. That's what made me think it was an input stream. Could it be a configuration problem? g On Jul 7, 9:18 am, Phil Hagelberg wrote: > George Jahad writes: > > I think it is just an input stream encoding problem. I think if you > > change this line: > > (copy (-> context .in) out) > > > to this: > > (copy (-> context .in InputStreamReader.) out) > > > it will work. > > Thanks, but that gives the same result. =\ > > Contributing to the problem is the fact that nailgun swallows all > exceptions silently, so I wrapped the call to copy in a try/catch that > prints the exceptions, and I get a number of different exceptions: > > # > # > # > > The EOFException is the most common. > > -Phil --~--~-~--~~~---~--~~ 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: swank-clojure bug fix
Here's a better version that handles finding inner classes in Java source: diff --git a/swank/commands/basic.clj b/swank/commands/basic.clj index d668d2d..32c01b7 100644 --- a/swank/commands/basic.clj +++ b/swank/commands/basic.clj @@ -330,8 +330,14 @@ that symbols accessible in the current namespace go first." (defn source-location-for-frame [frame] (let [line (.getLineNumber frame) -frame-ns ((re-find #"(.*?)\$" (.getClassName frame)) 1) -filename (str (namespace-to-path (symbol frame-ns)) File/ separator (.getFileName frame)) +filename (if (.. frame getFileName (endsWith ".java")) + (.. frame getClassName (replace \. \/) + (substring 0 (.lastIndexOf (.getClassName frame) ".")) + (concat (str File/separator (.getFileName frame + (str (namespace-to-path +(symbol ((re-find #"(.*?)\$" + (.getClassName frame)) 1))) + File/separator (.getFileName frame))) path (slime-find-file-in-paths filename (slime-search- paths))] `(:location ~path (:line ~line) nil))) @@ -373,7 +379,7 @@ that symbols accessible in the current namespace go first." (defslimefn frame-catch-tags-for-emacs [n] nil) (defslimefn frame-locals-for-emacs [n] nil) -(defslimefn frame-source-location-for-emacs [n] +(defslimefn frame-source-location [n] (source-location-for-frame (nth (.getStackTrace *current-exception*) n))) --~--~-~--~~~---~--~~ 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: Questions / guidelines for adopting Clojure
Shawn Hoover wrote: > For example, Java doesn't have language support like C#'s using statement > for executing some block of code and deterministically cleaning up an object > at the end. You could implement that as a function (in many languages) and > call it like this: > (defn do-and-close [o f] > (try > (f) > (finally (.close o > (let [file (FileInputStream. "todo.txt"] > (do-and-close file > (fn [] > (do stuff with file > > In Clojure this was made cleaner with a simple macro, > clojure.core/with-open. Usage: > (with-open [file (FileInputStream. "todo.txt"] > (do stuff with file)) with-open is a good, simple macro, but with a trivial example like that, I don't think it demonstrates well enough what macros can do for you that functions can't. So let's make it a bit more complicated. with-open actually supports binding *multiple* closeables that depend on each other, just like let: (with-open [file (FileReader. "test.file") buffered (BufferedReader. file)] (do-stuff-with buffered)) with-open properly closes them in the reverse order, too. compared to the function approach, which quickly gets unwieldy: (let [file (FileReader. "test.file")] (do-close file (fn [] (let [buffered (BufferedReader. file)] (do-close buffered (fn [] (do-stuff-with buffered) One might think that it's possible to have do-close accept multiple files, but there's a problem: since function arguments are evaluated when the function execution begins, any errors happening during the creation phase will not be caught and thus some streams might be left unclosed. To emulate with-open perfectly, every file would have to be passed wrapped in an anonymous function! That's a lot of boilerplate, which would make with-open pointless, as its purpose is to eliminate boilerplate. :) --~--~-~--~~~---~--~~ 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: loneclojurian at ICFP programming contest
On Jul 7, 6:23 am, Jon Harrop wrote: > On Tuesday 07 July 2009 02:08:57 Bradbev wrote: > > > On Jul 6, 4:30 pm, fft1976 wrote: > > > On Jul 5, 11:42 pm, Bradbev wrote: > > > > more to modern x86 chips. After you have the best algorithm for the > > > > job, you very quickly find that going fast is entirely bound by memory > > > > speed (actually latency) - cache misses are the enemy. > > > > IME (outside JVM), this depends strongly on the kind of problem you > > > are solving as well as your implementation (you need to know how to > > > cache-optimize). One can easily think of problems that would fit > > > entirely in cache, but take an enormous amount of time. > > > What sort of problems did you have in mind? Anything that I can think > > of quickly spills the cache. > > There are many examples in scientific computing where many small problems are > attacked instead of one large problem. For example, practical use of FFTs > fall into this category with most users performing many transforms with no > more than 1,024 elements rather than fewer longer transforms. Time frequency > analysis usually takes n samples and produces an nxn grid over time and > frequency representing the signal where each frequency is computed from a > separate FFT. So you can get away with naive distribution of FFTs across > cores with no regard for cache coherence and still get very good performance. > Interesting, I've never dealt with problems in this domain - most of my performance problems involve relatively simple transforms over streams of data. It would be quite a different mindset to program for problems that fit entirely in cache, it would be fun to try & squeeze the theoretical power out of a chip. I guess at those levels you're mostly concerned about preventing pipeline stalls & instruction conflicts. I think I'd pretty much go for handwritten assembler at those levels. > I would actually say that intercore cache effects are more important than > conventional cache coherence today because you get massive performance > degradation if you cock it up and it is not at all obvious when that might > occur because it depends upon things like where the allocator places your > data. For example, if you have cores mutating global counters then you must > make sure they are spaced out enough in memory that none share cache lines. Effects like that & cache line aliasing are difficult to diagnose without good tools. Not to mention that in most machines you have an OS scheduling other threads & polluting your cache. Brad --~--~-~--~~~---~--~~ 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: tests involving threads
On Jul 6, 5:52 am, Jarkko Oranen wrote: > My guess is that having 'is inside a future messes up the per- > thread bindings that clojure.test uses. Yes, this doesn't work because the future fn is executed in a new thread, that does not inherit the dynamic context in which the future was created. clojure.test uses dynamic bindings for counting the number of tests/assertions. So yes, the answer is to do all your assertions in the test body, not in other threads. I hope this is a special case that won't be a problem too often, since I don't see any way around it. -Stuart Sierra --~--~-~--~~~---~--~~ 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: Questions / guidelines for adopting Clojure
Thanks a lot to everbody for the great responses! They certainly helped a lot! Cheers, Roman --~--~-~--~~~---~--~~ 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: procedural docstring attachment
On Jul 7, 12:11 am, Timothy Pratley wrote: > I have a function that relies on a keyword being supplied. The keyword > is used to find something in a static map. I want to put in the doc- > string: > (str "blah blah blah, arg1 must be one of " (keys map)) > Suggestions? You can procedurally alter the doc string attached to any definition like this: (defn f [] (println "This is f.")) (alter-meta! (var f) assoc :doc "This is the docstring.") -SS --~--~-~--~~~---~--~~ 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: Calling static methods on a variable holding a class
On Jul 6, 6:59 pm, Nicolas Buduroi wrote: > Hi, I needed to call a static method on a class stored in a var > yesterday and found that it was a little bit trickier than I initially > thought. My first impression is that this is probably not the best way to go about this. Java classes are not like Ruby or Python classes; you can't just call methods on them. Using "eval" is a hack, and probably not a good idea. If you can determine, in your code, which class is needed, then do that and call the static method directly using the (ClassName/ methodName...) syntax. If you really don't know what the class is (for example, you get a Class object returned by some library function) then you can use the Java Reflection API to call the static method. See http://java.sun.com/docs/books/tutorial/reflect/ -SS --~--~-~--~~~---~--~~ 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: Calling static methods on a variable holding a class
On Jul 7, 2009, at 3:29 PM, Stuart Sierra wrote: If you really don't know what the class is (for example, you get a Class object returned by some library function) then you can use the Java Reflection API to call the static method. See http://java.sun.com/docs/books/tutorial/reflect/ If you go this route, I recommend either using or learning from the functions in clojure/src/jvm/clojure/lang/Reflector.java. Its methods are not part of Clojure's official interface, so the usual caveats about using unsupported "implementation private" code apply, but it include many useful methods for dealing with reflection from Clojure. --Steve smime.p7s Description: S/MIME cryptographic signature
Re: I/O in Nailgun
George Jahad writes: > Hmmm. I'm seeing different behaviour. When I run your code > untouched, I never get the "unchunked" error. Instead, I see a bunch > of garbage printed after the echoed "hello" like so: > > echo "hello" | ng nailgun.Example > > hello > ^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@^...@^@ > > With the change I suggested it seems to work fine for me. I never see > any "Unexpected chunk type" error or broken pipes or garbage > characters. That's what made me think it was an input stream. Turns out I was using Nailgun from SVN. Switching to the released version 0.7.1 fixed the problem. No reader was necessary for me, oddly enough. -Phil --~--~-~--~~~---~--~~ 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: loneclojurian at ICFP programming contest
On Jul 6, 6:08 pm, Bradbev wrote: > On Jul 6, 4:30 pm, fft1976 wrote:> On Jul 5, 11:42 pm, > Bradbev wrote: > > > > more to modern x86 chips. After you have the best algorithm for the > > > job, you very quickly find that going fast is entirely bound by memory > > > speed (actually latency) - cache misses are the enemy. > > > IME (outside JVM), this depends strongly on the kind of problem you > > are solving as well as your implementation (you need to know how to > > cache-optimize). One can easily think of problems that would fit > > entirely in cache, but take an enormous amount of time. > > What sort of problems did you have in mind? Anything that I can think > of quickly spills the cache. > For an extreme example, just about any NP-complete, NP-hard, EXP-hard problem may do. Who wins at checkers assuming perfect play: black or white? Answering this requires little memory and "lots" of time. Of course, a program does not need to fit in cache not to be memory- bound. --~--~-~--~~~---~--~~ 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: swank-clojure bug fix
Sudish Joseph writes: > The patch below fixes the computation of swank-version, which broke when > (clojure-version) was defined to returned a string. The bug only > manifests itself if swank-clojure-compile-p is set to t. Thanks! Applied. -Phil --~--~-~--~~~---~--~~ 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: swank-clojure bug fix
George Jahad writes: > I guess it's swank night tonight! > > The newer versions of slime.el changed the name of the frame-source- > location-for-emacs slimefn to frame-source-location, which breaks > stack trace source file viewing. > > This patch fixes that and adds support for finding java files in > addition to the clojure ones already supported. Thanks! I've pushed out the patch. -Phil --~--~-~--~~~---~--~~ 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: Is this unquote dangerous?
On Jul 6, 6:00 pm, Chouser wrote: > On Mon, Jul 6, 2009 at 4:18 PM, Meikel Brandmeyer wrote: > > Hi, > > > Am 06.07.2009 um 22:00 schrieb Chouser: > > >> Or if you really do need a list: > > >> (for [x [1 2 3]] (cons 'some-symbol (list x))) > > > o.O > > > *cough*(list 'some-symbol x)*cough* ;) > > Oh. Right. What he said. > > --Chouser Why not this? (map #(list 'some-symbol %1) [1 2 3]) or (map list (repeatedly (constantly 'some-symbol)) [1 2 3]) --~--~-~--~~~---~--~~ 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: Mysterious ClassFormatError after simple code change.
On Tue, Jul 7, 2009 at 9:30 AM, Stephen C. Gilardi wrote: > > On Jul 7, 2009, at 5:51 AM, John Harrop wrote: > > Somehow, code that is treated as valid when compiled a function at a time >> is treated as invalid when compiled all at once. That pretty much proves >> it's an implementation bug, since the same code can't both be buggy and be >> fine at the same time. :( >> > > It sounds a lot like you're running into limits on the size or count of > something in a class file: Shouldn't be. I'm not using :gen-class or similar, so the only classes generated should be ones for the individual functions, and the largest one of those works, so is not exceeding any kind of limit. Furthermore, the clojure documentation does not state any limits on function size or similar, so implies that there are none. Last but not least, a change to a single function definition's interior triggered the error. If the error was: * too large a function, a much larger function elsewhere in the file would fail; * too many names or other things in the namespace, changing a single thing's interior without adding more top-level things would not fail; * just about anything else, either something else would have failed earlier or things would have stayed working, one or the other. That compiling the functions one by one in the REPL, in the same namespace, exceeds no limits is also worthy of note. It can't be a namespace size limit then, nor can any of the individual functions be exceeding a limit. In fact, the only thing different is that a load script of sorts has to be compiled for a load-file or build, which evaluates the definitions and other instructions in order. If that's hitting some sort of limit, the ability to execute exactly the same things in the same sequence at the REPL proves that that limit can be circumvented under the hood, simply by having load-file more faithfully emulate pasting everything into a REPL set to the appropriate namespace and hitting "enter" than it apparently currently does. Is it making the load script into a single huge static method perhaps? If so, having it break such things up under the hood into several smaller ones with a driver that calls them all in sequence would fix it, or even having it break up the -init class into -init, -init2, -init3 and so forth if necessary and making these invoke one another in chains. There's really no reason I can think of for anything like this to even be affecting the user. If that's true, I think Clojure should be detecting the problem and > reporting it in a way that's helpful rather than generating a bad class > file. That much I'd agree with. > Are you able and willing to make the entire Clojure source file that's > failing for you available so it's feasible to track down the problem? > It's probably going to end up GPL'd eventually -- if I can get it to actually work and stay working -- but it's not presently in a releasable state. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Passing primitives from an inner loop to an outer loop efficiently
Problem: Passing primitives from an inner loop to an outer loop efficiently. Here is what I've found. The fastest method of result batching, amazingly, is to pass out a list and: (let [foo (loop ... ) x (double (first foo)) r1 (rest foo) y (double (first r1)) r2 (rest r1) z (double (first r2))] ... ) (here passing out three doubles). About half as fast is: (let [[x y z] (loop ... )] ... ) with (double x), (double y), and (double z) used later in place of x y z and only one occurrence of each (so no more (double foo) conversions than before). The destructuring bind apparently exerts a higher run-time overhead compared to manual destructuring. (with-locals [x (double 0) y (double 0) z (double 0)] (loop ... ) (do-something-with (double (var-get x)) (double (var-get y)) (double (var-get z is two full orders of magnitude slower (here the loop doesn't return a list but uses var-set). Using atoms is even worse. (let [#^doubles xyz (double-array (int 3))] (loop ... ) (do-something-with (aget xyz (int 0)) (aget xyz (int 1)) (aget xyz (int 2 with the loop using aset-double to pass out values is, surprisingly, no faster. Using plain aset makes no difference, as does removing the (int ...) wrappings around the numbers. Intermediate in speed is using a clojure vector to pass out values, e.g. [result-x result-y result-z] is the expression that returns a value from the loop, and (do-something-with (get results (int 0)) (get results (int 1)) (get results (int 2))) It's surprising that this is faster than using a primitive Java array with type-hints, and interesting that retrieving sequential items from a list is faster than a like number of in-order indexed retrievals from a vector, which could theoretically be optimized to a pointer-walk with each retrieval involving an increment and a dereference and a store, rather than an increment, three dereferences, and a store. (Dereference linked list entry item pointer, store, increment pointer, dereference to get next-entry pointer, dereference again, repeat.) Whatever, these results may be useful to someone, along with: (defn- extract-result-list-into [conv hint gensyms result-generator] (let [rs (take (count gensyms) (repeatedly gensym))] (into [(first rs) result-generator] (loop [r rs g (if hint (map #(with-meta % {:tag hint}) gensyms) gensyms) output []] (if (empty? r) output (let [fr (first r) rr (rest r) frr (first rr)] (recur (rest r) (rest g) (into output (concat [(first g) (if conv `(~conv (first ~fr)) `(first ~fr))] (if frr [frr `(rest ~fr)])) This helper function can be used in a macro to suck the contents of a list into variables with conversions, type hints, or both; conv would be a symbol like `double, hint something like BigInteger, gensyms some gensyms (or other symbols) for the variable names (in order), and result-generator some code (e.g. resulting from a backtick expression). The output is a vector resembling [G__5877 (loop ... whatever code) #^hint G__5874 (conv (first G__5877)) G_5878 (rest G__5877) #^hint G__5875 (conv (first G__5878)) G_5879 (rest G__5878) #^hint G__5876 (conv (first G__5879))] which can be used in a let, loop, or other construct that uses bindings with the usual clojure syntax, and can even have other things added to it by macro code. The downside is relative inflexibility. If you pass in a gensyms seq with an embedded vector of two gensyms you'll get a valid destructuring bind for a composite item in the results, but it won't work with type hints or conversions, nor can those be mixed. Making it more sophisticated would be possible, though. This arose when I had a performance-critical double-barreled loop to optimize, and found that the outer loop was spending several thousand iterations of the inner loop worth of time just to extract the results via with-locals. I did some experimenting and benchmarking of various ways to get the output of the inner loop to code in the outer loop, using System/nanoTime, millions of repetitions, and averaging to determine the winner. An efficient "labeled recur" would be nice for clojure 2.0. :) (Limited though it would be to when the inner loop was in tail position in the outer loop.) --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Implementing ISeq
Hello Clojurians--- I'm about to begin writing a Clojure wrapper for a Java data structure that's amenable to seq-ability. 1) I'd like to implement the ISeq interface. Could someone point me to some up-to-date documentation on what I need to implement? Sorry if this is covered somewhere obvious... I couldn't find it. Stu's book and the web site seem to indicate that "first," "cons," and "rest" are the important things (are they all?). Yet I see discussions online about, e.g., "next," and looking inside clojure.lang.ISeq I see cons, first, more, and next. Am I right in assuming that Clojure constructs (rest coll) out of some combination of these? Could someone shed some light on this? 2) Can one enhance the performance of the seq library by implementing more than the basics (i.e. more than [first cons rest] or [first cons more next])? Or is the whole idea that the entire edifice is built on just the basics? 3) How stable is the interface at this point? Thanks. Garth --~--~-~--~~~---~--~~ 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: Implementing ISeq
On Jul 7, 5:31 pm, Garth Sheldon-Coulson wrote: > Hello Clojurians--- > > I'm about to begin writing a Clojure wrapper for a Java data structure > that's amenable to seq-ability. > > 1) I'd like to implement the ISeq interface. Could someone point me to some > up-to-date documentation on what I need to implement? Sorry if this is > covered somewhere obvious... I couldn't find it. > > Stu's book and the web site seem to indicate that "first," "cons," and > "rest" are the important things (are they all?). Yet I see discussions > online about, e.g., "next," and looking inside clojure.lang.ISeq I see cons, > first, more, and next. Am I right in assuming that Clojure constructs (rest > coll) out of some combination of these? Could someone shed some light on > this? > > 2) Can one enhance the performance of the seq library by implementing more > than the basics (i.e. more than [first cons rest] or [first cons more > next])? Or is the whole idea that the entire edifice is built on just the > basics? > > 3) How stable is the interface at this point? > You should have a look at clojure.lang.StringSeq and clojure.lang.IteratorSeq. Deriving from ASeq as they do is the way to go. The interface is stable, and no, there are no other optimizations needed. Rich --~--~-~--~~~---~--~~ 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: Implementing ISeq
Thanks Rich, I'll take a look. By the way, Clojure is a beautiful and enriching thing. Keep up the great work. On Tue, Jul 7, 2009 at 6:21 PM, Rich Hickey wrote: > > > > On Jul 7, 5:31 pm, Garth Sheldon-Coulson wrote: > > Hello Clojurians--- > > > > I'm about to begin writing a Clojure wrapper for a Java data structure > > that's amenable to seq-ability. > > > > 1) I'd like to implement the ISeq interface. Could someone point me to > some > > up-to-date documentation on what I need to implement? Sorry if this is > > covered somewhere obvious... I couldn't find it. > > > > Stu's book and the web site seem to indicate that "first," "cons," and > > "rest" are the important things (are they all?). Yet I see discussions > > online about, e.g., "next," and looking inside clojure.lang.ISeq I see > cons, > > first, more, and next. Am I right in assuming that Clojure constructs > (rest > > coll) out of some combination of these? Could someone shed some light on > > this? > > > > 2) Can one enhance the performance of the seq library by implementing > more > > than the basics (i.e. more than [first cons rest] or [first cons more > > next])? Or is the whole idea that the entire edifice is built on just the > > basics? > > > > 3) How stable is the interface at this point? > > > > You should have a look at clojure.lang.StringSeq and > clojure.lang.IteratorSeq. Deriving from ASeq as they do is the way to > go. The interface is stable, and no, there are no other optimizations > needed. > > Rich > > > > --~--~-~--~~~---~--~~ 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: procedural docstring attachment + argument descriptions
Perfect, thanks Stuart! That works great :) I put it in a convenience macro: ; Stuart Sierra (defmacro defn-with-doc "Like defn but accepts a procedurally generated string." [fun doc-str & body] `(let [f# (defn ~fun ~...@body)] (alter-meta! (var ~fun) assoc :doc ~doc-str) f#)) Got me thinking on a different line Laurent once remarked that it would be nice to attach argument descriptions as meta data: (defmacro defn-with-args "Like defn but takes non-literal string doc, and a map of arguments instead of a vector. args should be a map of argument names to descriptions." [fun doc-str args & body] `(let [f# (defn ~fun ~(vec (map symbol (keys args))) ~...@body)] (alter-meta! (var ~fun) assoc :doc ~(str doc-str \newline " " args)) (alter-meta! (var ~fun) assoc :argdescs ~(vec (vals args))) f#)) (let [m {:one 1, :two 2}] (defn-with-args foo1 "hi1" {"in1" "must be a string", "in2" (str "must be one of: " (keys m))} (println in1 (m in2)) (m in2))) - test-extensions/foo1 ([in1 in2]) hi1 {"in1" "must be a string", "in2" (str "must be one of: " (keys m))} (println (:argdescs ^(var foo1))) [must be a string must be one of: (:one :two)] My code is almost but not quite, but you get the idea... I think this might be quite useful with a bit of improvement. I imagine Laurent is mostly interested in the arguments from an IDE perspective, but in general its nice to know precisely what arguments are expected. Also a few people have discussed the "by contract" style. Another possible extension would be to store preconditions: (def *debug* false) (defmacro check-preconditions "Ensure preconditions are met." [m] (if *debug* `(assert (apply = true (map #((val %) (key %)) ~m) (defmacro defn-by-contract "Like defn but takes non-literal string doc, and a map of arguments instead of a vector. args should be a map of strings to preconditions." [fun doc-str args & body] `(let [f# (defn ~fun ~(vec (map symbol (keys args))) (check-preconditions args) ~...@body)] (alter-meta! (var ~fun) assoc :doc ~(str doc-str \newline " " args)) (alter-meta! (var ~fun) assoc :argdescs ~(vec (vals args))) f#)) Actually preconditions should be handled completely separately perhaps as another metadata :argpreds, this code is just to illustrate a possibility. If anyone is interested in playing with this, feel free to use: http://github.com/timothypratley/strive/blob/baf83e2bb26662f5f5049d165dec31e47b91e171/clj/timothypratley/extensions.clj http://github.com/timothypratley/strive/blob/baf83e2bb26662f5f5049d165dec31e47b91e171/clj/timothypratley/test-extensions.clj Regards, Tim. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Help with example from "A Field Guide to Genetic Programming"
On Jul 7, 8:18 am, Robert Campbell wrote: > First, how can I print out the definition of a function in clojure? > For example, if I do (defn add [x y] (+ x y)) how can inspect this > definition, like (show-def add) -> (defn add [x y] (+ x y)). This > would help a lot in debugging the random programs I'm trying to > generate. > I don't think that's possible. You can use (doc add), which will give you the arity signatures of add, as well as the documentation for add, if there was any. You could, I suppose, include the function body itself in its documentation, e.g.: (defn add "(+ x y)" [x y] (+ x y)) #'user/add user=> (doc add) - user/add ([x y]) (+ x y) nil > Second, I believe the last line is the problem in my code. Let's > assume the function randomly selected was +, it will run (+ 1 2) and > the entire function returns 3 instead of a randomly generated syntax > tree like I need. I then tried '(func arg1 arg2) hoping it would > prevent evaluation, but then it will always just return (func arg1 > arg2) which isn't what I need either. I need it to actually return a > syntax tree made up of expressions like (+ 1 2) but unevaluated. > If your syntax tree is just composed of three-element lists, then instead of your definition of add, you might want this: (defn add [x y] `(+ ~x ~y)) HTH, -- Michel --~--~-~--~~~---~--~~ 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: Help with example from "A Field Guide to Genetic Programming"
It seems to me you want: user=> (list + 1 2) (# 1 2) As opposed to: user=> '(+ 1 2) (+ 1 2) Regarding examining a function, contrib has some helpers written by Chris user=> (use 'clojure.contrib.repl-utils) (source func) (show func) In your case source wont be useful as the function is generated not read from source. The output from show is a bit opaque to me so not sure if it is useful to you. I think once it is compiled a function is not easy to examine... so as you alluded to the best alternative would be to keep the AST? Regards, Tim. On Jul 7, 10:18 pm, Robert Campbell wrote: > I'm trying to write the first basic GP example in this free > book:http://www.lulu.com/items/volume_63/2167000/2167025/2/print/book.pdf > > I've gotten a lot of the suppor methods working correctly (like > fitness) but I'm having problem convering the pseudocode on page 14 > for generating random expressions to make up my initial population. > Here's what I have so far: > > (defn gen-rand-expr [functions terminals max-depth arity method] > (if (or (= max-depth 0) (and (= method :grow) (< (rand) (/ (count > terminals) (+ (count terminals) (count functions)) > (rand-element terminals) > (let [arg1 (gen-rand-expr functions terminals (- max-depth 1) arity > method) > arg2 (gen-rand-expr functions terminals (- max-depth 1) arity > method) > func (rand-element functions)] > (func arg1 arg2 > > First, how can I print out the definition of a function in clojure? > For example, if I do (defn add [x y] (+ x y)) how can inspect this > definition, like (show-def add) -> (defn add [x y] (+ x y)). This > would help a lot in debugging the random programs I'm trying to > generate. > > Second, I believe the last line is the problem in my code. Let's > assume the function randomly selected was +, it will run (+ 1 2) and > the entire function returns 3 instead of a randomly generated syntax > tree like I need. I then tried '(func arg1 arg2) hoping it would > prevent evaluation, but then it will always just return (func arg1 > arg2) which isn't what I need either. I need it to actually return a > syntax tree made up of expressions like (+ 1 2) but unevaluated. > > I am guessing I need to start reading and using macros at this point? > > Rob --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Dependency management
I've been noodling on the problem of dependency management for a while now. It's definitely a pain point for projects with more than a couple dependencies. Currently our approach has been to use maven, but that involves a fair amount of arcane knowledge as well as writing a bunch of XML, which isn't a lot of fun. But there's been a community consensus that any dependency tool needs to be able to leverage all the valuable stuff out there that's currently in maven repositories. I've put together a proof-of-concept dependency manager called Corkscrew. It uses Maven under the hood as well as offering dependencies on source packages stored in git or subversion. A simple project.clj file lays out the dependencies and other project info: {:name "my-sample" :version "1.0" :dependencies [["tagsoup" "1.2" "org.ccil.cowan.tagsoup"] ;; group defaults to name ["rome" "0.9"]] :source-dependencies [["clojure-contrib" "r663" :svn "http://clojure-contrib.googlecode.com/svn/trunk";] ["enlive" "95b2558943f50bb9962fe7d500ede353f1b578f0" :git "git://github.com/cgrand/enlive.git"]]} You can install it with: $ git clone git://github.com/technomancy/corkscrew.git $ cd corkscrew $ ./install $ cp bin/corkscrew /somewhere/on/your/path Create a project.clj file in your project root based on the one above. Then you can use "corkscrew deps" to set everything up for you. At that point just make sure your classpath includes target/dependency/ and you should be good to go. It's simple, but it solves the main problems that I've been having with more complicated projects. I'd love to get some opinions on it. The biggest issue right now is that it runs Maven as a subprocess rather than using the Java API in the same VM because I can't make head or tail of the Maven Java API (it uses plexus.core), but shelling out works as a proof-of-concept even if it's tacky. -Phil --~--~-~--~~~---~--~~ 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: Help with example from "A Field Guide to Genetic Programming"
> I am guessing I need to start reading and using macros at this point? I also wrote something to do symbolic regression. I used plain functions to manipulate quoted trees, and one macro to wrap the expression in a fn and eval. --~--~-~--~~~---~--~~ 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: Dependency management
interesting idea! It reminds me a bit of the Grape system in groovy. Groovy uses Ivy for this. and you can grab the needed library either via annotation like @Grab(group='com.jidesoft', module='jide-oss', version='[2.2.1,2.3.0)') or method call like Grape.grab(group:'org.jidesoft', module:'jide-oss', version:'[2.2.0,)') http://groovy.codehaus.org/Grape On Wed, Jul 8, 2009 at 12:28 AM, Phil Hagelberg wrote: > > > I've been noodling on the problem of dependency management for a while > now. It's definitely a pain point for projects with more than a couple > dependencies. Currently our approach has been to use maven, but that > involves a fair amount of arcane knowledge as well as writing a bunch of > XML, which isn't a lot of fun. But there's been a community consensus > that any dependency tool needs to be able to leverage all the valuable > stuff out there that's currently in maven repositories. > > I've put together a proof-of-concept dependency manager called > Corkscrew. It uses Maven under the hood as well as offering dependencies > on source packages stored in git or subversion. A simple project.clj > file lays out the dependencies and other project info: > > {:name "my-sample" > :version "1.0" > :dependencies [["tagsoup" "1.2" "org.ccil.cowan.tagsoup"] > ;; group defaults to name > ["rome" "0.9"]] > :source-dependencies [["clojure-contrib" "r663" :svn > "http://clojure-contrib.googlecode.com/svn/trunk";] > ["enlive" "95b2558943f50bb9962fe7d500ede353f1b578f0" > :git "git://github.com/cgrand/enlive.git"]]} > > You can install it with: > > $ git clone git://github.com/technomancy/corkscrew.git > $ cd corkscrew > $ ./install > $ cp bin/corkscrew /somewhere/on/your/path > > Create a project.clj file in your project root based on the one > above. Then you can use "corkscrew deps" to set everything up for > you. At that point just make sure your classpath includes > target/dependency/ and you should be good to go. > > It's simple, but it solves the main problems that I've been having with > more complicated projects. I'd love to get some opinions on it. > > The biggest issue right now is that it runs Maven as a subprocess rather > than using the Java API in the same VM because I can't make head or tail > of the Maven Java API (it uses plexus.core), but shelling out works as a > proof-of-concept even if it's tacky. > > -Phil > > > > -- Omnem crede diem tibi diluxisse supremum. --~--~-~--~~~---~--~~ 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: Dependency management
Phil, it might be worthwhile to look at Ivy (http://ant.apache.org/ ivy). It has real good interop with ant and can easily pull from a maven repo and read pom files. On Jul 7, 9:28 pm, Phil Hagelberg wrote: > I've been noodling on the problem of dependency management for a while > now. It's definitely a pain point for projects with more than a couple > dependencies. Currently our approach has been to use maven, but that > involves a fair amount of arcane knowledge as well as writing a bunch of > XML, which isn't a lot of fun. But there's been a community consensus > that any dependency tool needs to be able to leverage all the valuable > stuff out there that's currently in maven repositories. > > I've put together a proof-of-concept dependency manager called > Corkscrew. It uses Maven under the hood as well as offering dependencies > on source packages stored in git or subversion. A simple project.clj > file lays out the dependencies and other project info: > > {:name "my-sample" > :version "1.0" > :dependencies [["tagsoup" "1.2" "org.ccil.cowan.tagsoup"] > ;; group defaults to name > ["rome" "0.9"]] > :source-dependencies [["clojure-contrib" "r663" :svn > "http://clojure-contrib.googlecode.com/svn/trunk";] > ["enlive" > "95b2558943f50bb9962fe7d500ede353f1b578f0" > :git "git://github.com/cgrand/enlive.git"]]} > > You can install it with: > > $ git clone git://github.com/technomancy/corkscrew.git > $ cd corkscrew > $ ./install > $ cp bin/corkscrew /somewhere/on/your/path > > Create a project.clj file in your project root based on the one > above. Then you can use "corkscrew deps" to set everything up for > you. At that point just make sure your classpath includes > target/dependency/ and you should be good to go. > > It's simple, but it solves the main problems that I've been having with > more complicated projects. I'd love to get some opinions on it. > > The biggest issue right now is that it runs Maven as a subprocess rather > than using the Java API in the same VM because I can't make head or tail > of the Maven Java API (it uses plexus.core), but shelling out works as a > proof-of-concept even if it's tacky. > > -Phil --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Does anyone need any clojure work done?
After having spent the last decade doing server-side java, lots of infrastructure level code which I enjoy), and going blind on xml, I'd really like to get more into clojure. I've been playing with it off and on for about a year now, reading whatever FP-related material I can get my hands on, but without a real project to work on it's all been a bit aimless. To get more serious about it I'd need to work on an actual problem to solve. To that end, if anyone has a project they'd like help on, be it open or closed, paid or not, please let me know. --~--~-~--~~~---~--~~ 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: Does anyone need any clojure work done?
On Jul 7, 10:18 pm, ataggart wrote: > After having spent the last decade doing server-side java, lots of > infrastructure level code which I enjoy), and going blind on xml, I'd > really like to get more into clojure. > > I've been playing with it off and on for about a year now, reading > whatever FP-related material I can get my hands on, but without a real > project to work on it's all been a bit aimless. To get more serious > about it I'd need to work on an actual problem to solve. > > To that end, if anyone has a project they'd like help on, be it open > or closed, paid or not, please let me know. Talk to Jon Harrop. He just asked for help with his ray tracer. Also all the shootout needs porting to Clojure. Beware the frequently bad tempered admin 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 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: Passing primitives from an inner loop to an outer loop efficiently
On Jul 7, 5:10 pm, John Harrop wrote: > Problem: Passing primitives from an inner loop to an outer loop efficiently. > Here is what I've found. > > The fastest method of result batching, amazingly, is to pass out a list and: > > (let [foo (loop ... ) > x (double (first foo)) > r1 (rest foo) > y (double (first r1)) > r2 (rest r1) > z (double (first r2))] ... ) > This isn't suprising if you think about it. In the list situation you are just grabbing the next pointer, in an array situation you have to do math to access a vector. > (here passing out three doubles). > > About half as fast is: > > (let [[x y z] (loop ... )] ... ) with (double x), (double y), and (double z) > used later in place of x y z and only one occurrence of each (so no more > (double foo) conversions than before). The destructuring bind apparently > exerts a higher run-time overhead compared to manual destructuring. > If you look at the source code this isn't that surprising. The big difference between (for example): (let [[x y z] [1 2 3]] ...) and (let [v [1 2 3] x (v 0) y (v 1) z (v 2)] ...) Most of the slowdown Seems to have to do with bounds checking: The first is 'safe' and returns nil for out of bounds, the second throws an exception. but If you look at the source the 2ary version of nth gets inlined and the 3ary version (which destructuring bind expands to) does not. and if you put a symbol in the second position you'll note that Destructuring bind rebinds the symbol with a Gensym even though it cannot suffer from multiple evaluation. If you look here: http://gnuvince.wordpress.com/2009/05/11/clojure-performance-tips/ And look at 'avoid destructuring binding for vectors' I did some hacking and improved the worst case from about 500ms on my computer to 300ms. (By inlining the 3ary version and removing the duplication; compiling a destructuring function without bounds checking breaks compilation for obvious reasons...). There are probably better ways to optimize it as this was just me screwing around ('What can i break this evening?'). I will note that there is something very funny going on with the destructuring/binding example in the link above. The fast version on my machine returns every number of times(1e7 1e8 1e9 etc...) returns 26 ms. It is kind of like it all just got collapsed into a constant. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---