Re: How to write performant functions in clojure (and other functional languages)
On Sat, Jul 25, 2009 at 4:40 PM, atucker agjf.tuc...@googlemail.com wrote: I wonder if any of the Clojurians on here might like to describe how one might write the factorial function as a parallel one? Taking advantage of the associativity of multiplication, along the lines of 16! = (((1*2)*(3*4)) * ((5*6)*(7*8))) * (((9*10)*(11*12)) * ((13*14)* (15*16))) (defn factorial [n] (let [cores (.. Runtime (getRuntime) (availableProcessors))] (if ( n (* 2 cores)) (reduce * (rest (range (inc n (let [parts (pmap #(reduce * %) (partition (quot (inc n) cores) (rest (range (inc n)] (reduce * parts) ought to do it. --~--~-~--~~~---~--~~ 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: Confusion with apply.
On Wed, Jul 22, 2009 at 5:17 PM, mmwaikar mmwai...@gmail.com wrote: So if this is the intended behavior of apply, which function should I use in this case? Is there anything in Clojure where I can apply any user-defined function to each and every element of a list one-by-one? Use map: user= (map #(* 5 %) [1 2 3 4 5]) (5 10 15 20 25) (Here I also made the multiply-by-five function an anonymous lambda.) --~--~-~--~~~---~--~~ 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: Simple data structure access macro
On Mon, Jul 20, 2009 at 4:31 PM, Moses mosesam...@gmail.com wrote: I come primarily from a perl programming background, but am trying to learn Clojure. I'm looking for a clojure equivalent to the following. Perl: my $nestedDS = [ foo, { hi = there, hello = [buddy] }, hi] my $foo = $nestedDS-[0]; my $there = $nestedDS-[1]-{hi}; my $hello = $nestedDS-[1]-{hello}; my $hi = $nestedDS-[2]; print $foo $there $buddy $hi; I'm not sure if it exists or not, but hopefully if it doesn't it can be created with a macro. To clarify, I'm looking for a function/macro that makes use of a small DSL for accessing fields within the basic Clojure data structures. The best I can come up with in Clojure for a DS equivalent to the above is: (let [nestedDS [foo, {hi there, hello, [buddy]}, hi] foo (nth nestedDS 0) there (get (nth nestedDS 1) hi) buddy (first (get (nth nestedDS 1) hello)) hi (nth nestedDS 2)] (print foo there buddy hi) ) Its not that much longer, but if the fields were more deeply nested, it would become a bit pretty annoying. Does any kind of DS access macro exist? If not, how hard do you think it would be to write? Something like buddy (get-it nestedDS [1]-{hello}-[0]) Or perhaps an even shorter syntax is possible? Perhaps use nested maps, along with get-in, assoc-in, update-in etc.: let [nestedDS {:foo foo :greet-map {hi there hello [buddy]} :hi hi}] --~--~-~--~~~---~--~~ 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: let a variable number of bindings
On Fri, Jul 17, 2009 at 11:52 PM, Rowdy Rednose rowdy.redn...@gmx.netwrote: How can I lexically bind names like let does in a macro, when names and values for those bindings are passed in? This here works fine when I pass a literal collection: (defmacro let-coll [coll body] `(let ~(vec coll) ~...@body)) user= (let-coll [a 11 b 22] (list b a)) (22 11) Doing the same with a var doesn't work though: user= (def x ['a 11 'b 22]) #'user/x user= (let-coll x (list b a)) java.lang.Exception: Unable to convert: class clojure.lang.Symbol to Object[] (NO_SOURCE_FILE:0) Any ideas? It'll be evaluating (vec 'x) during macro expansion, which gives that error. The argument x has to be evaluated for it to work, so you'd need (vec (eval x)) in there. Then you'll also need to quote when passing in a literal vector, e.g. (let-coll ['a 11 'b 12] (list b a)). --~--~-~--~~~---~--~~ 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: let a variable number of bindings
On Sat, Jul 18, 2009 at 1:22 AM, Meikel Brandmeyer m...@kotka.de wrote: Using eval is not really a solution. (def foo '[a 1 b 2]) (let-coll foo ...) will probably work with eval, but (let [foo '[a 1 b 2]] (let-coll foo ...)) will not. No, for that you need to make the macro run-time, too. This can be done by turning it into an ordinary function -- change defmacro to defn and wrap the return value in eval. The argument now doesn't need to be evald, but the body now needs to be quoted. To fix the latter, you can create a macro to wrap the function call that quotes the body. The function then builds the form to be evaluated from the passed-in quoted body and other argument and calls eval on this. The downside to this is that the function now has a run-time computation cost, and won't work in a deployment situation that doesn't support eval. (Thus far, with Clojure I'm not aware of any, but a stripped-down micro edition for use on phones might exist in the future where this wouldn't work.) On the other hand, run-time access to eval allows a few very powerful tricks that are otherwise unavailable, including some very interesting ways of optimizing computations on the fly. In fact, Clojure can grant all the power of self-modifying code, without (if you avoid eval-ing def forms) most of the usual pitfalls of same. The JIT-created code even benefits from the Hotspot JIT in turn, so it's exactly as powerful (and a lot easier! And more portable) as self-modifying x86 assembly code, which has a history of being used to run graphics demos on old hardware that many would have thought incapable of what was done with it. (See http://www.anioni.com/pauli/site1999/demoscene.html but this sort of thing long predates hardware 3D acceleration. These days, this sort of capability will be more of interest for getting maximum performance out of game or numeric code, or for AI research.) (Self-modifying assembly also has a history of being misused to write viruses and make them hard to detect. Clojure is, fortunately, not so useful for that. :-)) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Very minor problem in the REPL
On Fri, Jul 17, 2009 at 11:31 AM, Stephen C. Gilardi squee...@mac.comwrote: It looks like somehow you're seeing a very old REPL or it's not the default REPL you get from launching Clojure via clojure.main. I can confirm the described behavior for the enclojure REPL. --~--~-~--~~~---~--~~ 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 there a standard function testing if a sequence starts with a sequence
On Fri, Jul 17, 2009 at 4:41 PM, Mark Engelberg mark.engelb...@gmail.comwrote: On Fri, Jul 17, 2009 at 1:32 PM, samppirbysam...@gmail.com wrote: Is there a function in clojure.core or clojure.contrib so that: (and (mystery-fn '(a b c d) '(a b)) (not (mystery-fn '(a b c d) '(a b d how about something like: (defn mystery-fn [l1 l2] (every? identity (map = l1 l2))) user= (mystery-fn '(a b) '(a b c d)) true How about something like: (defn mystery-fn [l1 l2] (and (= (count l2) (count l1)) (every? identity (map = l1 l2 --~--~-~--~~~---~--~~ 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: How to achieve indirection?
On Thu, Jul 16, 2009 at 11:34 AM, Dragan draga...@gmail.com wrote: Thanks for the tip, I meant something else. Let's say that I want to write a function do-something. There could be 2 implementations: do-something-quickly and do-something-elegantly. The parameters are the same and there are no differences in their interface. I would like to be able to call it by writing (do- something arg) in my code and specify which implementation I want to use somewhere else (in the configuration part of the code). Functions are values you can pass around, so: (defn do-something-quickly [x y] ... ) (defn do-something-elegantly [x y] ... ) (defn do-various-things [do-something x y z w] (let [z (do-something x y)] ... )) user= (do-various-things do-something-quickly 13 19 3 23) some-sort-of-output user= (do-various-things do-something-elegantly 13 19 3 23) some-sort-of-output --~--~-~--~~~---~--~~ 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: Performance question (newbie)
On Wed, Jul 15, 2009 at 11:39 AM, B Smith-Mannschott bsmith.o...@gmail.comwrote: An explicit loop with some type hints is faster, though likely not as fast as Java: (defn sum-of-range-4 [range-limit] (loop [i (int 1) s (long 0)] (if ( i range-limit) (recur (inc i) (+ s i)) s))) This took 20.275s for the same scenario. Use unchecked-add and unchecked-inc in place of + and inc and you should get equivalent speed. --~--~-~--~~~---~--~~ 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: EY map reduce contest
On Wed, Jul 15, 2009 at 4:53 AM, hosia...@gmail.com hosia...@gmail.comwrote: http://www.engineyard.com/blog/2009/programming-contest-win-iphone-3gs-2k-cloud-credit/ Has anyone got access to hundreds of thousands of machines that I could borrow for 30 hours ? ;) Don't know any botnet herders; sorry. :) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure vectors
On Wed, Jul 15, 2009 at 12:58 PM, Mark Engelberg mark.engelb...@gmail.comwrote: It looks like stack-rot is going to be the bottleneck in your app since it requires traversing the whole vector to build the new one, but I think the list-based implementation would be a bit worse, so I think your choice to use vectors here is sound. For stack-dropn and stack-rot to both be fast, I think that you really want to use a deque. Unfortunately, Clojure doesn't have a built-in deque, and I don't see one in contrib, but you could look at clojure.lang.PersistentQueue and read Okasaki's Functional Data Structures to draw some inspiration. What's needed here is a ring buffer. It shouldn't be hard to implement one atop a pair of a clojure vec, a true-count, and a start-offset. Rotation is then very cheap: replace v with (assoc v (- (+ start-offset true-count) (count v)) (get v start-offset)) and start-offset with (let [s-o (inc start-offset)] (if (= (count v) s-o) 0 s-o)). Dropn is similarly: true-count becomes (- n true-count) and start-offset (mod (+ start-offset n) (count v)). Indexing is cheap: (get v (mod (+ start-offset (mod index true-count)) (count v))) and peek is even cheaper: (get v start-offset). (Maybe add code to handle empty, that is, (= 0 true-count)). The tricky thing is push. If (= true-count (count v)) the vector needs to be copied to a larger vector. You might want to double the size, leaving the unused elements nil: v becomes (vec (concat (drop start-offset v) (take start-offset v) [new-element] (repeat true-count nil))), true-count is inc'd as normal for a push, and start-offset reset to zero. Doubling the size whenever the vector must grow causes the cost of copying the vector to be asymptotically constant per push, instead of linear in the average size of the vector at the time of a push. (Ironically, the vector probably has this behavior under the hood, like java.util.ArrayList, but we need it again because (vec (concat (drop start-offset v) (take start-offset v) [new-element] (repeat true-count nil))) has linear time-complexity in vector length.) You'd actually want to use a structmap for the above if you want to have multiple ring buffers, with struct keys :count, :offset, and :vector or similarly. Depending on the application, you might want to make the values for these keys be refs and have the ring buffer operations use dosync, though you could instead use a single ref per instance of the structmap. --~--~-~--~~~---~--~~ 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: Compilation troubles...
On Mon, Jul 13, 2009 at 3:11 PM, Morgan Allen alfred.morgan.al...@gmail.com wrote: It's a shame about the lack of official support for java-side invocation- the bulk of my code is still implemented in java (largely for efficiency reasons), so it would be handy to be able to initiate things largely from that side. It's definitely not necessary to implement the bulk of your code in Java to get performance. On the other hand, getting performance out of Clojure can be tricky. First, you need to know how to use loop/recur, type hints, primitives, and such, not just separately but in harmony. With that, you can get inner loops that will run, on the server VM, at C-code speeds, not unlike a tight loop in Java that avoids method calls. Second, if you need significant flexibility and variability and conditioning in those loops, but not inside any given instance of running a loop for a while, you need to get comfortable with macros -- backquote, unquote and unquote-splicing, gensyms, and the works. With those, you can customize the loop at each site in the program code so that decisions that don't have to be made every iteration are made entirely outside of the loop, and each loop instance has a particular, optimized form built in. This will give you flexibility coupled with blazing speed. I currently have a project on the go that has performance-critical CPU-bound work that involves an open-ended, runtime-changeable set of parameters; a simulation of sorts. I have it running probably faster than C code could manage, because it actually uses eval and programmatically-constructed code to compile new functions on the fly to do the bottleneck parts of the computations. The resulting functions would be nightmares to code and maintain individually, modify as needed, and so on, but then so would assembly language. Basically, I went beyond domain-specific language and wrote a domain-specific optimizing compiler that ultimately punts to Clojure's. Of course, eval is evil and this program will not run on hypothetical future micro-edition deployment environments whose Clojure runtimes lack eval/compiler support, but it will run on netbook and larger classes of device at speeds that would make experienced C coders and assembly hand-tuners turn green. Of course I can't take all the credit. Rich's Clojure to bytecode compiler sits beneath my compiler, and Sun's Hotspot Server VM JIT compiler sits beneath that in turn, and with either shoddy or missing I couldn't get this kind of speed. But it is proof that any needed speeds can be achieved in Clojure that can be achieved in Java, or even by hand-hacking directly on the bare metal, or by anything short of overclocking chips or fabricating new ones. (Think of the future, too. Clojure macro-like code that compiles directly to FPGA circuit layouts or programmable spintronic arrays or suchlike. Well, not directly; it would be the JVM JIT that would be responsible for creating hardware acceleration or extra cache memory on the fly for code bottlenecks, and reallocating the finite gate-array real-estate dynamically as the needs of the app demanded. Still, combining that with the ability to emit new optimized JVM bytecode on the fly at need and you've got the ultimate in JIT capabilities.) I *was* planning to write up some interfaces for more frequent/time-critical communications, but having to compile things via ant or the command line is a pain, and Eclipse doesn't have particularly good support for mix-and-match of java and clojure files in the same project (at least atm.) NetBeans, which I use, does better at this. You have to restart the REPL after any change to Java classes, which is a nuisance, but you don't have to restart the IDE or muck with anything else (project libraries, classpath). Even if you have separate projects and some are dependencies of others, and all are undergoing active development, you just have to reboot the REPL after changing Java code. Changing Clojure code, even in a separate project that's a dependency of your main project, can typically be handled with a load-file of the changed file. Only if your refactoring moves a Clojure function or other object from one namespace to another (same or different project) do you generally have to restart the REPL, since it won't let you intern a name in a package that imports the same name from another one, and uninterned symbols won't go away. It's a good idea to occasionally restart your REPL anyway to clear out cruft and avoid having a running image that's become dependent on something that isn't in your code base, and also to find anywhere where you are missing forward-declarations. --~--~-~--~~~---~--~~ 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
Re: Best way to create nonref variable?
On Thu, Jul 9, 2009 at 10:29 PM, J. McConnell jdo...@gmail.com wrote: You can try with-local-vars. I'm not sure of the performance characteristics of this versus using an atom, but it certainly feels more imperative: It's slow. I suspect it (and binding) uses Java's ThreadLocal, which is slow. Loop/recur rebinding is literally thousands of times faster. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
*math-context*
It would be useful to have a *math-context* or similar that had a sensible default and could be set with binding to affect bigdec calculations within the temporal scope of said binding. --~--~-~--~~~---~--~~ 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: *math-context*
On Fri, Jul 10, 2009 at 9:22 AM, Rich Hickey richhic...@gmail.com wrote: On Jul 10, 9:01 am, Chouser chou...@gmail.com wrote: On Fri, Jul 10, 2009 at 7:14 AM, John Harropjharrop...@gmail.com wrote: It would be useful to have a *math-context* or similar that had a sensible default and could be set with binding to affect bigdec calculations within the temporal scope of said binding. user= (binding [*math-context* (java.math.MathContext. 5)] (+ 2 1.1M)) 3.M See also: with-precision Eh. Thanks. There's no *math-context* on the api page at the web site. I just checked again. I'll keep it in mind 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 -~--~~~~--~~--~--~---
ArithmeticException with doubles
This is odd: user= (/ 1.0 0.0) #CompilerException java.lang.ArithmeticException: Divide by zero (NO_SOURCE_FILE:0) Shouldn't it be Double/POSITIVE_INFINITY? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure in Clojure?
On Thu, Jul 9, 2009 at 11:10 AM, tmountain tinymount...@gmail.com wrote: I just finished watching the Bay Area Clojure Meetup video, and Rich spent a few minutes talking about the possibility of Clojure in Clojure. The prospect of having Clojure self-hosted is incredibly cool, but it brought a few questions to mind. For one, Rich mentions that it would potentially open up additional target platforms for the language citing Objective C, Actionscript, and Javascript as potential host languages. As awesome as this sounds, wouldn't it first require a native implementation to be created for each language prior to Clojure in Clojure running on the platform? Perhaps there's some magic bootstrapping stuff that can be done to avoid a full port? I'm also wondering if Clojure would take a big performance hit as a result of being self-hosted? Either way, this seems like a really neat idea. The difficult thing would be preserving the inability of bad Clojure code to crash the process, and most especially, providing all of Swing, AWT, JDBC, JAXP, and all of the rest of the goodies from the Java class library. Being JVM-hosted has its advantages. --~--~-~--~~~---~--~~ 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 Wed, Jul 8, 2009 at 3:42 AM, Frantisek Sodomka fsodo...@gmail.comwrote: If result is a vector v, then from these 4 cases: (let [v [1 2 3]] (let [[a b c] v] a b c) (let [a (v 0) b (v 1) c (v 2)] a b c) (let [a (nth v 0) b (nth v 1) c (nth v 2)] a b c) (let [x (first v) r1 (rest v) y (first r1) r2 (rest r1) z (first r2)] x y z)) using 'nth' (let [a (nth v 0) b (nth v 1) c (nth v 2)] a b c) is the fastest. Is it faster than using list and manually destructuring the list? If so, that would mean that (nth v n) is faster than (get v n), which would be odd since the latter should turn into the former anyway and be inlinable by the JIT. --~--~-~--~~~---~--~~ 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: Save current namespace like a Smalltalk image
On Wed, Jul 8, 2009 at 5:14 AM, Robert Campbell rrc...@gmail.com wrote: Thanks Daniel, that makes perfect sense, especially about having random - and forgotten - code in the image. I have a lot of this during my exploration sessions. Perhaps instead of saving an image, it should be able to save a transcript of the REPL inputs? Then you could rescue code from this, or find any cruft your image had become dependent on, or whatever. --~--~-~--~~~---~--~~ 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: Homoiconicity and printing functions
On Wed, Jul 8, 2009 at 9:11 AM, Mike cki...@gmail.com wrote: One of the things that drew me to Clojure was the fact that it's homoiconic (and my previous lisp [Scheme] was not necessarily), which means code is data, macro writing is easy etc. etc. What I'm missing is why I can't print a function. I understand that most of the functions I write use quite a few macros, and after expansion into the core forms it looks shredded...but isn't there any way for me to see a representation of this source after a function has been compiled? If you want to see macro expansions, macroexpand and macroexpand-1 will do ya. If you want to be able to query a function for its source code later on, that's tougher. You'll need to make a macro that wraps defn and assigns a copy of the body form to a metadata tag on the function's name. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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
Interesting. How are these timings affected if you add in the time taken to pack the list or vector in the first place, though? I have the feeling it may be slightly cheaper to unpack a vector, but noticeably cheaper to pack a list... --~--~-~--~~~---~--~~ 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 Wed, Jul 8, 2009 at 1:57 PM, Robert Campbell rrc...@gmail.com wrote: If it's okay, could somebody explain the difference between what's happening here: user (def my-func (list + 1 2)) #'user/my-func user (my-func) ; Evaluation aborted. and here: user (def my-func (list + 1 2)) #'user/my-func user (eval my-func) 3 I don't really understand how: user(my-func) is NOT eval on my-func in the REPL. My understanding is the first item in the list is treated as a function, with the rest of the list passed as arguments. Wouldn't the REPL just be calling eval internally on everything you type in? Not every expression is a function, even if most are function calls. Any expression can be evaluated with eval. To call something as a function, though, it has to be something invokable. A list, even a list of a function and two values, isn't. An actual function is, as produced by defn or fn or #(). So are sets, maps, and vectors, which will look up the argument key or index: user= (#{'x 'y} 'x) x user= (#{'x 'y} 'z) nil user= ({:key 'val} :key) val user= ({:key 'val} 3) nil user= (['a 'b 'c] 0) a user= (['a 'b 'c] 2) c user= (['a 'b 'c] 3) #CompilerException java.lang.ArrayIndexOutOfBoundsException: 3 (NO_SOURCE_FILE:0) And keywords can be invoked to do set and map lookups: user= (:key {:key 'val}) val user= (:x {:key 'val}) nil user= (:key #{:key}) :key user= (:x #{:key}) nil Last but not least, there's ., .., .methName, Class., Class/staticMeth, Class/staticField, and other variations on this theme to interact with Java classes. And maybe one or two things I'm forgetting. :) --~--~-~--~~~---~--~~ 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 Wed, Jul 8, 2009 at 4:57 PM, Frantisek Sodomka fsodo...@gmail.comwrote: So far it seems that vectors win in Clojure: (timings 3e5 (let [v (vector 1 2 3) a (nth v 0) b (nth v 1) c (nth v 2)] (+ a b c)) (let [lst (list 1 2 3) a (nth lst 0) b (nth lst 1) c (nth lst 2)] (+ a b c))) = 680.63 ms 83.6% 1.2x (let [v (vector 1 2 3) a (nth v 0) b (nth v 1) c (nth v 2)] (+ a b c)) 813.79 ms 100.0% 1.0x (let [lst (list 1 2 3) a (nth lst 0) b (nth lst 1) c (nth lst 2)] (+ a b c)) Does using vec instead of vector make a difference? Using first, rest, first, rest instead of nth to destructure the list? --~--~-~--~~~---~--~~ 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 holyg...@gmail.com 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 jharrop...@gmail.com wrote: On Mon, Jul 6, 2009 at 7:50 PM, Richard Newman holyg...@gmail.com 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: Mysterious ClassFormatError after simple code change.
On Tue, Jul 7, 2009 at 9:30 AM, Stephen C. Gilardi squee...@mac.com 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 -~--~~~~--~~--~--~---
Re: Mysterious ClassFormatError after simple code change.
On Mon, Jul 6, 2009 at 8:53 AM, Chouser chou...@gmail.com wrote: On Sun, Jul 5, 2009 at 3:51 PM, John Harropjharrop...@gmail.com wrote: This is frankly quite baffling. The changes to the function are innocent from a large-literal or pretty much any other perspective. Both your functions load fine for me without the rest of your code. Are there type hints on the return values of any of the functions called in your examples? Not that I know of. Called macros above are let-print; called functions are cons, map, factor-term, rest, make-product*, concat, and subexpressions-of-product. All are called by both versions; cons, map, rest, and concat are the clojure.core versions and let-print is just (defmacro let-print [bindings body] `(let ~bindings ~@(map (fn [x#] `(println ~x#)) (take-nth 2 bindings)) ~...@body)) which I find handy sometimes when debugging, because I can just slap a -print at the end of a let to add some debugging dumps to the console output. (I also have eval-print and intend to add loop-print to dump loop variables every time around the loop.) I had been debugging the above function, which work led to the change that triggered the new problem. Interestingly, changing the let-print back to let alters the error message, specifically, the cryptic number after unknown constant tag, but has no other effect. The functions factor-term, make-product*, and subexpressions-of-product have all been working for ages, and have not changed recently. None type-hints anything, return value or otherwise. --~--~-~--~~~---~--~~ 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?
Or if you really do need a list: (for [x [1 2 3]] (cons 'some-symbol (list x))) Why not (for [x [1 2 3]] (list 'some-symbol x)) ? --~--~-~--~~~---~--~~ 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 3:58 PM, Emeka emekami...@gmail.com wrote: (defn- subexpressions-of-sum** [[n p] terms] (let-print [sum (cons '+ (map #(factor-term % n p) terms)) prod (rest (make-product* n p))] (cons sum (map #(cons '* (cons sum (rest %))) (concat prod (subexpressions-of-product prod)) I look at the above, and something stupid just entered into my thought. What happened when this situation occurs (cons sum ())? I hope that's not possible with your code. It shouldn't be. Even if it is, there'd just be some (* sum) in the results, which is inefficient but not illegitimate. I don't see any way that this could be the cause of the ClassFormatError, in particular. Frankly, I am starting to suspect a bug in clojure. I'm using the stable 1.0, not the bleeding edge stuff. Whether the occurrence of the ClassFormatError itself is down to a subtle error in my code (so subtle no-one can spot it) or an error in clojure, its failure to point to a line in my source file as the erroneous one is in and of itself a bug, I'd argue. 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. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Mysterious ClassFormatError after simple code change.
I had this: (defn- subexpressions-of-sum** [[n p] terms] (let-print [sum (cons '+ (map #(factor-term % n p) terms)) prod (rest (make-product* n p))] (concat [sum] (subexpressions-of-product (cons sum prod) in a source file with other definitions. Load-file worked. I then changed it to this: (defn- subexpressions-of-sum** [[n p] terms] (let-print [sum (cons '+ (map #(factor-term % n p) terms)) prod (rest (make-product* n p))] (cons sum (map #(cons '* (cons sum (rest %))) (concat prod (subexpressions-of-product prod)) and got: #CompilerException java.lang.ClassFormatError: Unknown constant tag 32 in class file com/mycompany/myfile$eval__14598 (NO_SOURCE_FILE:0) when I tried to do a load-file. That function definition was the ONLY thing I changed, but I'm at a loss to find any kind of error in it. Delimiters balance, all of the referenced functions exist, basically there's nothing wrong. The full exception trace, which required evaluating (.printStackTrace (.getCause *e)) at the repl, is: java.lang.ClassFormatError: Unknown constant tag 32 in class file com/mycompany/myfile$eval__14598 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:621) at java.lang.ClassLoader.defineClass(ClassLoader.java:466) at clojure.lang.DynamicClassLoader.defineClass(DynamicClassLoader.java:42) at clojure.lang.Compiler$FnExpr.getCompiledClass(Compiler.java:3417) at clojure.lang.Compiler$FnExpr.eval(Compiler.java:3428) at clojure.lang.Compiler.eval(Compiler.java:4531) at clojure.core$eval__3990.invoke(core.clj:1728) at clojure.main$repl__5813$read_eval_print__5825.invoke(main.clj:176) at clojure.main$repl__5813.doInvoke(main.clj:193) at clojure.lang.RestFn.invoke(RestFn.java:548) at org.enclojure.repl.main$create_clojure_repl__53$repl_thread_fn__55.invoke(main.clj:96) at clojure.lang.AFn.run(AFn.java:37) at java.lang.Thread.run(Thread.java:619) It does not point to any line of my source file. Perhaps the rewritten version of the function provokes a compiler bug? If there is a known bug that would cause this, let me know of the known workaround. If there is an error in the second version of my function, let me know. (It has intentionally different semantics from the first version, so that's not an error in and of itself.) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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.
I'm not doing any funny things with load-string. The largest literal at this time is [2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541 547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659 661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809 811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941 947 953 967 971 977 983 991 997] and has been in there a while without causing problems. The function definition in my original post is the ONLY change between working and not-working. With the first version, the file loads consistently. With the second version, it fails consistently. The error is definitely in that function and not elsewhere, or else it is in the implementation of load-file, the compiler, or even Java or the JVM. The JVM is 1.6.0_something, I forget what. It's pretty current. The literal generated in the post you linked to took a list of four items and doubled it up 13 times, for a grand total of 2^15 = 32768 items. There's nothing that large in that function, nor anything in the second version of it that would expand (say, via a macro) into something that large from a number being changed. This is frankly quite baffling. The changes to the function are innocent from a large-literal or pretty much any other perspective. On 7/5/09, Stephen C. Gilardi squee...@mac.com wrote: On Jul 5, 2009, at 2:01 AM, John Harrop wrote: and got: #CompilerException java.lang.ClassFormatError: Unknown constant tag 32 in class file com/mycompany/myfile$eval__14598 (NO_SOURCE_FILE:0) Are there large literals elsewhere in the same namespace? Here's some info from a previous report of this error: http://groups.google.com/group/clojure/browse_frm/thread/e556434a382de814/f8183c88db8fa257?lnk=gstq=oct+18+2008#f8183c88db8fa257 --Steve --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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 -~--~~~~--~~--~--~---