Re: take 1 element from each coll, make all possible strings?
Timothy - It becomes more tricky if you want to know what fraction of everything a host can present that carries 2 or 3 different filters (I mentioned that somewhere). For example: everything is 4^4 = 256 options [ABCD][ABCD][ABCD][ABCD] Host carries these two filters: [ABC][AC][AB][ABC] [ABC][AB][AC][ABC] Each of these filters can present 36 options, but they overlap on [ABC] [A][A][ABC] (9 options), so the total they can present is 36 + 36 - 9. Unless I can logically identify the overlap between all the combinations of filters that are present within a host (i.e. 1-3, 1-2, 2-3 if I've three filters), and remove that overlap from one of the filters.. calculating the exact value is going to be tricky. Overlap between these: [AC D][AC][BD][C] (12 options) [ABC][A][ACD][ABC] (27 options) is [AC][A][D][C] - 2 options. However, I can't just substract the overlap from one of these two filters.. [D][C][D][C] (1 option) [ABC][A][ACD][ABC] (27 options) or [AC D][AC][BD][C] (12 options) [B][][D][C] (0 options) I might try and figure out what I can do, I gave up on this course of action earlier, but seeing that the brute-force way takes eons, I'll look into this. This will be an interesting exercise :). On Dec 29, 1:16 am, Timothy Pratley timothyprat...@gmail.com wrote: If you aren't interested in the permutations themselves, just the number of them (if I read you right) The only way I could think up to know exactly what fraction of the optimum (2x 5%: remember the diploidi)) a set of combined filters can present is by expanding these filters into a set of all possible strings that they can present, and counting this set. (count (expand (first myset Then there is no real need to generate them at all: user= (reduce * (map count [[1 2 3] [3 4]])) 6 Regards, Tim. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Serializing functions
I want to be able to read and write a clojure object, which contains functions, from/to a file. The structure looks something like this: { :s my-string :f (fn[x] (inc x) } Reading is easy: (load-file ...) works fine. The tricky part is writing it back to the file. (pr ...) gives something like this: {:s my-string, :f #user$fn__895 user$fn__...@2dc62dc6} which cannot be subsequently read. The only workaround I found is this: I quote the function in the file (which means that it needs to explicitly eval-ed when called). Then, I save it like this: (assoc my-map :f (cons 'quote (list (my- map :f Although this works it seems a bit cumbersome. I am pretty sure there is a better way to do it. Any ideas? Thanks, -Itay PS: This issue has been also mentioned at the Persistent storage discussion last week. --~--~-~--~~~---~--~~ 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: making code readable
Mark, Thanks so much for pointing that out, it makes Clojure to belong to others. Clojure should not be only for FP experts and PH.D holders. I took time to check the background of some members in this group: we have lecturers, research scientists and others from the best technical schools. I know that for such people simplifying(through commenting and spreading codes by using methods) Clojure may kill their brain cells. But for me and other mere mortals we need such help and as I see Clojure it may become another phenomenon in the rank of Ruby. Emeka --~--~-~--~~~---~--~~ 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: Exercise: words frequency ranking
You could consider using a StreamTokenizer: (import '(java.io StreamTokenizer BufferedReader FileReader)) (defn wordfreq [filename] (with-local-vars [words {}] (let [st (StreamTokenizer. (BufferedReader. (FileReader. filename)))] (loop [tt (.nextToken st)] (when (not= tt StreamTokenizer/TT_EOF) (if (= tt StreamTokenizer/TT_WORD) (let [w (.toLowerCase (.sval st))] (var-set words (assoc @words w (inc (@words w 0)) (recur (.nextToken st) (println (reverse (sort (map (fn [[k v]] [v k]) @words)) For me it was faster (even ignoring output): user= (time (wordfreq wordfreq.txt)) Elapsed time: 444.171796 msecs user= (time (top-words wordfreq.txt out.txt)) Elapsed time: 618.196978 msecs Obviously if you wanted to take this approach you could rework to apply your existing printer for a better comparison. Interestingly when I compared 3 implementations: 1) by Chouser here: http://groups.google.com/group/clojure/browse_thread/thread/d03e75812de6c6e2/5c47c243474c999d?lnk=gstq=sort+by+value#5c47c243474c999d 2) top-words as described 3) Using a StreamTokenizer I get 3 different histograms using a test file! All very similar but slightly different. It is probably largely related to my test file having opposite architecture newlines... shows that word counting is not necessarily a cut and dried thing! Hahahaha, so how just how many words are in this file ??? :) Regards, Tim. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Fibonacci sequence
Hi David, (defn fib (fib-helper 0 1)) ; This doesn't work either: (defn fib (fib- helper '(0 1))) You're missing your argument list for fib. I assumed you meant the empty square brackets [] just after the work fib? I didn't realise these were necessary even when there were no function arguments. Thanks. (println (take 5 fib)) take creates a lazy list from a collection: (take n collection) Your fib does not produce a collection. I see. I think I had my algorithm in a twist, I tried to make that two-function algorithm work in python (and then translate), but failed at the first hurdle. I've since tried to go for the single function recursive algorithm. Thanks, Craig --~--~-~--~~~---~--~~ 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: Exercise: words frequency ranking
Hello sir, I would have asked this question in the thread but , I don't want to create noise over this issue. I have not been able to get my head around your code or Clojure. I need some support. (defn top-words-core [s] (reduce #(assoc %1 %2 (inc (%1 %2 0))) {} (re-seq #\w+ (.toLowerCase s My little understanding of Inc is that it returns a number greater than the arg. That's clear to me, however, which argument is passed here (%1 %2 0) Please try as much as you can to simplify your explanation because this may assist me in making a great leap in the learning of of Clojure. Again, #(%)[3 4] works because of closure, so when you apply reduce function of #(.) does it suspend #() closure capability. Emeka --~--~-~--~~~---~--~~ 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: making code readable
I think that just as important as compactness is the issue of density: the ratio of the conceptual weightof the computation to the size of the code expressing it. if a computation is inherently complicated and I manage to squeeze it into a few lines (typically accomplished via an intense cognitive effort) the resulting code is usually hard to understand/maintain/debug because you need to be acquainted with all sorts of little truths and insights which are not obvious for the casual reader. This is what I call a high density code. Given that Clojure is a very powerful language, I often find my self in a situation where I mange to write highly dense code, sometimes at the expense of readability. In such cases I think that the use of explaining variables, and simplified-but- somewhat-longer expressions is desirable. OTOH, if the code is inherently simple (e.g.: a chain of straight- forward transformations on a collection) I think that using Clojure's power to reduce the line count by a factor of more than 5 (compared to, say, Java), is highly beneficial. The predicament is that there's no objective way to measure conceptual weight nor density so this issue is largely a personal judgment call. Just my 2c. -- Itay Maman http://javadots.blogspot.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: making code readable
On Mon, Dec 29, 2008 at 12:03 AM, Abhishek Reddy arbs...@gmail.com wrote: Speaking for myself, as the author of the original Snake example, I had no intention of converting developers to Clojure, or of producing instructive or readable code, with that snippet. While I agree with some of your critique, I do think it is misplaced. The aim of this particular exercise was to produce an _abnormally_ terse program, after all. If you believe there is some utility in producing a more readable version, as a tutorial, do not hesitate to make one and publish it! I'll be happy to direct readers to it. :-) I apologize for the nature of my email which somewhat singled you out. I would like to produce a version of the snake code that could serve as an example of the kind of code that the Clojure community thinks is good. Unless it's part of an exercise to produce the shortest code possible, I think we should always write Clojure code with a goal of making it as easy as possible for others to read, while not attempting to serve as a Clojure tutorial. Again, my goal here is to get more developers to give Clojure a shot. My challenge to everyone on the list is to start with any version of the snake code you've seen and make it as readable as *you* think it should be by doing things like renaming variables and functions, adding comments and changing indentation. I'd really like to see what *you* think is the best way to write this code. The lessons learned from this exercise could then be applied to other code we write in the future. -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ 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
Haven't solved it yet, but I may have found something useful enough for someone cleverer than I to make something out of. When I run clojure directly as inferior-lisp, without slime, the problem does occur. However, as soon as I enter something in the inferior lisp buffer, it starts working again. 1. I start up clojure with M-x run-lisp 2. I load my test Swing app (the temperature converter) using (load- file ...). 3. The Swing frame hangs (doesn't respond to events) 4. I hit enter in the inferior lisp buffer 5. The Swing frame starts responding again My best guess is that something is blocking on the input stream from the Repl, and preventing events from being processed by the event- handling thread. As soon as something is entered in the Repl, it somehow clears this state and starts working again. Any thoughts on how to fix it? Thanks, -Luke On Dec 23, 9:28 am, levand luke.vanderh...@gmail.com wrote: Yeah, thanks for the suggestion, but that's not it... I can see the Swing window, and it is also hung (it doesn't process events from the OS). I'm going to do some more in-depth debugging today, doing stack dumps and such, and see if I can figure out what's locking. Thanks, -Luke On Dec 22, 3:51 pm, Michael Beauregard mich...@insightfulminds.com wrote: This is a long shot, but... It's been a while since I played with swing in clojure, but I remember the swing UI would display behind emacs. The result is that the app is correctly running despite the fact that it is obscured by other windows while your REPL appears stuck. Michael --~--~-~--~~~---~--~~ 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: making code readable
On Mon, Dec 29, 2008 at 5:44 AM, Mark Volkmann r.mark.volkm...@gmail.com wrote: I would like to produce a version of the snake code that could serve as an example of the kind of code that the Clojure community thinks is good. Unless it's part of an exercise to produce the shortest code possible, I think we should always write Clojure code with a goal of making it as easy as possible for others to read, while not attempting to serve as a Clojure tutorial. Again, my goal here is to get more developers to give Clojure a shot. My challenge to everyone on the list is to start with any version of the snake code you've seen and make it as readable as *you* think it should be by doing things like renaming variables and functions, adding comments and changing indentation. I'd really like to see what *you* think is the best way to write this code. The lessons learned from this exercise could then be applied to other code we write in the future. Okay, I took the challenge and produced a modified version of my earlier code where I removed what I considered to be redundant comments and did a little more renaming. You can see it at http://www.ociweb.com/mark/programming/ClojureSnake.html. Feedback is welcomed! I also started documenting some Clojure coding guidelines aimed at making code more readable at http://www.ociweb.com/mark/programming/ClojureCodingGuidelines.html and would appreciate feedback on these. I expect there will be cases where not following these is justified, which is why I refer to them as guidelines instead of rules. -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ 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: making code readable
My challenge to everyone on the list is to start with any version of the snake code you've seen and make it as readable as *you* think it should be by doing things like renaming variables and functions, adding comments and changing indentation. I'd really like to see what *you* think is the best way to write this code. The lessons learned from this exercise could then be applied to other code we write in the future. I'll keep this as short. Thanks to the folks who contributed to the snake code. I spent a few hours reading it, referring repeatedly to the API documentation, renaming a few of the variables, experimenting with snippets in REPL, and adding comments to the code so I wouldn't forget what I'd learned. I'm not sure that's a problem, though. I learned more in that process than I would have if the code had been excruciatingly documented. The level of educational documentation varies with the level of experience. Too much documentation in an example is just as bad as too little. I also wonder whether insisting upon coding standards might deter people from participating in this forum. Bill --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to encapsulate local state in closures
On Sat, Dec 27, 2008 at 12:03 AM, Mark Engelberg mark.engelb...@gmail.com wrote: On Fri, Dec 26, 2008 at 8:35 PM, Adrian Cuthbertson adrian.cuthbert...@gmail.com wrote: It's important to distinguish between updating atoms within transactions and outside transactions. In the former case, one has to ensure the update function can be retried without ill-effects. However, outside a transaction, atoms are just mutable values, that can safely be shared between threads, provided that their updating does not need to be coordinated with other updates (to other atoms, refs or agents). Yes, but when you write your atom-based code, you have no way to know whether you or others who want to reuse it will want to use it as part of a transaction. atom-based code is not generally safe for transactions, which is why I suggested it should be avoided. In your example, if incserid is used in a transaction, it is possible that certain serids will be skipped. This may be acceptable, in which case, go ahead and use an atom, but often programs rely on subtle assumptions (like the serids will be issued consecutively), and your program can become brittle if there's a chance your code won't follow these assumptions. Probably better off not to take the chance. Stick with something like refs which will yield more predictable behavior, and thus be easier to test. Memoization is a very special exception, because it really doesn't matter if something gets cached more than once. The whole point of Clojure seems to make as much code as possible safe for its software transactional memory. Thus the persistent data structures, and other design details. Although interoperating with Java also produces risk within transaction, generally speaking, if you stay within the Clojure core, you're safe for transactions. Except atoms. It is certainly not the whole point of Clojure to make as much code as possible safe for its software transactional memory. Clojure is a set of tools. They are designed to allow for robust programs to be built, including multithreaded programs. STM is one of those tools, but is not a universal answer. I think it would be wise to avoid sweeping generalizations - sweeping generalizations are always wrong :) There are many things that will never be safe inside transactions - I/O in particular, and you can look at many forms of mutation (e.g. all the Java OO mutation) as I/O of a sort. That doesn't mean that these things aren't useful, or should be avoided. Good practice programming with STM involves segregating the I/O portion of your code from the transactional portion, and minimizing the footprint of your transactions in general. I think many people look at the facilities provided by Clojure and hope there's also some magic recipe for good multithreaded designs. There isn't. Even with Clojure's (or any language's) tools, you have to think. I don't disagree that refs should be your first choice, and that atoms are special purpose tools for more experienced users. But they are not just for memoization caches. Taking the case at hand, ID generation. A modern multithreaded program would try to avoid monotonically increasing consecutive IDs, as any implementation of that would be a severe concurrency bottleneck. If you were to use a ref as an ID source, every transaction would have to line up for access to that ref. Yes, it will be predictable - with predictably bad scalability. Using an atom for this can seriously improve the throughput of transactions, by removing what might be the only ref they share. I think everyone should try to avoid dispensing advice from theoretical arguments. You need to understand your tools, the tradeoffs they involve, the use case at hand, and make good decisions. 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 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: making code readable
On Dec 29, 2008, at 10:45 AM, Mark Volkmann wrote: On Mon, Dec 29, 2008 at 5:44 AM, Mark Volkmann r.mark.volkm...@gmail.com wrote: I would like to produce a version of the snake code that could serve as an example of the kind of code that the Clojure community thinks is good. Unless it's part of an exercise to produce the shortest code possible, I think we should always write Clojure code with a goal of making it as easy as possible for others to read, while not attempting to serve as a Clojure tutorial. Again, my goal here is to get more developers to give Clojure a shot. My challenge to everyone on the list is to start with any version of the snake code you've seen and make it as readable as *you* think it should be by doing things like renaming variables and functions, adding comments and changing indentation. I'd really like to see what *you* think is the best way to write this code. The lessons learned from this exercise could then be applied to other code we write in the future. Okay, I took the challenge and produced a modified version of my earlier code where I removed what I considered to be redundant comments and did a little more renaming. You can see it at http://www.ociweb.com/mark/programming/ClojureSnake.html. Feedback is welcomed! I also started documenting some Clojure coding guidelines aimed at making code more readable at http://www.ociweb.com/mark/programming/ClojureCodingGuidelines.html and would appreciate feedback on these. I expect there will be cases where not following these is justified, which is why I refer to them as guidelines instead of rules. Much of Norvig's Tutorial on Good Lisp Programming Style is applicable to Clojure. http://norvig.com/luv-slides.ps[PS] http://www.cs.umd.edu/~nau/cmsc421/norvig-lisp-style.pdf[PDF] -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ 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: making code readable
You should consider using docstrings for documenting functions On 29 déc, 16:45, Mark Volkmann r.mark.volkm...@gmail.com wrote: On Mon, Dec 29, 2008 at 5:44 AM, Mark Volkmann r.mark.volkm...@gmail.com wrote: I would like to produce a version of the snake code that could serve as an example of the kind of code that the Clojure community thinks is good. Unless it's part of an exercise to produce the shortest code possible, I think we should always write Clojure code with a goal of making it as easy as possible for others to read, while not attempting to serve as a Clojure tutorial. Again, my goal here is to get more developers to give Clojure a shot. My challenge to everyone on the list is to start with any version of the snake code you've seen and make it as readable as *you* think it should be by doing things like renaming variables and functions, adding comments and changing indentation. I'd really like to see what *you* think is the best way to write this code. The lessons learned from this exercise could then be applied to other code we write in the future. Okay, I took the challenge and produced a modified version of my earlier code where I removed what I considered to be redundant comments and did a little more renaming. You can see it athttp://www.ociweb.com/mark/programming/ClojureSnake.html. Feedback is welcomed! I also started documenting some Clojure coding guidelines aimed at making code more readable athttp://www.ociweb.com/mark/programming/ClojureCodingGuidelines.html and would appreciate feedback on these. I expect there will be cases where not following these is justified, which is why I refer to them as guidelines instead of rules. -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Swank in Tomcat via JSP: classpath issues
Hi, I'm not sure how to integrate this into the Tomcat JSP scenario, but I think the issue is that *use-context-classloader* is not set to true (it defaults to nil). Again, I'm not positive how to get your JSP to do this, but an untested stab at it would be just to wrap the call to clojure.main/with-bindings in a binding expression: Modified from http://paste.lisp.org/display/71541: final String startSwankScript = (add-classpath \file:///c:/usr/unpacked/clojure/swank-clojure/\)\n + (require (quote swank) (quote clojure.main))\n + (binding [*use-context-classloader* true]\n + (clojure.main/with-bindings\n + (swank/ignore-protocol-version \2008-11-23\)\n + (swank/start-server \nul\ :encoding \utf-8-unix\ :port )))\n; I had a similar issue when working with Clojure in a J2EE web app context. This did the trick. Explanation: Clojure needs its own implementation of a ClassLoader in order to be able to define classes that it compiles from user code. By default, when it resolves classes it reuses this dynamic classloader. If you however bind the var *use-context-classloader*, then it will instead try and use Thread.currentThread().getContextClassLoader() to resolve classes. J2EE specifies that a servlet container must define a context class loader, and so with this set it should do what you need. /mike. On Sun, Dec 28, 2008 at 11:04 PM, Greg Harman ghar...@gmail.com wrote: Thanks for that - I'm all up to date now. The bad news is that it didn't seem to affect my problem at all. On Dec 28, 6:58 pm, Michael Wood esiot...@gmail.com wrote: The current version of Clojure is 1185. Clojure was recently moved to Google Code: http://groups.google.com/group/clojure/browse_thread/thread/6b4a5284d... I don't know if that has anything to do with your problem, though. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Swank in Tomcat via JSP: classpath issues
Doh! I just read your discussion w/ Anton on his blog. Seems you've already looked at the context classloader. *shrug*. I'm stumped. /mike. On Mon, Dec 29, 2008 at 12:46 PM, Michael Reid kid.me...@gmail.com wrote: Hi, I'm not sure how to integrate this into the Tomcat JSP scenario, but I think the issue is that *use-context-classloader* is not set to true (it defaults to nil). Again, I'm not positive how to get your JSP to do this, but an untested stab at it would be just to wrap the call to clojure.main/with-bindings in a binding expression: Modified from http://paste.lisp.org/display/71541: final String startSwankScript = (add-classpath \file:///c:/usr/unpacked/clojure/swank-clojure/\)\n + (require (quote swank) (quote clojure.main))\n + (binding [*use-context-classloader* true]\n + (clojure.main/with-bindings\n + (swank/ignore-protocol-version \2008-11-23\)\n + (swank/start-server \nul\ :encoding \utf-8-unix\ :port )))\n; I had a similar issue when working with Clojure in a J2EE web app context. This did the trick. Explanation: Clojure needs its own implementation of a ClassLoader in order to be able to define classes that it compiles from user code. By default, when it resolves classes it reuses this dynamic classloader. If you however bind the var *use-context-classloader*, then it will instead try and use Thread.currentThread().getContextClassLoader() to resolve classes. J2EE specifies that a servlet container must define a context class loader, and so with this set it should do what you need. /mike. On Sun, Dec 28, 2008 at 11:04 PM, Greg Harman ghar...@gmail.com wrote: Thanks for that - I'm all up to date now. The bad news is that it didn't seem to affect my problem at all. On Dec 28, 6:58 pm, Michael Wood esiot...@gmail.com wrote: The current version of Clojure is 1185. Clojure was recently moved to Google Code: http://groups.google.com/group/clojure/browse_thread/thread/6b4a5284d... I don't know if that has anything to do with your problem, though. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: making code readable
On Monday 29 December 2008 09:11, lpetit wrote: You should consider using docstrings for documenting functions There's a big difference between the comments directed at someone reading the code (possibly the author at a later date) and someone wishing to use it. Function-level documentation strings serve only the latter class of person. Randall Schulz --~--~-~--~~~---~--~~ 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: IntelliJ Plugin
On Sat, Dec 27, 2008 at 8:55 AM, Peter Wolf opus...@gmail.com wrote: Hi Justin, This is the right place. Thanks for trying the plugin. It would absolutely be helpful to document use of the plugin. However, I am sure you can tell that it is nowhere near ready. Yes, I noticed there wasn't much there yet. I still think it would be great if you documented how you build and test. In particular I found it to be a pain to setup my own update site and updatePlugins.xml file just to install my own plugin. It wasn't difficult, but certainly not efficient. My hope was that sharing setup info like this would help me discover more efficient ways of working. I would like to get a basic set of features going and then recruit you and Randall to test and document it. Once it is banged on, we can post the plugin to IntelliJ so it can be installed with a mouse click. I am currently working on the Parser, which will give us parens matching and folding, and Compile/Run/Debug/Profile. The one big piece I am missing is the REPL. Any help would be appreciated. Peter On Wed, Dec 24, 2008 at 4:25 PM, Justin Johnson ajustinjohn...@gmail.comwrote: Hi, Is this the appropriate mailing list to talk about the Clojure IntelliJ plugin? The Google Code site didn't list any other mailing list. http://code.google.com/p/clojure-intellij-plugin/ I went through the process of building and installing the plugin on Windows XP with IntelliJ IDEA 8.0.1 and thought it might be helpful if I document what I did on the wiki. I also have a small suggestion that the build.xml file use environment variables instead of hard coded paths to java.home and idea.home. Thanks, Justin --~--~-~--~~~---~--~~ 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: Suggestion: introduce (defn name attr-map? [params*] doc-string body) form.
Rich rest. I have gone through the process of implementing this in defn. The patch is inlined for commenting (if need be) and attached for accurate application. I declare my changes public domain, but I suppose I could fill out a CA if it helps. I can also make a similar change for defmacro, if you want. But if you don't want this at all, then I'll go weep in a corner and leave it at that. $ svn diff Index: src/clj/clojure/core.clj === --- src/clj/clojure/core.clj(revision 1188) +++ src/clj/clojure/core.clj(working copy) @@ -183,6 +183,7 @@ name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata :arglists '([name doc-string? attr-map? [params*] body] +[name attr-map? [params*] doc-string body] [name doc-string? attr-map? ([params*] body)+ attr-map?])} defn (fn defn [name fdecl] (let [m (if (string? (first fdecl)) @@ -197,6 +198,13 @@ fdecl (if (map? (first fdecl)) (rest fdecl) fdecl) + m (if (clojure.lang.Numbers/lt 2 (clojure.lang.RT/length fdecl)) + (if (vector? (first fdecl)) +(if (string? (second fdecl)) + (if (m :doc) m (assoc m :doc (second fdecl))) + m) +m) + m) fdecl (if (vector? (first fdecl)) (list fdecl) fdecl) On Fri, Dec 19, 2008 at 1:06 PM, Christian Vest Hansen karmazi...@gmail.com wrote: On Fri, Dec 19, 2008 at 12:46 PM, Michael Wood esiot...@gmail.com wrote: Where would it go when you have multiple parameter lists and bodies? (defn blah ([a] (do-something-with a)) ([a b] (do-something-with a b))) That case should be unchanged, and work as it does today. -- Michael Wood esiot...@gmail.com -- Venlig hilsen / Kind regards, Christian Vest Hansen. -- Venlig hilsen / Kind regards, Christian Vest Hansen. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~--- doc-string.patch Description: Binary data
Re: making code readable
On Mon, Dec 29, 2008 at 11:11 AM, lpetit laurent.pe...@gmail.com wrote: You should consider using docstrings for documenting functions Good suggestion. I've changed my code to do that. I also noticed that I had forgotten to replace special characters with built-in entities in my HTML, so that is fixed now. The new version is at http://www.ociweb.com/mark/programming/ClojureSnake.html. What else would you do different in this code? Do you think it still contains too many comments? On 29 déc, 16:45, Mark Volkmann r.mark.volkm...@gmail.com wrote: On Mon, Dec 29, 2008 at 5:44 AM, Mark Volkmann r.mark.volkm...@gmail.com wrote: I would like to produce a version of the snake code that could serve as an example of the kind of code that the Clojure community thinks is good. Unless it's part of an exercise to produce the shortest code possible, I think we should always write Clojure code with a goal of making it as easy as possible for others to read, while not attempting to serve as a Clojure tutorial. Again, my goal here is to get more developers to give Clojure a shot. My challenge to everyone on the list is to start with any version of the snake code you've seen and make it as readable as *you* think it should be by doing things like renaming variables and functions, adding comments and changing indentation. I'd really like to see what *you* think is the best way to write this code. The lessons learned from this exercise could then be applied to other code we write in the future. Okay, I took the challenge and produced a modified version of my earlier code where I removed what I considered to be redundant comments and did a little more renaming. You can see it athttp://www.ociweb.com/mark/programming/ClojureSnake.html. Feedback is welcomed! I also started documenting some Clojure coding guidelines aimed at making code more readable athttp://www.ociweb.com/mark/programming/ClojureCodingGuidelines.html and would appreciate feedback on these. I expect there will be cases where not following these is justified, which is why I refer to them as guidelines instead of rules. -- R. Mark Volkmann Object Computing, Inc. -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to encapsulate local state in closures
On Mon, Dec 29, 2008 at 8:05 AM, Rich Hickey richhic...@gmail.com wrote: It is certainly not the whole point of Clojure to make as much code as possible safe for its software transactional memory. Clojure is a set of tools. They are designed to allow for robust programs to be built, including multithreaded programs. STM is one of those tools, but is not a universal answer. It's good to hear you say this, because I agree. I was dispensing advice based on my perception of your philosophy (and because I sense from discussions that most people are assuming atoms are safe in ways they really aren't). But in fact, I think that Clojure's tools for mutability don't yet go far enough, and I'd prefer to have a few more unsafe things in the toolbox for experienced programmers. For example, mutability is extremely useful for constructing/initializing complex data structures, especially ones that have cyclic references. (Or think about how StringBuffer is used to set up a string with mutability, and then it is delivered as an immutable String). Also, mutability of local variables can be handy when implementing a complex classic algorithm that is described as a sequence of imperative steps, in order to keep the form of the code as close as possible to the source. This sort of local mutability has no impact on referential transparency, and is really quite safe when used properly. But none of the existing types of mutability seem like a good fit for this need. It seems like overkill to have to use a ref or atom with their transaction or swapping syntaxes in order to mutate something that will never be observed as mutable by the outside world. --~--~-~--~~~---~--~~ 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: Modulo
On Dec 29, 7:50 am, Achim Passen achim.pas...@gmail.com wrote: Hi! I uploaded my attempt at this to the files section of this group: http://clojure.googlegroups.com/web/mod-sgn.diff It adds the modulus operator plus, as a by-product, the signum operator (sgn). Comments most welcome! Thanks! Could you (and everyone) please submit patches as attachments on the relevant issue? I want to get away from patches in messages and in the files section. Thanks, Rich On 29 Dez., 07:01, Rich Hickey richhic...@gmail.com wrote: On Dec 29, 12:44 am, Mark Engelberg mark.engelb...@gmail.com wrote: So I understand that we're supposed to discuss ideas here to try to gain mindshare which is why last week I brought up the issue with Clojure missing mod (which works differently from rem on negative numbers). So really, no one else cares about this, or was the post just lost in the shuffle of holiday time? On Mon, Dec 22, 2008 at 4:04 AM, Mark Engelberg mark.engelb...@gmail.com wrote: Anyone know why there is no modulo or mod function in Clojure's core? I know there is a rem function, but that's not the same thing. mod and rem behave differently when the first number is negative. (mod -2 5) - 3 (rem -2 5) - -2 modulo n is important for making things stay in the range from 0 to n-1, for example, if you're working with vectors of length n. You need to ensure that negative numbers wrap around to the positive range. rem does not do this. I'm more familiar with Scheme than CL, and I know PLT Scheme provides both modulo and remainder. But according to the Wikipedia (http://en.wikipedia.org/wiki/Modulo_operation), Common Lisp also provides both mod and rem functions. So why not Clojure? Is it a Java defeciency? Holidays here. Feel free to create an issue for this: http://code.google.com/p/clojure/issues/list Patch (from a registered contributor) welcome. 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 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 -~--~~~~--~~--~--~---
load-file within a do
Hi everybody, I just got started with Clojure and I'm now trying to simultaneously learn Lisp and Java. My progress is slow, but I'm having a lot of fun. I hit a small roadblock though, because I can't figure out why calling load-file from within a do is behaving the way it is. I'm probably missing something obvious, but hopefully someone will be able to explain it. I created a small file foo.clj with the following contents: (defn foo [] :bar) Then from a REPL I try the following: (do (load-file foo.clj) (foo)) but this gives an error message: java.lang.Exception: Unable to resolve symbol: foo in this context (NO_SOURCE_FILE :1) Strangely enough, the following does work: (do (load-file foo.clj) (ns-interns 'user)) This returns {foo #'user/foo} (as expected) So, while it seems that the file gets loaded and the function gets added to the namespace, calling it from within the do doesn't seem to work. What's going on? thanks, Kees --~--~-~--~~~---~--~~ 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: (Updated) Patch available: unifies entry points, fixes (read-line) for clojure.main/repl, provides source-only jar
On Dec 21, 5:53 pm, Stephen C. Gilardi squee...@mac.com wrote: On Dec 21, 2008, at 4:43 PM, Stephen C. Gilardi wrote: On Dec 21, 2008, at 4:40 PM, Rich Hickey wrote: If main doesn't match the behavior of Repl and Script in this area when run in repl or script modes respectively, it needs to. Repl calls exit, Script does not. OK, I'll fix that. This is fixed in the enclosed unified-main-3.patch . Patch applied (svn 1189) - thanks! 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 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: [jvm-l] Kawa Scheme on Android
On Sun, Dec 28, 2008 at 6:05 PM, Randall R Schulz rsch...@sonic.net wrote: Howdy, Folks, The gauntlet has been thrown down: I've made changes in svn 1186 and 1188 that should help facilitate targeting Android/Dalvik. clojure.jar now translates with dx --dex, but that is all I've had time to look at. If people have time to try it, I'll follow up on any issues that arise. 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 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: load-file within a do
Hi Kees-Jochem, Am 29.12.2008 um 20:37 schrieb Kees-Jochem Wehrmeijer: I created a small file foo.clj with the following contents: (defn foo [] :bar) Then from a REPL I try the following: (do (load-file foo.clj) (foo)) but this gives an error message: java.lang.Exception: Unable to resolve symbol: foo in this context (NO_SOURCE_FILE :1) You have to distinguish compile time from runtime. The load-file happens during runtime. However the compiler looks about foo already during compile time. But since the file is not loaded, the compiler doesn't find foo and, hence, complains. Strangely enough, the following does work: (do (load-file foo.clj) (ns-interns 'user)) This returns {foo #'user/foo} (as expected) Not at all strange: Since the *call* to ns-interns happens at runtime, the foo.clj is already loaded. Hence, foo is defined and everything is fine. So, while it seems that the file gets loaded and the function gets added to the namespace, calling it from within the do doesn't seem to work. What's going on? So it's not actually the do, but the different times when things happen. Instead of load-file, use a namespace. Although, this may already be a bit involved depending how far you already got with your learning. Create a file named foo/bar.clj in your classpath. In this file put the following: (ns foo.bar) (defn foo [] :bar) Then do at the Repl: (use 'foo.bar) (foo) This should work without problems, since use loads the file at compile time. So the compiler knows about the foo definition and everything works out. Hope this helps. Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Re: making code readable
Looking at this code the uppercase variables stands out. This isn't idiomatic is it? (def GRID_SIZE 10) (def HEIGHT 600) (def MARGIN 50) On Mon, Dec 29, 2008 at 12:19 PM, Mark Volkmann r.mark.volkm...@gmail.comwrote: On Mon, Dec 29, 2008 at 11:11 AM, lpetit laurent.pe...@gmail.com wrote: You should consider using docstrings for documenting functions Good suggestion. I've changed my code to do that. I also noticed that I had forgotten to replace special characters with built-in entities in my HTML, so that is fixed now. The new version is at http://www.ociweb.com/mark/programming/ClojureSnake.html. What else would you do different in this code? Do you think it still contains too many comments? On 29 déc, 16:45, Mark Volkmann r.mark.volkm...@gmail.com wrote: On Mon, Dec 29, 2008 at 5:44 AM, Mark Volkmann r.mark.volkm...@gmail.com wrote: I would like to produce a version of the snake code that could serve as an example of the kind of code that the Clojure community thinks is good. Unless it's part of an exercise to produce the shortest code possible, I think we should always write Clojure code with a goal of making it as easy as possible for others to read, while not attempting to serve as a Clojure tutorial. Again, my goal here is to get more developers to give Clojure a shot. My challenge to everyone on the list is to start with any version of the snake code you've seen and make it as readable as *you* think it should be by doing things like renaming variables and functions, adding comments and changing indentation. I'd really like to see what *you* think is the best way to write this code. The lessons learned from this exercise could then be applied to other code we write in the future. Okay, I took the challenge and produced a modified version of my earlier code where I removed what I considered to be redundant comments and did a little more renaming. You can see it athttp:// www.ociweb.com/mark/programming/ClojureSnake.html. Feedback is welcomed! I also started documenting some Clojure coding guidelines aimed at making code more readable athttp:// www.ociweb.com/mark/programming/ClojureCodingGuidelines.html and would appreciate feedback on these. I expect there will be cases where not following these is justified, which is why I refer to them as guidelines instead of rules. -- R. Mark Volkmann Object Computing, Inc. -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ 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: distinct broken?
Fixed (rev 1190) tristan a écrit : Thanks for the explanation Christophe. I really need to try use (for) more often. I seem to forget about it all the time. On Dec 27, 10:42 pm, Christophe Grand christo...@cgrand.net wrote: tristan a écrit : Hi All, I've been trying to learn clojure lately by solving the project euler problems with it, and I think the distinct function is broken (or it doesn't quite work as I assume it would). here is the code i'm running (defn pow [nbr pwr] (if ( pwr 2) nbr (* nbr (pow nbr (dec pwr) (count (sort (distinct (apply concat (map (fn [i] (map (fn [j] (pow i j)) (range 2 101))) (range 2 101)) for which the result shows 9188, but should be 9183. distinct uses a hash-set (which relies on .hashCode): user= (vector (- 4294967296 BigInteger. .hashCode) (- 4294967296 Long. .hashCode)) [31 1] But: user= (compare (- 4294967296 BigInteger.) (- 4294967296 Long.)) 0 Since sorted-sets relies on compare you could rewrite distinict to use a sorted-set: (defn distinct1 Returns a lazy sequence of the elements of coll with duplicates removed [coll] (let [step (fn step [[f r :as xs] seen] (when xs (if (seen f) (recur r seen) (lazy-cons f (step r (conj seen f))] (step (seq coll) (sorted-set user= (- (for [i (range 2 101) j (range 2 101)] (pow i j)) distinct1 count) 9183 or, without rewriting distinct: user= (count (into (sorted-set) (for [i (range 2 101) j (range 2 101)] (pow i j 9183 I don't know how to fix distinct per se (short of documenting this case). Maybe by adding a distinct-by function which would take a comparator as its first arg. Christophe I wrote my own distinct function which gives the correct result but runs a LOT slower (defn in? [lst n] (if (nil? lst) false (if (= (first lst) n) true (in? (rest lst) n (defn unique [lst] (loop [l lst n (list)] (if (nil? l) (sort n) (if (in? n (first l)) (recur (rest l) n) (recur (rest l) (cons (first l) n)) i'm using revision 1185. is this a bug or am i doing something wrong? thanks -Tristan --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to encapsulate local state in closures
On Dec 29, 2:29 pm, Mark Engelberg mark.engelb...@gmail.com wrote: On Mon, Dec 29, 2008 at 8:05 AM, Rich Hickey richhic...@gmail.com wrote: It is certainly not the whole point of Clojure to make as much code as possible safe for its software transactional memory. Clojure is a set of tools. They are designed to allow for robust programs to be built, including multithreaded programs. STM is one of those tools, but is not a universal answer. It's good to hear you say this, because I agree. I was dispensing advice based on my perception of your philosophy (and because I sense from discussions that most people are assuming atoms are safe in ways they really aren't). But in fact, I think that Clojure's tools for mutability don't yet go far enough, and I'd prefer to have a few more unsafe things in the toolbox for experienced programmers. For example, mutability is extremely useful for constructing/initializing complex data structures, especially ones that have cyclic references. (Or think about how StringBuffer is used to set up a string with mutability, and then it is delivered as an immutable String). Also, mutability of local variables can be handy when implementing a complex classic algorithm that is described as a sequence of imperative steps, in order to keep the form of the code as close as possible to the source. This sort of local mutability has no impact on referential transparency, and is really quite safe when used properly. But none of the existing types of mutability seem like a good fit for this need. It seems like overkill to have to use a ref or atom with their transaction or swapping syntaxes in order to mutate something that will never be observed as mutable by the outside world. People who know what they are doing can do these things right now with Clojure's array support. There really isn't any more value for Clojure to add to that, so no special primitives. I fully accept the necessity of doing that at times, and the correctness of internally mutating, but externally referentially transparent functions, and Clojure has several of them. That's one of the reasons Clojure isn't 'pure'. OTOH it's not a good argument for mutable local vars. What other unsafe things are you looking for? People could have used j.u.c.atomic also, but atom provides a unified interface consistent with the other reference types, and using swap! encourages a race-free discipline most people wouldn't pursue with plain mutable locals and often get wrong with CAS. 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 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: Accessing this in gen-class constructor
On Sat, Dec 27, 2008 at 9:24 PM, CuppoJava patrickli_2...@hotmail.com wrote: I believe the first parameter must be this, only in the case of methods . The init function doesn't take a this parameter. Correct. My understanding is that the init function is actually run before the instance is even created. So no only is there no this parameter, there's not even a this value yet. Instead, your init function returns values to pass to the superclass constructor and the value to use as your object's state. Also note that I had to specify :constructors in order for my init to accept no args but to use the constructor of the superclass that takes a String. (ns net.n01se.MyThread (:gen-class :extends java.lang.Thread :constructors {[] [String]} :init my-init :state myState :exposes-methods {getId getIdSuper})) (defn -my-init [] (prn :init-my-thread) [[my derived class] this is my state]) (defn -getId [this] (+ 123000 (.getIdSuper this))) This also demonstrates the use of :exposes-methods to call the superclass's implementation of a method I'm overridding. Note that because I didn't use a mutable object for myState, (instead using the string this is my state), there's no way to change the value of myState. user= (compile 'net.n01se.MyThread) net.n01se.MyThread user= (def x (net.n01se.MyThread.)) :init-my-thread #'user/x user= (.myState x) this is my state user= (.getId x) 123008 user= (.getName x) my derived class --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 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: making code readable
On Mon, Dec 29, 2008 at 2:24 PM, Brian Doyle brianpdo...@gmail.com wrote: Looking at this code the uppercase variables stands out. This isn't idiomatic is it? (def GRID_SIZE 10) (def HEIGHT 600) (def MARGIN 50) I don't know. I was following Java conventions of making constants all uppercase. Is there a convention for this in Clojure? Is there a way I could prevent them from being changed later? Maybe I should make them be map entries where the keys are keywords and the values are the integers. That seems extreme though. On Mon, Dec 29, 2008 at 12:19 PM, Mark Volkmann r.mark.volkm...@gmail.com wrote: On Mon, Dec 29, 2008 at 11:11 AM, lpetit laurent.pe...@gmail.com wrote: You should consider using docstrings for documenting functions Good suggestion. I've changed my code to do that. I also noticed that I had forgotten to replace special characters with built-in entities in my HTML, so that is fixed now. The new version is at http://www.ociweb.com/mark/programming/ClojureSnake.html. What else would you do different in this code? Do you think it still contains too many comments? On 29 déc, 16:45, Mark Volkmann r.mark.volkm...@gmail.com wrote: On Mon, Dec 29, 2008 at 5:44 AM, Mark Volkmann r.mark.volkm...@gmail.com wrote: I would like to produce a version of the snake code that could serve as an example of the kind of code that the Clojure community thinks is good. Unless it's part of an exercise to produce the shortest code possible, I think we should always write Clojure code with a goal of making it as easy as possible for others to read, while not attempting to serve as a Clojure tutorial. Again, my goal here is to get more developers to give Clojure a shot. My challenge to everyone on the list is to start with any version of the snake code you've seen and make it as readable as *you* think it should be by doing things like renaming variables and functions, adding comments and changing indentation. I'd really like to see what *you* think is the best way to write this code. The lessons learned from this exercise could then be applied to other code we write in the future. Okay, I took the challenge and produced a modified version of my earlier code where I removed what I considered to be redundant comments and did a little more renaming. You can see it athttp://www.ociweb.com/mark/programming/ClojureSnake.html. Feedback is welcomed! I also started documenting some Clojure coding guidelines aimed at making code more readable athttp://www.ociweb.com/mark/programming/ClojureCodingGuidelines.html and would appreciate feedback on these. I expect there will be cases where not following these is justified, which is why I refer to them as guidelines instead of rules. -- R. Mark Volkmann Object Computing, Inc. -- R. Mark Volkmann Object Computing, Inc. -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ 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: 12 Days of Christmas in idiomatic(?) clojure
Emeka, In short, no. Remember, this was about me learning some functional tools, so this shouldn't be viewed as pedagogical. Well, *my* code shouldn't - I can't speak for the other posters in this thread. -Matt On Dec 27, 7:28 am, Emeka emekami...@gmail.com wrote: (defn sum-up-to [n] returns the sum of the positive integers from 1 to n (apply + 0 (map #(+ 1 %) (range n Is there any reason for that zero ('0')? I guess your function could work with it. Emeka --~--~-~--~~~---~--~~ 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: making code readable
On Dec 29, 3:40 pm, Mark Volkmann r.mark.volkm...@gmail.com wrote: On Mon, Dec 29, 2008 at 2:24 PM, Brian Doyle brianpdo...@gmail.com wrote: Looking at this code the uppercase variables stands out. This isn't idiomatic is it? (def GRID_SIZE 10) (def HEIGHT 600) (def MARGIN 50) I don't know. I was following Java conventions of making constants all uppercase. Is there a convention for this in Clojure? Hi Mark, There's a Common Lisp convention of surrounding constant names with +, like: (def +grid-size+ 10) but even in CL it's not followed consistently. Go with what feels good. :) Is there a way I could prevent them from being changed later? Not really, you can always re-def. -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 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: making code readable
On Mon, Dec 29, 2008 at 3:40 PM, Mark Volkmann r.mark.volkm...@gmail.com wrote: On Mon, Dec 29, 2008 at 2:24 PM, Brian Doyle brianpdo...@gmail.com wrote: Looking at this code the uppercase variables stands out. This isn't idiomatic is it? (def GRID_SIZE 10) (def HEIGHT 600) (def MARGIN 50) I don't know. I believe the idiom for global values like this is to place asterisks around the name. Underscores (and CamelCase) should only be used when required for Java interop: (def *grid-size* 10) (def *height* 600) (def *margin* 50) (def *x-index* 0) (def *y-index* 1) I was following Java conventions of making constants all uppercase. Is there a convention for this in Clojure? Is there a way I could prevent them from being changed later? I'm not aware of anyway to make a global constant. By using a Var as you've done, the only way to change them is to use 'def' again (which is a big hammer and very much discouraged inside regular functions) or to use 'binding' to temporarily change their values within a particular thread. I think what you have is sufficient for communicating your intended meaning. On a more general point, I'd personally recommend being wary of over-investing in comments. This is not a radical recommendation, but I'll bring up again anyway that thought that it's better to write code in such a way that it explains itself than to add comments to code that doesn't. Only when the former is insufficient should more comments be added. Every line of comment is another line of code that must be maintained, and worse than that it's a line that no compiler or unit test is ever going to indicate as incorrect. When adding a comment, I think it's appropriate to be sure that the maintenance cost of the comment itself outweighs the maintenance cost of having no comment (or a shorter or more general comment). An example of this point -- Abhishek's original code used a hash with:x and :y keys to indicate coordinates. I changed this to a two-element vector only in pursuit of this particular puzzle's goals, namely fewer lines of code. This is a very different goal from most code, which should be maintainability, and also different from tutorial code, which should be about teaching Clojure to someone who doesn't already know it. For either of those latter goals, I would contend Abhishek's solution was a better one -- using :x and :y help indicate what's going on without global index names (like *x-index*) or much extra commenting. Another example -- if you find a particular use of #() to be too confusing on its own, consider replacing it with a (fn ...), which allows the naming of each argument as well as destructuring. This can again improve readability without require more comments. I think your expanded version of the snake program may be very beneficial to some, though with a different purpose than the original version, so thanks for providing it. Personally, I wouldn't want to maintain a large codebase that was written using either style, as both are a bit extreme in opposite ends of the verbosity scale. As I've said elsewhere golfing is fun, if not broadly useful. Conversely, tutorial-style code may be very useful in appropriate contexts, but is hardly ever fun to write. ...and now this post is at an extreme of the verbosity scale. Sorry all, I'll quit now before I get any further behind. --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 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: making code readable
On Mon, Dec 29, 2008 at 3:01 PM, Stuart Sierra the.stuart.sie...@gmail.com wrote: On Dec 29, 3:40 pm, Mark Volkmann r.mark.volkm...@gmail.com wrote: On Mon, Dec 29, 2008 at 2:24 PM, Brian Doyle brianpdo...@gmail.com wrote: Looking at this code the uppercase variables stands out. This isn't idiomatic is it? (def GRID_SIZE 10) (def HEIGHT 600) (def MARGIN 50) I don't know. I was following Java conventions of making constants all uppercase. Is there a convention for this in Clojure? Hi Mark, There's a Common Lisp convention of surrounding constant names with +, like: (def +grid-size+ 10) but even in CL it's not followed consistently. Go with what feels good. :) Is there a way I could prevent them from being changed later? Not really, you can always re-def. Thanks for the info. Stuart! It's early enough in the life of Clojure that we haven't developed any deeply held habits yet. I think it would be a good idea for you and other Clojure committers to at least suggest the way you think things should be done in code. If you think surrounding names of constants with plus signs is a good way to identify them as such, I'll gladly start doing that for the sake of consistency. I don't think it's a good idea for all of us to simply do what feels good because that will make it harder to read code written by others. -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ 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: making code readable
On Mon, Dec 29, 2008 at 3:10 PM, Chouser chou...@gmail.com wrote: On Mon, Dec 29, 2008 at 3:40 PM, Mark Volkmann r.mark.volkm...@gmail.com wrote: On Mon, Dec 29, 2008 at 2:24 PM, Brian Doyle brianpdo...@gmail.com wrote: Looking at this code the uppercase variables stands out. This isn't idiomatic is it? (def GRID_SIZE 10) (def HEIGHT 600) (def MARGIN 50) I don't know. I believe the idiom for global values like this is to place asterisks around the name. Underscores (and CamelCase) should only be used when required for Java interop: (def *grid-size* 10) (def *height* 600) (def *margin* 50) (def *x-index* 0) (def *y-index* 1) I think that's supposed to be + instead of *, at least Common Lisp seems to use +. On a more general point, I'd personally recommend being wary of over-investing in comments. This is not a radical recommendation, but I'll bring up again anyway that thought that it's better to write code in such a way that it explains itself than to add comments to code that doesn't. Only when the former is insufficient should more comments be added. I agree completely! In some programming languages, for example Smalltalk, I feel like I can almost always write the code in a way that doesn't require comments. However, I don't feel able to do that as often in Clojure. I think it's because you can do so much with so little code in Clojure. For example, here's some code that I don't know how to rewrite in a way that I find self-explanatory: (every? #(= (- (apple %) +grid-size+) (head %) (+ (apple %) +grid-size+)) [+x-index+ +y-index+])) And here's another one: (assoc snake :body (cons (vec (map #(+ (dir %) ((first body) %)) [+x-index+ +y-index+])) (if grow body (butlast body) Perhaps using your suggestion to go back and use a map with :x and :y keys instead of a two-element vector to represent x/y coordinates would help a little, but I'm still not sure the code would be immediately obvious. Maybe it's just a matter of time before I'm good enough at reading Clojure code that I won't feel the need to add comments to these. Even if that happens though, I'll still be concerned about the ability of other developers that haven't yet reached that level of proficiency to understand my code. -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ 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: making code readable
On Mon, Dec 29, 2008 at 4:40 PM, Mark Volkmann r.mark.volkm...@gmail.com wrote: I think that's supposed to be + instead of *, at least Common Lisp seems to use +. I meant * -- I don't know CL at all, but the *asterisk* form is used frequently in clojure.core, while no +plus+ form ever appears. I also was careful to refer to the global nature of the Vars, not anything about const-ness. --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 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: making code readable
I don't know CL that well myself, but I think the convention is to use + for constants (i.e. defconst) where * is used for global variables (i.e. defparameter). In that case the + convention doesn't really make sense in clojure as it doesn't have any notion of a constant reference type. --Darren On Mon, Dec 29, 2008 at 1:58 PM, Chouser chou...@gmail.com wrote: On Mon, Dec 29, 2008 at 4:40 PM, Mark Volkmann r.mark.volkm...@gmail.com wrote: I think that's supposed to be + instead of *, at least Common Lisp seems to use +. I meant * -- I don't know CL at all, but the *asterisk* form is used frequently in clojure.core, while no +plus+ form ever appears. I also was careful to refer to the global nature of the Vars, not anything about const-ness. --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 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: making code readable
On Mon, Dec 29, 2008 at 3:58 PM, Chouser chou...@gmail.com wrote: On Mon, Dec 29, 2008 at 4:40 PM, Mark Volkmann r.mark.volkm...@gmail.com wrote: I think that's supposed to be + instead of *, at least Common Lisp seems to use +. I meant * -- I don't know CL at all, but the *asterisk* form is used frequently in clojure.core, while no +plus+ form ever appears. I also was careful to refer to the global nature of the Vars, not anything about const-ness. Ah ... thanks for clarifying that! I've changed my code at http://www.ociweb.com/mark/programming/ClojureSnake.html to follow that convention. -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to encapsulate local state in closures
It looks like the mutable locals use case is covered by the with- local-vars binding form. That said, I'm not sure how useful this would be. Even in Java 5, 95% of my local vars are immutable, i.e annotated as final and never have any mutating methods called on them. Most of the rest are simple accumulators: StringBuffers, collections which are filled then used then tossed, or summations. In Clojure these would be replaced by some sort of reduction, requiring no . The only time I could see myself using with-local-vars is in some complex graph-theoretic code, of the sort I write maybe once 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 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: Some code review for clj-record?
That seems to be working better now John. I looked over most of the code and it seems like a good start. I'm no expert when it comes to functional programming or Clojure, so I'm not sure how to critic the code exactly. If I was doing the porting I would prolly do it in very OO way, since that's what I'm used to, and that would not be correct. I noticed that in the init-model macro you are creating a 'defn table [] ...' function in the model namespace and was wondering why you didn't just make it a def instead, since it doesn't take any args? I have an idea for you with the callbacks like, before-create, after-create, etc. In the all-models-metadata in the core.clj you could store the namespace in the hash associated with the model-name on setup. Then in the create function defined in the core.clj you could call the before-create function defined in the model something like: (let-if [bc ('before-create (ns-publics model-namespace)] (bc attributes#)) That was just an idea I had, but there could be a better way to do it that's for sure! Of course it's prolly a bit more complex than that since you the before-create function could alter the attributes#, but you get the idea of discovering and calling the appropriate callback function in the model namespace. On Sun, Dec 28, 2008 at 9:49 PM, John D. Hume duelin.mark...@gmail.comwrote: Ok, please pull the latest and try again. git clone git://github.com/duelinmarkers/clj-record.git The problem was due to something I've seen a couple other messages about: When running a file as a script, it starts out in the clojure.core namespace. I was doing (def db {...}) before any (ns ...) so the db var lived in clojure.core, which made it conveniently (but sloppily) visible everywhere. Loading from the REPL, however, it was landing in the user namespace. I've now put it in a config namespace and required config from the two places that need it. Thanks for looking. -hume. On Sun, Dec 28, 2008 at 11:27 PM, John D. Hume duelin.mark...@gmail.com wrote: The db configuration isn't reasonable at the moment. You can run clj_record/test/main.clj as a script but not load it from the REPL. Let me see if I can get it to work both ways and push an update. On Sun, Dec 28, 2008 at 6:28 PM, Brian Doyle brianpdo...@gmail.com wrote: Having used Rails myself I wanted to check this out and play with it. I'm having some trouble just loading the clj_record/core.clj file though: 1:1 user= (load-file clj_record/core.clj) java.lang.Exception: Unable to resolve symbol: db in this context (core.clj:19) I'm sure it's something I'm doing wrong but I do have derby.jar on my classpath. Thanks. --~--~-~--~~~---~--~~ 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: making code readable
A useful comment addition: How do I run it? Cheers Tom 2008/12/29 Mark Volkmann r.mark.volkm...@gmail.com On Mon, Dec 29, 2008 at 3:58 PM, Chouser chou...@gmail.com wrote: On Mon, Dec 29, 2008 at 4:40 PM, Mark Volkmann r.mark.volkm...@gmail.com wrote: I think that's supposed to be + instead of *, at least Common Lisp seems to use +. I meant * -- I don't know CL at all, but the *asterisk* form is used frequently in clojure.core, while no +plus+ form ever appears. I also was careful to refer to the global nature of the Vars, not anything about const-ness. Ah ... thanks for clarifying that! I've changed my code at http://www.ociweb.com/mark/programming/ClojureSnake.html to follow that convention. -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ 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: Accessing this in gen-class constructor
Thanks for the reply Chouser, Yeah, I figured it would be like that. No this value actually exists until after the init function is called. The reason I'm asking about this is that it's quite standard practice to set up some parameters inside the constructor of a class. ie. A use-case like this is quite common, and (I think) reasonable. public class MyThread extends Thread{ public MyThread(){ setName(This is my thread); } } So whenever the user creates an instance of MyThread, he can be guaranteed that the thread's name has already been appropriately set. How would you do this in Clojure? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to encapsulate local state in closures
On Mon, Dec 29, 2008 at 12:40 PM, Rich Hickey richhic...@gmail.com wrote: People who know what they are doing can do these things right now with Clojure's array support. There really isn't any more value for Clojure to add to that, so no special primitives. I fully accept the necessity of doing that at times, and the correctness of internally mutating, but externally referentially transparent functions, and Clojure has several of them. That's one of the reasons Clojure isn't 'pure'. OTOH it's not a good argument for mutable local vars. What other unsafe things are you looking for? After giving this some more thought, I think the absolutely simplest way to further improve Clojure's mutability support would be to add an atom-set function for the cases where you really want to clobber the contents of atom and don't care what the contents already are. This takes the variable which needs no synchronization thing one step further, allowing for fastest speed in those situations. The semantics would be like this: (defn atom-set [a val] (swap! a (constantly val))) But presumably it could be implemented in the Clojure core in a way that is even faster than the above implementation, since it doesn't need to do the check that the contents haven't changed before setting. I think this is consistent with the idea of atom as a power-user's tool for getting the best possible performance when synchronization is not required. --~--~-~--~~~---~--~~ 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: Accessing this in gen-class constructor
On Mon, Dec 29, 2008 at 8:02 PM, CuppoJava patrickli_2...@hotmail.com wrote: The reason I'm asking about this is that it's quite standard practice to set up some parameters inside the constructor of a class. ie. A use-case like this is quite common, and (I think) reasonable. public class MyThread extends Thread{ public MyThread(){ setName(This is my thread); } } So whenever the user creates an instance of MyThread, he can be guaranteed that the thread's name has already been appropriately set. How would you do this in Clojure? The example I posted does exactly this -- the name of all MyThreads start as my derived class as demonstrated by: user= (.getName x) my derived class --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 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 encapsulate local state in closures
On Mon, Dec 29, 2008 at 2:57 PM, Dave Griffith dave.l.griff...@gmail.com wrote: It looks like the mutable locals use case is covered by the with- local-vars binding form. Not really. with-local-vars has somewhat surprising semantics. For example, you'd expect this (contrived) function to generate an add 2 function: (defn create-add-2 [] (with-local-vars [x 1] (do (var-set x 2) (fn [y] (+ y (var-get x)) But in fact, it just generates a function which errors. If Clojure had some sort of mutable local binding construct, I would expect this to work: (defn create-add-2 [] (mutable [x 1] (do (set! x 2) (fn [y] (+ x y) because you should be able to refer to a mutable local inside of a closure. But any attempt to *set* the local in the closure would generate an error, because you really should be using refs for something like this: (defn create-growing-adder [] (mutable [x 1] (do (set! x 2) (fn [y] (do (set! x (inc x)) (+ x y)) I think if Clojure could do something like this (enforce a certain kind of referentially transparent mutable local), that would be neat, but just extending the interface for atoms with atom-set (as I proposed in my previous post) is probably a perfectly fine and more realistic solution. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
what does - mean?
Hi all, Looking into ants.clj, I came across (defn place [[x y]] (- world (nth x) (nth y))) What - mean here? thanks sun --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Contrib REPL Invocation Changes
Hi, Following today's SVN updates to the Clojure Core and Contrib (as of this writing, at 17:42 PST, which is GMT -8), I can no longer invoke the Contrib REPL as I was able to before today. When I do, I get no prompt until I type a non-empty line, after which I'm presented with an unending repetition of this: java.lang.IllegalArgumentException: Wrong number of args passed to: repl-ln$read-hook My launcher script does this when I request invocation of the Contrib REPL: % java -cp ... clojure.main --init /home/rschulz/.clojure/user.clj -e '(use 'clojure.contrib.repl-ln)' -e '(repl)' So, what is the correct way to invoke the Contrib REPL now? By the way, the stock REPL works as expected. Randall Schulz --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
test-is nesting
;; Note: originally I was just going to write Stuart, but I think input from anybody on the list could be valuable, so I'm CC'ing Clojure Hi Stuart, I've been working on an RSpec-like library for Clojure called Specjure. It has gone through many iterations and the one that is currently up on github is not something I am satisfied with. As I get closer to something I like, it seems that what I will end up with will end up with will look look like where test-is seems to be heading. So, rather than creating duplicate work I'd like to get your opinion on what I have in mind. If you like it, I'd be glad to contribute to test-is rather than creating a duplicate library. This is what I'm thinking, let me explain: http://gist.github.com/41468 (If you are familiar with RSpec, here is the equivalent RSpec example http://rspec.info/examples.html) First off, I renamed deftest to test (note this is a small design choice that I think is a good idea, but wouldn't care too much about.) I tend to write a lot of tests, and having the main keywords for tests be something short is a nice way to encourage writing many tests. The is macro in test-is follows this short name for frequently used form theme (as does def instead of define, and defn instead of define-function in clojure), and I think it's appropriate to do the same for deftest-test. Another change is that the test macro can take a symbol, a string, or both as arguments. This allows for more specification/RSpec/BDD-like tests to be created (I noticed you're experimenting with something similar in clojure-contrib tests, in the form of test-that). Also, if somebody wanted to just do non-specification style tests by using symbols then they are free to do so. There is also a new context. This should be familiar to you if you've ever used RSpec or other BDD libs. It allows for arbitrary nesting of contexts. Inside of a context, you can use test. Any test forms used in a context will inherit its description, prepending it to its own description. Quick aside: If you use a symbol, it's resolved name will be used in the description, ie: ;; the description string here would be my-ns/my-fn run concurrently returns foo (ns my-ns) (context my-fn run concurrently (test returns foo (is (= foo (my -fn :concurrent) You can also use the before and after forms. Any code in these will be captured into functions, and run before running any tests defined in the context. This is useful for things like database fixtures that must clean and repopulate database tables before running tests. The before/after forms are also inherited when nesting contexts. Another two forms are $get and $assoc! $assoc! lets you set key/value pairs to a map that is created for each test, and $get lets you access the map. This is useful for things like setting up values in a before form, and accessing them for testing and cleanup purposes in test and after, respectively, ie: (context create-user with valid attributes (before ($assoc! :user (create-user)) (after (clean-database!)) ... other tests ... (test is valid (is (valid? ($get :user) Somtimes you write small functions that only do one thing in one context. These functions do not really need a a context form. Since test can take a symbol and a string optionally, it can accomodate for such cases. If there are different contexts, but no heavy set up is necessary (something you'd put in before), you may also want to avoid the nesting. For example, you might want to write a test like this:( (ns clojure.core) (test + without arguments returns 0 (is (= 0 (+ (test + with a single argument returns the argument (is (= 3 (+ 3 (test + with multiple arguments returns their sum (is (= 7 (+ 4 2 1 However, you could also avoid some repetition if you like by using context: (context + (test without arguments returns 0 (is (= 0 (+ (test with a single argument returns the argument (is (= 3 (+ 3 (test with multiple arguments returns their sum (is (= 7 (+ 4 2 1) The last things in gist I posted are share-test and use-test. This is basically just for storing functions with (share-test my string [arg] ... stuff ...) and calling them with (use-test my string :some-arg). Because context, test, before, and after are anamorphic, you could put a before form in their and just share that (without putting it in a context first.) This lets you achieve similar functionality to what is referred to as mixins in some languages such as Ruby. Whew, lots of stuff there. I've been going through lots of variations of how I think this kind of context-based testing would work best while retaining the simplicity and flexibility of just using deftest/test and this is where I'm at so far. Let me know what you think. I've basically written the above example in specjure before, so porting it to test-is wouldn't be a problem. Cheers, and thanks for the read! P.S. I just typed this stuff without a
Re: Stumped - Java hangs when using Swing in Slime
What if you run the Swing code in the Event Dispatch Thread? In other words, does this: (. javax.swing.SwingUtilities (invokeAndWait #(. javax.swing.JOptionPane (showMessageDialog nil Hello World or (. javax.swing.SwingUtilities (invokeLater #(. javax.swing.JOptionPane (showMessageDialog nil Hello World work for you? On 20 Dez., 06:06, Daniel Eklund doekl...@gmail.com wrote: 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: 12 Days of Christmas in idiomatic(?) clojure
On Dec 24, 4:20 pm, Mibu mibu.cloj...@gmail.com wrote: I'd write it this way: (apply + (mapcat #(range 1 %) (range 2 14))) I think idiomatically I would have written it with (partial range 1) instead of #(range 1 %), but I prefer compact forms. In Clojure (anybody correct me if I'm wrong) I think it's preferable for performance reasons to use reduce instead of apply when you can. Also, for clarity I think it's much cleaner to have the natural range instead of one that's been pre-mangled to suit (the numbers two and fourteen do not immediately pop in to my head when I think of the Twelve Days of Christmas ;-): (reduce + (mapcat #(range 1 (inc %)) (range 1 (inc 12 With the above usage of range, it's much easier to see the pattern in the solution. Every once in a while I wish for an inclusive- range (irange, perhaps) so I wouldn't need the increment but it's fairly natural to read it as range from 1 INCluding 12. -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 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: Contrib REPL Invocation Changes
On Dec 29, 2008, at 8:49 PM, Randall R Schulz wrote: Following today's SVN updates to the Clojure Core and Contrib (as of this writing, at 17:42 PST, which is GMT -8), I can no longer invoke the Contrib REPL as I was able to before today. When I do, I get no prompt until I type a non-empty line, after which I'm presented with an unending repetition of this: Try clojure-contrib svn 332: http://code.google.com/p/clojure-contrib/source/detail?r=332 --Steve smime.p7s Description: S/MIME cryptographic signature
Re: How to encapsulate local state in closures
I think if Clojure could do something like this (enforce a certain kind of referentially transparent mutable local), that would be neat, It is possible to achieve this behavior explicitly: (defn create-add-2 [] (with-local-vars [x 1] (do (var-set x 2) (let [z @x] (fn [y] (+ y z)) (def myc (create-add-2)) user= (myc 1) 3 user= (myc 2) 4 A bit verbose, but also very clear about what is really mutable and what isn't. --~--~-~--~~~---~--~~ 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: what does - mean?
You can look up the documentation for a function/macro interactively from the repl: user= (doc -) - clojure.core/- ([x form] [x form more]) Macro Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc. nil On Dec 29, 8:27 pm, wubbie sunj...@gmail.com wrote: Hi all, Looking into ants.clj, I came across (defn place [[x y]] (- world (nth x) (nth y))) What - mean here? thanks sun --~--~-~--~~~---~--~~ 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: Fibonacci sequence
Craig, Something you should be aware of is that this implementation of Fibonacci is very inefficient. For more info as to why, you can read: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_1.2.2 The short story is doing it this way performs a lot of wasted calculations as n gets larger: user= (time (fib 40)) Elapsed time: 54768.247 msecs 102334155 If you use this implementation, it uses an iterative process, and is therefore much faster: user= (defn fib [n] (loop [a 1 b 0 count n] (if (zero? count) b (recur (+ a b) a (dec count) #'user/fib user= (fib 9) 34 user= (time (fib 40)) Elapsed time: 0.06 msecs 102334155 On Dec 29, 5:01 am, Craig Marshall cra...@gmail.com wrote: I finally got it working without looking at someone elses code. (defn fib [n] (if (= n 1) ; if 0 or 1 n ; return same, else... (let [n1 (fib (- n 1)) ; calculate n-1 fib n2 (fib (- n 2))] ; and n-2 (+ n1 n2 ; return sum of n-1 and n-2 (println (fib 9)) I had to start with the python equivalent: def fib(n): if n = 1: return n n_1 = fib(n-1) n_2 = fib(n-2) return n_1 + n_2 print fib(9) # Should be 34 and translate to clojure, which hopefully is something I won't have to do forever as I understand clojure more. Thanks, Craig --~--~-~--~~~---~--~~ 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: 12 Days of Christmas in idiomatic(?) clojure
On Mon, Dec 29, 2008 at 9:36 PM, Aaron Brooks aa...@brooks1.net wrote: In Clojure (anybody correct me if I'm wrong) I think it's preferable for performance reasons to use reduce instead of apply when you can. I actually think that's backwards. In many cases it doesn't really matter. It's common to do what + currently does, and that is call reduce internally if given more than 2 arguments. However, it's possible for a function to do something more clever when called via apply, because it controls any looping itself. The 'str' function, for example, uses a single StringBuilder internally when given more than 1 argument, so it's much more efficient to call (apply str foo) than (reduce str foo) for large collections. user= (time (last (reduce str (range 3 Elapsed time: 5570.028441 msecs \9 user= (time (last (apply str (range 3 Elapsed time: 54.140901 msecs \9 --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 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: Exercise: words frequency ranking
(defn top-words-core [s] (reduce #(assoc %1 %2 (inc (%1 %2 0))) {} (re-seq #\w+ (.toLowerCase s maps are functions of their keys means: user= ({:a 1, :b 2, :c 3} :a) 1 Here we created a map {:a 1, :b 2, :c 3}, can then called it like a function with the argument :a and it finds the value associated with that key, which is 1. Maps and keys do this trick by delegating to get, which is a function that looks up stuff: user= (get {:a 1, :b 2} :a) 1 get also accepts an optional third argument, which is returned if key is not found in map: user= (get {:a 1, :b 2} :e 0) 0 But as we saw you don't need to call get, you can just call the map: user= ({:a 1, :b 2, :c 3} :e 0) 0 Keys can be called in the same way (reverse of what we did above): user= (:e {:a 1, :b 2} 99) 99 assoc stores a value in a map associated with a key: user= (assoc {:a 1, :b 2} :b 3) {:a 1, :b 3} So this: #(assoc %1 %2 (inc (%1 %2 0))) Could be written as: (defn map-count [map key] (assoc map key (inc (get map key 0 ie: Given a map and a key, find the value associated with key in map, or 0 if not in the map, and increment it. Return a map that has the key associated with this value. (re-seq #\w+ (.toLowerCase s)) turns the input string to lowercase then applys a regular expression to split it into a sequence of words. Which leaves us with: (reduce map-count {} sequence-of-words) {} empty map is supplied as the initial map and a whole sequence of keys (words) are fed in. reduce essentially does this: (map-count (map-count {} first-word) second-word) etc etc for every word ie: the result is used as input. Regards, Tim. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: what does - mean?
Very criptic for newbie. What does Threads the expr through the forms. mean? Does it create a thread to execute? thanks sun On Dec 29, 10:07 pm, Paul Barry pauljbar...@gmail.com wrote: You can look up the documentation for a function/macro interactively from the repl: user= (doc -) - clojure.core/- ([x form] [x form more]) Macro Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc. nil On Dec 29, 8:27 pm, wubbie sunj...@gmail.com wrote: Hi all, Looking into ants.clj, I came across (defn place [[x y]] (- world (nth x) (nth y))) What - mean here? thanks sun --~--~-~--~~~---~--~~ 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: [jvm-l] Kawa Scheme on Android
Rich Hickey wrote: On Sun, Dec 28, 2008 at 6:05 PM, Randall R Schulz rsch...@sonic.net wrote: Howdy, Folks, The gauntlet has been thrown down: I've made changes in svn 1186 and 1188 that should help facilitate targeting Android/Dalvik. clojure.jar now translates with dx --dex, but that is all I've had time to look at. If people have time to try it, I'll follow up on any issues that arise. Rich It's getting closer :) I've added Issue 25 that includes a small patch which allows dalvikvm to find the core clojure classes (was throwing a ClassNotFoundException for clojure.core__init). As mentioned in the issue report, it now crashes with a VerifyError on StringBuilder.append() - which you mentioned you're going to look into soon. Cheers, Adam --~--~-~--~~~---~--~~ 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: Contrib REPL Invocation Changes
On Monday 29 December 2008 18:36, Stephen C. Gilardi wrote: On Dec 29, 2008, at 8:49 PM, Randall R Schulz wrote: Following today's SVN updates to the Clojure Core and Contrib (as of this writing, at 17:42 PST, which is GMT -8), I can no longer invoke the Contrib REPL as I was able to before today. When I do, I get no prompt until I type a non-empty line, after which I'm presented with an unending repetition of this: Try clojure-contrib svn 332: http://code.google.com/p/clojure-contrib/source/detail?r=332 Now I'm dumped back to my shell prompt following a single Clojure REPL prompt (of the Contrib REPL variety) without even touching the keyboard: % clojure-svn --crepl +cp=$PROJ_SRC/tau/run +cp=/dar/clojure 1:1 user= % --Steve Randall Schulz --~--~-~--~~~---~--~~ 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: what does - mean?
On Dec 30, 2:49 pm, wubbie sunj...@gmail.com wrote: Very criptic for newbie. What does Threads the expr through the forms. mean? Shameless plug, if you find learning from examples easier than textual descriptions, you might want to look up http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples I'm trying to fully cover the entire API with snippets and examples as I come across them... its pretty well fleshed out now, but still some gaps to fill In this case the entry is: - user= (- hello .toUpperCase (.replace H J)) JELLO However - works on everything user= (- true (if inc dec) (map [1 2 3])) (2 3 4) or expanded (map (if true inc dec) [1 2 3]) So one can also use macros and normal functions in -, ie. non- methods. In this case - is pretty difficult to get your head around in either example or textual though, so YMMV :) --~--~-~--~~~---~--~~ 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: Kawa Scheme on Android
thanks for sharing. looking forward to the day when i can write my android app in clojure! On Dec 30, 12:07 pm, Adam King va3...@gmail.com wrote: Rich Hickey wrote: On Sun, Dec 28, 2008 at 6:05 PM, Randall R Schulz rsch...@sonic.net wrote: Howdy, Folks, The gauntlet has been thrown down: I've made changes in svn 1186 and 1188 that should help facilitate targeting Android/Dalvik. clojure.jar now translates with dx --dex, but that is all I've had time to look at. If people have time to try it, I'll follow up on any issues that arise. Rich It's getting closer :) I've added Issue 25 that includes a small patch which allows dalvikvm to find the core clojure classes (was throwing a ClassNotFoundException for clojure.core__init). As mentioned in the issue report, it now crashes with a VerifyError on StringBuilder.append() - which you mentioned you're going to look into soon. Cheers, Adam --~--~-~--~~~---~--~~ 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: Contrib REPL Invocation Changes
Now I'm dumped back to my shell prompt following a single Clojure REPL prompt (of the Contrib REPL variety) without even touching the keyboard: % clojure-svn --crepl +cp=$PROJ_SRC/tau/run +cp=/dar/clojure 1:1 user= % Here it is working with the current clojure.jar and clojure-contrib.jar: % java -cp clojure.jar:clojure-contrib.jar clojure.contrib.repl_ln Clojure 1:1 user= (prn hi) hi nil 1:2 user= As for the syntax for clojure.repl_ln loading init files, it's -i or --init like clojure.main. -e and --eval are not currently supported nor is -r or --repl. Any arg that isn't introduced by -i or --init marks the beginning of the command-line-args: java -cp clojure.jar:clojure-contrib.jar clojure.contrib.repl_ln -i init.clj a b c Clojure loading init.clj 1:1 user= *command-line-args* (a b c) 1:2 user= (in this case init.clj contained (prn loading init.clj) --Steve smime.p7s Description: S/MIME cryptographic signature
Re: Some code review for clj-record?
On Mon, Dec 29, 2008 at 7:15 PM, Brian Doyle brianpdo...@gmail.com wrote: I noticed that in the init-model macro you are creating a 'defn table [] ...' function in the model namespace and was wondering why you didn't just make it a def instead, since it doesn't take any args? That didn't occur to me. I do like the idea of all the functionality being available directly on clj-record.core with model name as a first argument in addition to being defined in the model namespace, so I guess that's one reason. But the inference of table name from model name should only be the default, so maybe it would be better to just def it there and let clj-record.core look it up there if needed, somewhat as you recommended doing for callbacks... I have an idea for you with the callbacks like, before-create, after-create, etc. In the all-models-metadata in the core.clj you could store the namespace in the hash associated with the model-name on setup. Then in the create function defined in the core.clj you could call the before-create function defined in the model something like: (let-if [bc ('before-create (ns-publics model-namespace)] (bc attributes#)) That's interesting. It's basically the opposite of the way I did the validation stuff, where you pass in validation functions and those get stored away in metadata and aren't directly accessible. (Here metadata is not used in the clojure.org/metadata sense of the word. I've thought about using clojure metadata to store model info, but I don't know what symbol or collection I'd attach it to.) I think I prefer the validation approach, because those functions have a certain job to do and shouldn't be sitting there cluttering the model namespace. (On the other hand, it is awfully convenient to be able to test those functions directly.) Thanks again for looking. If you or anyone else has further comments, I'd like to hear them. git clone git://github.com/duelinmarkers/clj-record.git -hume. -- http://elhumidor.blogspot.com/ --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Swank in Tomcat via JSP: classpath issues
Thanks, Mike - although we had already looked at the context classloader, your explanation did provide some inspiration for a workaround. The correct classloader should be available in the JSP and so it should be possible to grab it there and pass it into Clojure as a variable (or a binding?) in the same section of the code that launches Swank. I've been hacking on this approach some tonight, although I'm not able to get an external JSP-sourced variable recognized within my slime repl (probably I'm doing something stupid here), but I'll keep poking at it as I have time. -Greg --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Parallel words frequency ranking
On Dec 28, 7:50 pm, Piotr 'Qertoip' Włodarek qert...@gmail.com wrote: Following my recent adventure with words ranking, here's the parallel version: ... (defn parallel-top-words [in-filepath out-filepath] (let [string (slurp in-filepath) 'slurp' just reads the whole file in at once as a string, right? You could be bottlenecking on the file access and read. Can you wrap this step only with a timer and see how long it takes? mfh --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Understanding how to use namespaces
So up until now, I've mainly been writing my code in a given file, using no namespaces, and then just compiling and executing it in a SLIME-based REPL. I've accumulated a few functions that seem worth making into a little library. So, for example, I've written a few permutation functions. I put these functions in a file called permutations.clj. I assume that to properly get reuse of this library, I need to put in a separate namespace (or is this not really necessary?). So, at the top of the file, I add: (ns permutations) Now, when I compile the permutations.clj file in emacs, the REPL can't use the defined functions unless I prefix them with the namespace: (permutations/permutations [1 2 3]) It's a bit of a pain that by making a namespace, I've created more work for myself in terms of using these functions in the REPL. Is there a way to make the REPL automatically see these functions? Next, I want to test whether I can use this library from another file (in the same directory). So I create a testperms.clj file. (ns testperms (:use permutations)) This doesn't work at all, so I must have the syntax wrong. So can someone elaborate, or point me towards a tutorial that explains how to use namespaces to partition your program into files which can use functions from other files in the same directory? Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: In core structure editor, anyone?
How's textjure coming along? On Dec 10, 3:35 pm, Chouser chou...@gmail.com wrote: On Wed, Dec 10, 2008 at 7:15 AM, Simon Brooke still...@googlemail.com wrote: I note people seem mainly to be using Emacs as an editing/development environment for Clojure. But as people keep pointing out, Clojure is homoiconic; the canonical source of a function is not a stream of bytes read from a file, but is a structure in core. Now, in-core editing does raise some issues - there needs to be some means of associating the structure which is the canonical source of a function with the function itself There is sufficient information provided in most Var metadata to get the source code where the Var defined (assuming the source code is available in the classpath). I'm working on (or perhaps more accurately, poking at) a small program to leverage Swing to provide an environment for editing Clojure and interacting with a running REPL. It's by no means emacs or even vim yet, but it will have no dependencies beyond what Clojure requires and may provide a sufficiently comfortable environment for spot-editing. It will also attempt to be an acceptable starting place for people wanting to play with Clojure who aren't too deeply committed to emacs or vim. It already has an 'open' function to pull up the source of a function in the edit pane. I'm not ready to provide a link yet, but go ahead and ask me in a few weeks how textjure is coming along. --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 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 -~--~~~~--~~--~--~---