Re: making code readable
This is the excuse continually trotted out by people too lazy to comment, or who think themselves superior to merely mortal programmers who have to work in teams and actually communicate with people. Redundancy in communication is almost never redundant; think of it as a checksum. snip A checksum should be trusted. Comments sometimes cannot. Since you brought up the issue with working in teams, I will submit my decade and a half of experience coding in 'enterprise' team environments (my chosen hell). I have built upon and maintained Java code that has grown through accretion of various consulting organizations, and I never trust comments. Even with third party (supposedly stable) APIs, I have had (more than once) to open up the code to discover that the javadocs are out of date and incorrect. I do my bit; I try to maintain my comments, but I never trust. The code IS the answer, always. 'Redundant comments are useless' is the mantra of the dilettante, the amateur, and the cowboy. I believe the मन्त्र 'comments are useless' is more cowboy-like, not 'redundant comments are useless'. If not, what about the phrase 'useless comments are useless'? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Understanding how to use namespaces
Hey Mark, In addition to Meikel's explanation above, have a look at this message http://groups.google.com/group/clojure/msg/17ada41fcb5ef667 from the overall thread http://groups.google.com/group/clojure/browse_frm/thread/ff80d120c996ba1a/9bfbfe1b08246035# This was the post that finally made it clear (for me) the differences between use, require, refer, load etc Namespaces and library loading are intertwined. daniel --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Stumped - Java hangs when using Swing in Slime
Anyone have any ideas? I'm pretty confused as to what might be going on. Some sort of deadlock in the thread pool that isn't allowing the AWT event thread any cycles? I'm looking at the thread pool in JSwat and I see a lot of Swank threads, but I can't tell exactly what's going on. I literally just had this problem today. I was having slime hang on me with _any_ swing code. So I tried the basic repl and even the most basic (. javax.swing.JOptionPane (showMessageDialog nil Hello World)) and even this was failing. Spent an hour svn updating, etc. Finally, I clicked on the system icon tray at the bottom right of XP and noticed that that the stupid Java download manager wanted me to update. I let it download whatever patch it wanted and then suddenly everything worked. It could be coincidental. But I am telling you just in case. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: FAQ
Suggestions for entries welcome here. Rich How about: What language constructs/objects may be found in the function position of an expression? Ii like the fact that sets, maps and vectors are all 'functions of their keys', and that keywords and symbols are functions of maps. ((([ + - apply ] 2) hash-map [ 1 one 3 three]) 1 ) Examples would be useful --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Typo on Refs and Transactions page
Fixed - thanks for the report. ahh since you're here and responding, there is a reference to 'boot.clj' at http://clojure.org/getting_started which is no longer valid.. this page also points to sourceforge ... any plans for a bug/typo tracking system so we don't fill up the group with too much noise? daniel --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: 'require' doc string out of date?
In general, clojure-contrib is a good place to look to find examples of properly laid-out libs, as well as generally idiomatic Clojure code. --Chouser Yeah, just recently I've taken to scanning the code in 'webjure' and 'swank' to see how things are done, rather than relying on the APIs. I never got to downloading 'clojure-contrib' but the more I read the group, the more it seems like this is where the magic is happening. Thanks for the recommendation. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Is clojure.core/require documentation out of date ?
If I'm wrong, could you please help me understand, maybe by giving me a URL I may have missed ? Regards, -- Laurent PETIT yes it is out of date... check the post 5 posts down: http://groups.google.com/group/clojure/browse_frm/thread/4a4c2e3e7aab5325# --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Is clojure.core/require documentation out of date ?
I know don't feel comfortable with the notion of lib. I currently assume that it is more or less similar to a namespace : it looks like a namespace, it tastes like a namespace, but still does seem to be not considered a namespace. I understand your pain. I am right now going through the same thought process, and do not have a satisfactory understanding myself. The myriad connections between namespaces and libraries as manifest through 'load-file', 'require', 'use', 'refer', 'load', have left me scratching my head. In the end, someone like you or I might need to publish our discoveries here (with the understanding that we are looking for feedback). I am currently going through the core.clj to understand the dependencies. I think you will find the API will stay out of date for the short term as things are fleshed out here and on the IRC channel. I thought that clojure was further along when I started a few weeks ago. Please don't mistake this last statement for a criticism. In fact, now that I see that I am in the middle of the birth of something extremely impressive, I am rather excited. The primitives and major design decisions of this language seem to be solid. It seems to be these higher level notions that are being refined as we speak. I've dug up month-old to half-year old posts on this group where people propose and implement breaking changes. The AOT compilation change came only a short time ago and seems to be the source of this particular API staleness. I've seen posts where the binding forms to most of the sequencing funcitons are fleshed out on the group and then committed. There seems to be a great willingness to allow these 'API's to gestate in contrib libraries before they are promoted to core -- after all, they're all just macros and functions in the end. I am guessing this trend will continue for the foreseeable future, and some examples, APIs and code libraries will be out of synch. Heck, a lot of the information I gleaned came from watching the movies, and even those are out of date (there is no longer a boot.clj for instance). I think the best course of action, for now, is to just read the code. Make core.clj your friend. It has deepened my understanding of the language decisions. (Still trying to grok 'libraries' though :) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: understanding quoting
Looks like an if then else version of the map lookup?? ie: (if (%1 %2) (%1 %2) %3) Is this a special feature of maps in general, such that you can look up a key but return something else if it doesn't exist? I hadn't come across it yet, but it sounds useful :) This is exactly right (I just confirmed it for myself). I looked up the java code for Keyword.java and Symbol.java both of which implement IFn (those things that can be put in the function position). The single and double arity invoke() merely delegate to 'get'. And voila: user (doc get) - clojure.core/get ([map key] [map key not-found]) Returns the value mapped to key, not-found or nil if key not present. The last parameter is definitely for those situations where 'if not found, use this' I think I _finally_ understand the statement, keywords and symbols are functions of maps. So, the original poster's observation about ('+ '1 '2) returning '2 makes more sense when you consider that it turns into this: (get '1 '+ '2) or get from the hashmap ( '1 ) the value stored at key ( '+ ) and if nil is returned, return ( '2 ) instead (get '1 '+) returns nil as '1 is not even a map. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: understanding quoting
How did you know that it delegates to 'get'? sorry, I rushed that part. the keyword and symbol are instances of clojure.lang.Keyword and clojure.lang.Symbol which are _java_ classes found in Keyword.java and Symbol.java (I found these in the src/jvm directory) These are what the invoke( ) methods looks like for the single and double arity of both these classes (this is _java_ code): /** * Indexer implements IFn for attr access * * @param obj - must be IPersistentMap * @return the value at the key or nil if not found * @throws Exception */ public Object invoke(Object obj) throws Exception{ return RT.get(obj, this); } public Object invoke(Object obj, Object notFound) throws Exception{ return RT.get(obj, this, notFound); } - which in turn goes to RT.java static public Object get(Object coll, Object key){ if(coll == null) return null; else if(coll instanceof Associative) return ((Associative) coll).valAt(key); else if(coll instanceof Map) { Map m = (Map) coll; return m.get(key); } else if(coll instanceof IPersistentSet) { IPersistentSet set = (IPersistentSet) coll; return set.get(key); } else if(key instanceof Number (coll instanceof String || coll.getClass().isArray())) { int n = ((Number) key).intValue(); if(n = 0 n count(coll)) return nth(coll, n); return null; } return null; } static public Object get(Object coll, Object key, Object notFound){ if(coll == null) return notFound; else if(coll instanceof Associative) return ((Associative) coll).valAt(key, notFound); else if(coll instanceof Map) { Map m = (Map) coll; if(m.containsKey(key)) return m.get(key); return notFound; } else if(coll instanceof IPersistentSet) { IPersistentSet set = (IPersistentSet) coll; if(set.contains(key)) return set.get(key); return notFound; } else if(key instanceof Number (coll instanceof String || coll.getClass().isArray())) { int n = ((Number) key).intValue(); return n = 0 n count(coll) ? nth(coll, n) : notFound; } return notFound; } - all really cool --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
My quest to modify a leaf node in an arbitrarily deep map (question posed)
Hi all, I am relatively new to clojure. I am trying to port some toy code I wrote for common lisp a few years ago (a boggle-like game which needs a dictionary prefix trie to trim possible word matches). My old code was fairly imperative in nature when creating the dictionary trie, and so now I am having fun exercising my brain trying to do the right thing with functional programming. One thing I immediately ran up against were certain situations where I have a map and want to modify a value several levels deep into the hierarchy. Imagine the following structure: (def nested-structure { :level 0, :nested1 { :level 1, :nested2 { :level 2, :final-data initial data}}}) If I need to change the value for :final-data, the chain of nested assoc, and get becomes unwieldy (IMO). So I spent several hours scanning through the API to see what might help me out in this. I thought that the (-) macro was where it was at, but spun my wheels. I thought potentially, that the destructuring capabilities of let would help me out, but again I could not get anything to work the way I wanted... I played around with various reduce concoctions (accumulating closures) and even toyed with generating a macro, before I realized how easy it was: ;; keys is a vector of steps in a path, navigating down a map hierarchy (defn path-rebind [map keys val] (let [ [first rest] keys nested-val (get map first) ] (if rest (assoc map first (path-rebind nested-val rest val)) (assoc map first val user (path-rebind nested-structure [:nested1 :nested2 :final-data] new data) {:nested1 {:nested2 {:final-data new data, :level 2}, :level 1}, :level 0} So, I have two questions: 1) Am I missing something from the API that could have done what my function path-rebind? (I would have assumed that this would be a common need and that programmers would not need to roll their own each time) 2) Am I missing out on a clever reduce usage that could have made this more in-line? i.e. how's my code? It was after I made wrote this function and contemplated how I could make it abstract (i.e. with vectors, lists, etc) that I noticed the existence of the zip library... Maybe question 1) above is answered by the zip library. Is/Will the zip library be the recommended means by which to navigate/modify data structures of arbitrary depth, branching, and concrete 'type' ? daniel --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: My quest to modify a leaf node in an arbitrarily deep map (question posed)
One thing I immediately ran up against were certain situations where I have a map and want to modify a value several levels deep into the hierarchy. Imagine the following structure: (def nested-structure { :level 0, :nested1 { :level 1, :nested2 { :level 2, :final-data initial data}}}) Look into clojure.zip (.../src/clj/clojure/zip.clj in the Clojure source). Excellent... thanks for the pointer. I will take a stab at using this for maps (I see stuff for vector-zip, but not yet maps). As an off-hand comment made without careful reading, I can imagine there being great utility in a special reader-syntax for paths. XSLT embeds xpath, and groovy embeds gpath. I am unsure at this point the exact capabilities of the zipper, so I don't know whether it's meant to go to a single location in a tree (it seems this way) or whether it refers to a sequence of all tree nodes that satisfy the predicates of the path (as xpath and gpath do). For the latter scenario, though, a reader syntax for a path could be very useful. thanks again ! daniel --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: My quest to modify a leaf node in an arbitrarily deep map (question posed)
user (path-rebind nested-structure [:nested1 :nested2 :final-data] new data) {:nested1 {:nested2 {:final-data new data, :level 2}, :level 1}, :level 0} Congratulations, you've implemented 'assoc-in' :-) user= (assoc-in nested-structure [:nested1 :nested2 :final-data] new data) {:nested1 {:nested2 {:level 2, :final-data new data}, :level 1}, :level 0} There are also 'get-in' and 'update-in'. Your code looks fine -- nearly identical to 'assoc-in' in fact. It does the destructuring right in the function arguments, but everything else is merely stylistic differences. --Chouser ahh even better... I knew someone must have done this before and it kills me now to look at the API and see it right underneath the (assoc) description. I have no idea how I missed it. thanks, daniel --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Elegant but very slow
I On Dec 4, 2:55 pm, PeterB [EMAIL PROTECTED] wrote: Hi, I downloaded clojure_20080916.zip and had a go with a simple tree benchmark (cut-down version of the one in the computer language shootout http://shootout.alioth.debian.org/). The Java version is pretty simple and runs in about 2s on my laptop: public class Main { public static void main(String[] args) { System.out.println(result: + sumTrees(1, 10)); } public static int sumTrees(int iterations, int depth) { int i; int sum = 0; for (i = 1; i = iterations; i++) sum += TreeNode.bottomUpTree(i, depth).itemCheck() + TreeNode.bottomUpTree(-i, depth).itemCheck(); return sum; } public static class TreeNode { private TreeNode left, right; private int item; TreeNode(int item) { this.item = item; } TreeNode(int item, TreeNode left, TreeNode right) { this.left = left; this.right = right; this.item = item; } private static TreeNode bottomUpTree(int item, int depth) { if (depth 0) return new TreeNode(item, bottomUpTree(2*item-1, depth-1), bottomUpTree(2*item, depth-1)); else return new TreeNode(item); } int itemCheck() { if (left == null) return item; else return item + left.itemCheck() - right.itemCheck(); } } } The Clojure version is considerably more compact and elegant: (defn make-tree [item depth] (if (zero? depth) (list item nil nil) (let [item2 (* 2 item) depth-1 (dec depth)] (list item (make-tree (dec item2) depth-1) (make-tree item2 depth-1) (defn check-tree [tree] (if (nil? tree) 0 (let [[i l r] tree] (- (+ i (check-tree l)) (check-tree r) (defn sum-trees [iterations depth] (let [sum #(+ (check-tree (make-tree % depth)) (check-tree (make-tree (- %) depth)))] (reduce #(+ %1 %2) 0 (map sum (range 1 (inc iterations)) (time (println result: (sum-trees 1 10))) However, there is a heavy price to be paid for this elegance: 'Elapsed time: 100730.161515 msecs' Ouch! That's rather disappointing :-( Any suggestions for improving the performance? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Elegant but very slow
ahhh... to answer my own question (and if I had looked at the code and the API a bit closer), it turns out that recur can only be used in tail-position... and your code (as a tree-recursor) would not benefit from this. On Dec 4, 5:39 pm, Daniel Eklund [EMAIL PROTECTED] wrote: oops... I am just learning the language right now and just quickly looked at what you did... Would the use of recur instead of self-calls potentially help consuming stack space? http://clojure.org/special_forms#toc10 On Dec 4, 5:37 pm, Daniel Eklund [EMAIL PROTECTED] wrote: I On Dec 4, 2:55 pm, PeterB [EMAIL PROTECTED] wrote: Hi, I downloaded clojure_20080916.zip and had a go with a simple tree benchmark (cut-down version of the one in the computer language shootout http://shootout.alioth.debian.org/). The Java version is pretty simple and runs in about 2s on my laptop: public class Main { public static void main(String[] args) { System.out.println(result: + sumTrees(1, 10)); } public static int sumTrees(int iterations, int depth) { int i; int sum = 0; for (i = 1; i = iterations; i++) sum += TreeNode.bottomUpTree(i, depth).itemCheck() + TreeNode.bottomUpTree(-i, depth).itemCheck(); return sum; } public static class TreeNode { private TreeNode left, right; private int item; TreeNode(int item) { this.item = item; } TreeNode(int item, TreeNode left, TreeNode right) { this.left = left; this.right = right; this.item = item; } private static TreeNode bottomUpTree(int item, int depth) { if (depth 0) return new TreeNode(item, bottomUpTree(2*item-1, depth-1), bottomUpTree(2*item, depth-1)); else return new TreeNode(item); } int itemCheck() { if (left == null) return item; else return item + left.itemCheck() - right.itemCheck(); } } } The Clojure version is considerably more compact and elegant: (defn make-tree [item depth] (if (zero? depth) (list item nil nil) (let [item2 (* 2 item) depth-1 (dec depth)] (list item (make-tree (dec item2) depth-1) (make-tree item2 depth-1) (defn check-tree [tree] (if (nil? tree) 0 (let [[i l r] tree] (- (+ i (check-tree l)) (check-tree r) (defn sum-trees [iterations depth] (let [sum #(+ (check-tree (make-tree % depth)) (check-tree (make-tree (- %) depth)))] (reduce #(+ %1 %2) 0 (map sum (range 1 (inc iterations)) (time (println result: (sum-trees 1 10))) However, there is a heavy price to be paid for this elegance: 'Elapsed time: 100730.161515 msecs' Ouch! That's rather disappointing :-( Any suggestions for improving the performance? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure HTML Documentation
beautiful ! thanks... i was just looking for something like this On Nov 21, 3:17 am, Mark McGranaghan [EMAIL PROTECTED] wrote: I've created some experimental HTML docs for Clojure. You can see them on S3:http://clj-doc.s3.amazonaws.com/tmp/doc-1116/index.html Or, just for kicks, on Amazon's new Cloud Front CDN:http://d2nbqsesuabw8o.cloudfront.net/tmp/doc-1116/index.html You can see the code I used to generate them on GitHub:http://github.com/mmcgrana/clj-doc The generation code is open for public perusal but will require some tweaking for public use (e.g. I still have paths hard coded). Any help along these lines would be greatly appreciated. Most methods in the clj-doc source have docstrings and in total its only a couple hundred lines of code: you should be able to find your way around if you're interested. The best entry point is bin/gen.clj. Again, any comments or suggests would be appreciated. I hope that some of you find this interesting/useful/helpful in your Clojure endeavors, - Mark --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---