Re: rules for writing macros
Does this clarify the point I was making? When writing macros, you cannot dynamically build one of the syntactic sugar forms. For example, you cannot write a macro that expands cls and member into (cls/member): (defmacro call-static [cls member] `(~cls/~member)) - java.lang.Exception: Invalid token: cls Instead, you should build normal, unsugared forms: (defmacro call-static [cls member] `(. ~cls ~member)) - nil On Tue, Feb 3, 2009 at 11:26 AM, Mark Volkmann r.mark.volkm...@gmail.com wrote: Now I remember what I was thinking about. This isn't so much a difference between macros and functions as it is a rule about something you cannot do in a macro. Quoting from Programming Clojure ... You cannot write a macro that expands to any of the syntactic sugar forms ... For example, you cannot write a macro that expands to (Math/PI). Hm... (defmacro pi [] 'Math/PI) == #'user/pi (macroexpand '(pi)) == Math/PI (pi) == 3.141592653589793 (defmacro strlen [s] `(.length ~s)) == #'user/strlen (strlen hello) == 5 (defmacro mydoc [s] `(:doc ^#'~s)) == #'user/mydoc (macroexpand '(mydoc doc)) == (:doc (clojure.core/meta (var doc))) (mydoc doc) == Prints documentation for a var or special form given its name That's a whole lot of sugar that all seems to work ok. Is there some other syntactic sugar form that does not work? Perhaps he's referring to actually producing reader macro usages, like this: (defmacro mydoc2 [s] `(:doc ~(symbol (str ^#' s == #'user/ mydoc2 (macroexpand '(mydoc2 doc)) == (:doc ^#'doc) (mydoc2 doc) == java.lang.Exception: Unable to resolve symbol: ^#'doc --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: Fully lazy sequences are coming - feedback wanted!
I prefer first/rest/next. Because of where the book is in the production cycle, it will be difficult for me to change the prose. But if this gets decided (and clojure-contrib updated) in the next week or two I think I can get the book printed with the changes incorporated throughout. Cheers, Stu I'm pretty much finished with the fully-lazy implementation and am happy so far with the results. I think this will be an important addition to Clojure and am planning to add it. Now comes the hard part - names and change. The essence of the fully lazy seqs is that they will not consume any resources, perform any computation or trigger any side effects until they are consumed. This is a change to the way the sequence functions work now, in that, in order to determine whether they should return a seq or nil, they need to touch at least one item. So, there will be an additional function on seqs, one that returns the items other than the first as a logical, non-nil, possibly empty collection. Calling seq on this collection will give you what rest currently gives you - the next seq object or nil if none. So the core operations on seqs will be: ;item (first x) ;collection of remaining items, possibly empty (possibly-empty-collection-of-the-remaining-items x) ;seq on next item, or nil if none (seq-on-the-next-item-if-any-else-nil x) (first x) is uncontroversial and won't change. The second is a new function. The third is currently called 'rest'. I have some ideas for names, and there are definitely tradeoffs between short-term pain and long-term goodness in some of the options. The first option is to leave rest alone, and give the new function a new name, like more. ;item (first x) ;collection of remaining items, possibly empty (more x) ;seq on next item, or nil if none (rest x) Note that (rest x) === (seq (more x)) This is implemented in the lazy branch, SVN rev 1281. It has the attribute of requiring the fewest changes to existing code, and the drawback of leaving us with less-than-ideal names, especially insofar as more (or whatever you choose to call it) will in some way seem synonymous with rest. This naming scheme, and the changes it implies, is documented here: http://clojure.org/lazier1 The second option is to choose the best possible names, and deal with some short term pain in porting and confusion. I think the best names are: ;item (first x) ;collection of remaining items, possibly empty (rest x) ;seq on next item, or nil if none (next x) This is implemented in the lazy branch, SVN rev 1282. Note that this changes the meaning of rest, and gives the current rest operation a new name, next. It has the attributes of using the most appropriate names (IMO) and the drawback of changing the semantics of a frequently used function name, but still offering that functionality under a different name. It would also break the compatibility of rest with Common Lisp's. As with the previous model, the third function can be defined in terms of the second - (next x) === (seq (rest x)). This naming scheme, and the changes it implies, is documented here: http://clojure.org/lazier A third option would be to retire rest and use only new names: ;item (first x) ;collection of remaining items, possibly empty (more x) ;seq on next item, or nil if none (next x) I haven't implemented this. I prefer first/rest/next. I think rest is the best complement to first, and it should mean the logical collection once things are fully lazy. I think next implies the next seq, as well as the eager nature of the operation. I am looking for feedback from people willing to read and understand the linked-to documentation and the fully lazy model, and especially from those trying the lazy branch code and porting some of your own. Questions on the model welcome as well. Chouser has also blogged a bit about this, with some useful descriptions of nil punning: http://blog.n01se.net/?p=39 I've been working on this for a few months, in lieu of more interesting things, because I knew it would be a breaking change and we're trying to get the biggest of those behind us. I appreciate any effort you spend in trying to provide informed input. 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: Fully lazy sequences are coming - feedback wanted!
Thanks Rich! :-) , 2009, at 11:25 AM, David Nolen wrote: butlast, doall, dorun, doseq, dosync, dotimes, doto, fnseq, gensym, macroexpand, macroexpand-1, mapcat, nthrest -1 Because they are similar to other Lisps I assume. The same reason for println vs print-line. Changing these are a bad idea in IMHO. Breaking the meaning of rest with Common Lisp is a consideration to take seriously. However as long as the documentation clearly states (highlights in big bold colors ;) this difference (and the fact the operation is support by next) then I think this is a change people can live with. Changing these names is not on the table. 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: Fully lazy sequences are coming - feedback wanted!
I agree with Walt, and there is no need to pressure the Prags, we are on it! :-) That said, it would be *very* helpful to me if we could get the lazyness thing settled this week... Stuart Regarding Programming Clojure: I think that placing the burden of book vs actual incompatibility upon Rich is misplaced. If anything, pressure from the Clojure community should be placed on the Pragmatic Programmers to allow Stuart to do the right thing regarding when the book is released, viz., when Clojure has stabilized. Realize who is making the open contribution and who is profiting from that contribution and keep the priorities straight. My 2 cents. Walt --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
terminology question re: binding
David Sletten sent me this erratum: At the beginning of section 2.4 we have The symbol user/foo refers to a var which is bound to the value 10. Under the next subsection Bindings we have Vars are bound to names, but there are other kinds of bindings as well. The Common Lisp standard defines a binding as an association between a name and that which the name denotes. This is the second sense used in the book. The first sense of a binding between a var and its value is inconsistent. Should I be using two different terms, or is the notion of binding overloaded? Stuart --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: how to learn clojure ?
Thanks for the kind words, David. I hope many people will like Programming Clojure and find it useful. Clojure has a *ton* of goodness in it. I think many of the chapters in Programming Clojure book could usefully be followed with an entire book. Here is a partial list of recommendations for companion reading: For Java Interop: * The JVM spec (free online). Know your platform. :-) For Functional Programming: * Real World Haskell (free online) For Concurrency: * Java Concurrency in Practice For Macros: * On Lisp (free online) For Lisp in General: * Practical Common Lisp (free online) * Paradigms of AI Programming For Multimethods: * The Art of the Metaobject Protocol Just Because: * Structure and Interpretation of Computer Programs Cheers, Stuart Of course I beg to differ. The Stuart Halloway's book is fantastic of course, I have it myself. It's absolutely required reading. Stuart does his best to describe the ins and outs of the language while giving a crash course on the Lisp philosophy. And yes Clojure is syntactically different from Scheme and Common Lisp, however many of the non-Clojure texts suggested do a better job explaining the deeper why's of Lisp programming, concepts that go beyond the particular implementation. In fact I would probably recommend the Structure and Interpretation of Computer Programs as the indispensable Lisp text above all others. But thats just MHO. David On Thu, Feb 19, 2009 at 8:46 AM, Rayne disciplera...@gmail.com wrote: Telling someone to read a book that isn't even focused on the language he's trying to learn isn't a great way to help them. Tell him to read Programming Clojure or something, anything but Common Lisp and Scheme books, he isn't learning those languages he's learning Clojure. There is enough information around on Clojure that someone shouldn't be forced to read a book on a completely different language. No offense guys. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
better syntax highlighting for Clojure
I have improved the clojure.js bits [1]. Various small changes, but the big issue was to discontinue using \b for end of word, which does not work well with names-like-this. Feedback or additional improvements welcome. Stuart [1] http://github.com/stuarthalloway/programming-clojure/blob/95d9943dfb54112912714a2d741a34749bca3be2/public/javascripts/clojure.js --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
challenge: best fibo implementation under the new laziness?
I have updated the sample source from the book (http://tinyurl.com/clojure-samples ) to the new laziness. Along the way, I replaced the lazy-cons based implementation of the fibonacci numbers with this: (defn fibo ([] (concat [0 1] (fibo 0 1))) ([a b] (let [n (+ a b)] (lazy-seq (cons n (fibo b n)) Is there a better/more idiomatic approach, without resorting to code in clojure-contrib? Test your code against the following expression to flush out stack and heap overflows. (rem (nth (fibo) 100) 1000) - 875 Also, the current 'fibs' implementation in clojure.contrib.seq fails the test above, because it holds the entire sequence as it goes. We should replace it with whatever the community comes up with on this thread. Cheers, Stu --~--~-~--~~~---~--~~ 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: better syntax highlighting for Clojure
Laurent, I originally grabbed the js and css from the Google groups files. I haven't changed the colors--I merely adapted the js to do a better job of identifying clojure names. The js and css should work on any website, which is why I thought this might be of general interest. Stuart Hello Stuart, Can you explain what this is ? Is it just something related to your book, or something that also colors syntax on websites (maybe the clojure website, or github ..) ? Indeed, if these are the commonly accepted colors for clojure code, I'll consider adapt clojure-dev to stick with this coloring scheme. Thanks in advance, -- Laurent 2009/2/23 Stuart Halloway stuart.hallo...@gmail.com I have improved the clojure.js bits [1]. Various small changes, but the big issue was to discontinue using \b for end of word, which does not work well with names-like-this. Feedback or additional improvements welcome. Stuart [1] http://github.com/stuarthalloway/programming-clojure/blob/95d9943dfb54112912714a2d741a34749bca3be2/public/javascripts/clojure.js --~--~-~--~~~---~--~~ 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: challenge: best fibo implementation under the new laziness?
Beautiful-thanks. Using a good old sequence of vectors: (defn fibo [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1]))) Christophe Stuart Halloway a écrit : I have updated the sample source from the book (http://tinyurl.com/clojure-samples ) to the new laziness. Along the way, I replaced the lazy-cons based implementation of the fibonacci numbers with this: (defn fibo ([] (concat [0 1] (fibo 0 1))) ([a b] (let [n (+ a b)] (lazy-seq (cons n (fibo b n)) Is there a better/more idiomatic approach, without resorting to code in clojure-contrib? Test your code against the following expression to flush out stack and heap overflows. (rem (nth (fibo) 100) 1000) - 875 Also, the current 'fibs' implementation in clojure.contrib.seq fails the test above, because it holds the entire sequence as it goes. We should replace it with whatever the community comes up with on this thread. Cheers, Stu -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~-~--~~~---~--~~ 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: retrieving argument :tag metadata
Cool, thanks. On Tue, Feb 24, 2009 at 11:59 AM, Stuart Halloway stuart.hallo...@gmail.com wrote: Is there a way to programmatically retrieve the :tag of an argument? The var metadata will return the tag of a return value... The :arglists metadata attached to the Var by defn appear to keep the metadata given in the defn form: user= (binding [*print-meta* true] (prn (:arglists ^#'future-call))) ([#^Callable f]) --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 -~--~~~~--~~--~--~---
new laziness: terminology help
I am wrestling the sequences chapter of the book into conformance with the new laziness, and I am finding it tricky to infer accurate definitions of the words sequence, seq (noun), seq (function), and ISeq from the variety of extant documentation, code, email chats, and IRC logs. I would appreciate comments and corrections to the following statements. (1) The book currently claims that sequence and seq are synonyms. This is consistent with http://clojure.org/sequences, but not with recent threads here. Is it more accurate to say that a sequence is a seq-able collection? (2) Is it correct to say that seq (noun) and ISeq are synonyms? I take this from http://clojure.org/lazy: seqs can be empty * always an ISeq Thanks, Stu --~--~-~--~~~---~--~~ 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: new laziness: terminology help
I like this, and I am OK with seq (function) being the oddball that returns a seq or nil. Rich, this is what Beta 8 of the book currently says -- ok with you? Stuart I believe that one of Rich's stated purposes with the latest revision of the laziness branch was to get rid of some of the subtle differences between these terms after all the discussions about this. I think that with the new changes the intent is: seq (noun) = sequence = ISeq, i.e., anything you might get back from rest. This is a bit counterintuitive, however, because you might expect that the noun seq should mean anything you can get back from the seq function (i.e., a nonempty ISeq or nil). However, the behavior of the seq? predicate implies that the noun seq is intended to be a synonym for ISeq. I tend to use the term seq-able to mean anything you can pass to the seq function without error. Anyway, that's my impression... --~--~-~--~~~---~--~~ 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: new laziness: terminology help
All sequences are represented by (chains of) (possibly lazy) seqs, of type ISeq. So yes, sequence/seq(noun)/ISeq are technically synonyms, but [1] Great. [1] In practice, a sequence fn (like map et al) may return an empty sequence, while seq/next will instead return a (forced) thing with a first, or nil, and I'd use the terms sequence for the former and seq for the latter. I believe it would be simpler to leave out this footnote. In my perfect world, seq/ISeq/sequence are synonyms, and nillability is a property only of *functions*: seq and next. I realize that this breaks with past usage. Rich, I will treat your next reply as a final ruling for the book. :-) Stu --~--~-~--~~~---~--~~ 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: class of java array
Hi Adrian, Here is one way: (- (into-array [one two]) (class) (.getComponentType)) - java.lang.String (- (to-array [one two]) (class) (.getComponentType)) - java.lang.Object Stu I have a java object that either contains a String or an array of Strings. (instance? java.lang.String obj... works fine for the String, but how would I check for the String Array? Thanks, Adrian. --~--~-~--~~~---~--~~ 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: New release 20090320
I am updating some of the examples in the FP chapter to use letfn, and the book is already up-to-date on fully lazy seqs. Any other new features jump out as must discuss in book? Stu New release 20090320 - http://clojure.googlecode.com/files/clojure_20090320.zip Incorporates all the recent additions - fully lazy seqs, :let option for doseq/for, letfn for mutually recursive local fns, synchronous watches, multi-arg set/union/difference/intersection, counted?, per- defmulti hierarchies, #_ ignore form reader macro, future-calls, future and pcalls/pvalues, defmulti docstrings and metadata, methods/ prefers for multimethod reflection, uniform metadata handling for atoms/refs/agents/vars/namespaces, condp, release-pending-sends, AOT tweaks to support applets and Android, etc. All this in addition to many fixes and enhancements. The API docs page is now current - changes to the rest of the site will come soon. This release includes many patches from contributors, and input and reports from many users - thanks all! 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: Clojure + Java compilation and IntelliJ IDEA plugin
Hi Ilya, I would like to be able to demo the sample code from the book in IDEA. Here are a few things I am seeing so far: (1) When I set a breakpoint, I get a warning icon that says no executable code found at... but the breakpoint does in fact seem to work. (2) The variable window correctly displays collections, but not large/ infinite sequences. If you try to open a variable view on an infinite sequence, it will use all of memory. Can the plugin be modified to respect the *print-length* and *print-depth* variables? (3) I am unable to set a watch on the special variable *print-length*. The entry UI goes wonky when I reach the hyphen character in the name. It's exciting to see the plugin moving forward, thanks for your efforts! Best, Stu Hello, all. I've just uploaded new version of La Clojure plugin for IntelliJ IDEA. Among several bugfixes and minor changes I have to note several essential moments. 1. Now Clojure support is added as so-called `facet', which may be attached to every module. Creating new module, just choose Clojure among desired technologies. In this case necessary clojure jar will be downloaded automatically and adjusted as a project library unless you point to it manually. 2. If you open existing project, clojure facet will be detected automatically. For now facet serves as a label for clojure-aware modules. In that modules you may invoke create new clojure file action and their clojure files will be compiled. 3. From now IntelliJ IDEA provides support for batch compilation of Clojure files, whose namespace is marked by :gen-calss tag. Compiled classes will be places to the appropriate output directory of a module. One may choose, which sources should be compiled first - Java or Clojure to resolve one-way dependencies. By default Clojure is compiled first. Moreoverm you may to choose whether to copy *.clj files to output path or not (this might be useful if you're going to invoke some functions from *.clj files dynamically). And, of course, automatic detection and compilation of class-labeled clojure files may be switched off. For more details see File - Settings - Compiler - Clojure. For someone these settings might seem not sufficiently flexible. So, all comments and proposals are appreciated. :) With best regards, Ilya Sergey --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Book erratum (was: Clojure + Java compilation and IntelliJ IDEA plugin)
Ilya, I have checked in a unit test for the tasklist example that demonstrates it working correctly locally. Can you try it and see what's different for you? Git repos: http://github.com/stuarthalloway/programming-clojure/tree/master Then bin/runtests.sh or bin\runtests.bat depending on your platform. The individual test is examples/test/tasklist.clj. Thanks, Stu Hi, Stuart. I would like to be able to demo the sample code from the book in IDEA That's great, I'm really happy to hear it. As for all three issues you've mentioned, all of them have same origin and related to so-called evaluator API. What you can see now using debugger is nothing but vanilla Java stack, some of whose variable may coincide with appropriate Clojure variables. Implmentation of watches, evaluate expression or some specific cases like dealing with lazy structures is _very_ non-trivial problem, cause all clojure constructs, written, say, in 'watches' section should be translated to correct Java code to capture appropriate stack and environment from JVM and being evaluated. For now, we solved this problem partially for Groovy, because Groovy is not so hard to translate to Java and we're working on the same problem for Scala, which is much more dificult because of presence of string typeing. As for Clojure, I don't see an easy way for now to implement such feature. For me such tasks as smart completion and resolve have greater priority. BTW, I'm not sure, that thiss issue was already mentioned in errata for book, but I failed to compile tasklist.clj example from last book version (27 feb), because some function (sort of `lazy-eval') from clojure-contrib raised an error during compilation. Same result was obtained by compilation from command line, so I'm afraid some- thing wrong either with current clojure-contrib version or this example. Kind regards, Ilya 2009/3/25 Stuart Halloway stuart.hallo...@gmail.com Hi Ilya, I would like to be able to demo the sample code from the book in IDEA. Here are a few things I am seeing so far: (1) When I set a breakpoint, I get a warning icon that says no executable code found at... but the breakpoint does in fact seem to work. (2) The variable window correctly displays collections, but not large/ infinite sequences. If you try to open a variable view on an infinite sequence, it will use all of memory. Can the plugin be modified to respect the *print-length* and *print-depth* variables? (3) I am unable to set a watch on the special variable *print-length*. The entry UI goes wonky when I reach the hyphen character in the name. It's exciting to see the plugin moving forward, thanks for your efforts! Best, Stu Hello, all. I've just uploaded new version of La Clojure plugin for IntelliJ IDEA. Among several bugfixes and minor changes I have to note several essential moments. 1. Now Clojure support is added as so-called `facet', which may be attached to every module. Creating new module, just choose Clojure among desired technologies. In this case necessary clojure jar will be downloaded automatically and adjusted as a project library unless you point to it manually. 2. If you open existing project, clojure facet will be detected automatically. For now facet serves as a label for clojure-aware modules. In that modules you may invoke create new clojure file action and their clojure files will be compiled. 3. From now IntelliJ IDEA provides support for batch compilation of Clojure files, whose namespace is marked by :gen-calss tag. Compiled classes will be places to the appropriate output directory of a module. One may choose, which sources should be compiled first - Java or Clojure to resolve one-way dependencies. By default Clojure is compiled first. Moreoverm you may to choose whether to copy *.clj files to output path or not (this might be useful if you're going to invoke some functions from *.clj files dynamically). And, of course, automatic detection and compilation of class-labeled clojure files may be switched off. For more details see File - Settings - Compiler - Clojure. For someone these settings might seem not sufficiently flexible. So, all comments and proposals are appreciated. :) With best regards, Ilya Sergey --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
questions about clojure.contrib.error-kit
(1) Is there any reasonable way to attach handlers to lazy sequences such that the handlers will still be in place outside the original handler scope, when the sequence is finally evaluated? (It is not obvious to me how to do this without making the handler system part of the language core.) (2) When using continue-with while mapping a sequence, I find myself wanting to simply ignore error conditions (instead of having continue- with contribute nil or some error token to the sequence which I then have to filter out). What is the most idiomatic way to do this? Thanks, Stu --~--~-~--~~~---~--~~ 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: Quick slime/emacs questions
describe-key (usually C-h k) followed by a key will tell you what a key is currently bound to. On my setup C-x C-b is bound to ido-switch-buffer--it is not immediately obvious how to make it pop the buffer list in the current window. You might find What You Can Learn From ido.el (http://www.vimeo.com/1013263 ) interesting. (Note the correction from Ed Singleton in the comments, too.) Stu When I have two windows open, and hit C-x-C-b, it pops up a list of buffers in the OTHER window from where the current focus is. Any idea why it's doing that, and how I can alter the behavior so it pops up the list of buffers in the current window? Also, where can I look up the names of various commands to rebind to different keys? For example, I want to remap C-s to do what C-x-C-s currently does, and I wan to remap C-f to do what C-s currently does, to make behavior more consistent with other programs I use. (After using emacs for a while, I inevitably find myself hitting C-x-C-s to save in other programs :) ) 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: Java interoperability and Clojure
Hi Geoff, You should have no trouble using setAccessible. There are several demos of this in the source code for the book [1] that use setAccessible to check private fields in a unit test. (See lancet/test/ step-2-complete.clj [2], for instance). Hope this helps, Stu [1] http://github.com/stuarthalloway/programming-clojure/tree/master [2] http://github.com/stuarthalloway/programming-clojure/blob/401f348b53ddf8ba9b90a445981a134c5eb20783/lancet/test/step_2_complete.clj What are the limitations of Clojure and Java interoperability? Are they clearly stated somewhere? I have been experimenting with using Clojure to test some existing Java code (being able to do so makes a convincing argument to use it where I work) and I've noticed that there doesn't seem to be any way to call or access package-protected methods or fields -- either that or I'm doing something wrong. :) I've also been trying use the java.lang.reflect capabilities (such as setAccessible() in java.lang.reflect.AccessbileObject) and noticed that they do not have an effect. How much can be done using those libraries within Clojure to affect Java code? Any information provided would be most helpful. Being able to use Clojure to write tests for existing Java code (that extensively employs package-protected methods and fields) would be a nice way to demonstrate Clojure's capabilities to some people I work with. --~--~-~--~~~---~--~~ 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: Every function is a thread in Clojure?
No threads: (ancestors (class (fn[]))) - #{java.lang.Runnable java.io.Serializable clojure.lang.AFn clojure.lang.Obj java.lang.Object clojure.lang.Fn clojure.lang.AFunction clojure.lang.IObj clojure.lang.IFn java.util.concurrent.Callable clojure.lang.IMeta java.util.Comparator} What you are referring to is the fact that functions implement Callable and Runnable, so that they can trivially play nice with Java threads if you need them to. Stu Someone correct me if I go wrong here. But, from my understanding, every defined function in Clojure is an implementation of a thread? What is the goal in implementing in this fashion? For example, if I am writing in imperative style: (println First line) (println Second line) (println Third line) ... The operations have to occur synchronously. What does adding Java threading add to the mix? --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
proposed new contrib: java-utils
Hi all, I would like to pull together functions that help with Java interop and place them in a new contrib: java-utils. Some examples: (1) Pull out SteveG's properties fn, currently hidden in the internals of clojure.contrib.sql (2) reflective helpers for accessing private and protected values (3) coercions for Java's irritating types: File/String, URL/String, IPAddress/String, etc. (4) Maybe some of the utils currently hiding in Compojure (James, would that be cool with you? Have you signed/would you sign the contributor agreement?) If this is interesting to others (or at least inoffensive) I will move forward with it. Are there other little nuggets of Java-interop code that I should also consider? Cheers, Stu --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
DISCUSS: clojure.contrib.java-utils/file
Never worry about foo vs. (File. foo) again! (doc file) - clojure.contrib.java-utils/file ([arg] [parent child] [parent child more]) Returns a java.io.File from string or file args. Notes: (1) You will need to build contrib from source to see this. (2) This function is a slight generalization of a similar function in Compojure. James, I am hoping to convince you to make Compojure depend on contrib and start using a standard set of utils. What do you think? --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
DISCUSS: clojure.contrib.java-utils/the-str
Never worry about the distinction between symbols, keywords, and strings when working with Java APIs that know only strings! (doc the-str) - clojure.contrib.java-utils/the-str ([x]) Returns the name or string representation of x Notes: (1) You will need to build contrib from source to see this. (2) This function is moved from Steve Gilardi's sql.internal contrib. (Steve, I broke sql in r636 but I think I fixed it now. Are there tests I can run?) (3) I believe that the-str in miglayout can also be eliminated in favor of this standard version. Steve, do you agree? Questions: (1) I kept the original name the-str but would prefer as-str. Community, what say ye? --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
DISCUSS: clojure.contrib.java-utils/with-system-properties
Don't work with the yucky properties API, just install a map of properties for the duration of a block! - clojure.contrib.java-utils/with-system-properties ([settings body]) Macro setting = property-name value Sets the system properties to the supplied values, executes the body, and sets the properties back to their original values. Values of nil are translated to a clearing of the property. - CREDITS: This function is a refactoring of Shawn Hoover's with-properties. Shawn, if my changes offend in any way let me know and I will fix it. NOTES: (1) You will need to build contrib from source to see this. (2) Name changed from with-properties to with-system-properties (3) Expected argument is now a map, not a vector, which I believe is more logical and convenient for callers. (4) Uses the-str so that property keys can be Clojure keywords or symbols. --~--~-~--~~~---~--~~ 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: DISCUSS: clojure.contrib.java-utils/the-str
I noticed the indentation changed for the ns form with your changes to sql.clj sql/internal.clj . Is the indentation you used produced by some tool? --Steve No -- the intended change was from multiple :use forms to one :use form with multiple namespaces. Any indentation changes outside of that were unintentional--let me know if I am violating conventions. --Stu --~--~-~--~~~---~--~~ 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: DISCUSS: clojure.contrib.java-utils/file
Doh! Missed that. The duck-streams and java-utils versions of file have overlapping but disjoint functionality. Other-Stuart, I can take a look at combining these, or we can just leave them separate for now. --Stuart On Apr 5, 5:07 pm, Stuart Halloway stuart.hallo...@gmail.com wrote: Never worry about foo vs. (File. foo) again! (doc file) - clojure.contrib.java-utils/file ([arg] [parent child] [parent child more]) Returns a java.io.File from string or file args. Notes: (1) You will need to build contrib from source to see this. (2) This function is a slight generalization of a similar function in Compojure. James, I am hoping to convince you to make Compojure depend on contrib and start using a standard set of utils. What do you think? There's actually a file in clojure.contrib.duck-streams that's pretty similar to this. In fact, I removed the file function from Compojure because it clashed with duck-streams :) - James --~--~-~--~~~---~--~~ 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: proposed new contrib: java-utils
I'd also like to get your latest thinking on your suggestions from some time ago about clojure.contrib.lazy-seqs. If they can be rewritten as you suggested as functions that return a new sequence rather than as def'd sequences, that's strictly more powerful and would be an improvement. (One can always use a def'd var to hold such a function if that's desired in a particular application.) Steve, At quick glance it looks to me that all three of the lazy-seqs should be functions. If you want me to I'll change this and add tests. Stuart --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: DISCUSS: clojure.contrib.java-utils/file
Good summary. Let's keep them separate until we feel pain. - Stuart Halloway They work rather differently. duck-streams/file treats all arguments as strings, so (file foo bar) = File foobar I wrote it that way because I often want to construct a file name like (file base . extension) java-utils/file is closer to the Java File interface, by assuming that each argument is a separate directory name. (file foo bar) = File foo/bar I don't see an obvious way of combining them. java-utils/file is more efficient because it doesn't have to do any string manipulation. My opinion? java-utils/file is more Java-like; duck-streams/file is more Ruby-like. Neither is particularly Clojure-like, that would just be (File. foobar). -Stuart Sierra On Apr 5, 5:30 pm, James Reeves weavejes...@googlemail.com wrote: I'd like it if they were combined. You could then use (file foo/ bar) or (file foo bar). - James On Apr 5, 9:25 pm, Stuart Halloway stuart.hallo...@gmail.com wrote: Doh! Missed that. The duck-streams and java-utils versions of file have overlapping but disjoint functionality. Other-Stuart, I can take a look at combining these, or we can just leave them separate for now. --Stuart On Apr 5, 5:07 pm, Stuart Halloway stuart.hallo...@gmail.com wrote: Never worry about foo vs. (File. foo) again! (doc file) - clojure.contrib.java-utils/file ([arg] [parent child] [parent child more]) Returns a java.io.File from string or file args. Notes: (1) You will need to build contrib from source to see this. (2) This function is a slight generalization of a similar function in Compojure. James, I am hoping to convince you to make Compojure depend on contrib and start using a standard set of utils. What do you think? There's actually a file in clojure.contrib.duck-streams that's pretty similar to this. In fact, I removed the file function from Compojure because it clashed with duck-streams :) - James --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
lazy seqs (was Re: proposed new contrib: java-utils)
r652 is a breaking change to contrib. (powers-of-2) and (fibs) are now functions and do not hold their heads. primes is still a sequence because it needs to hold past values for efficiency. Stuart On Apr 5, 2009, at 4:27 PM, Stuart Halloway wrote: At quick glance it looks to me that all three of the lazy-seqs should be functions. If you want me to I'll change this and add tests. Please do. Thanks. --Steve --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
reading properties file: does this helper already exist?
Does something like this (or better) already exist in Clojure? If not I will add it to java-utils. Thanks, Stu (defn read-properties [f] (into {} (let [props (Properties.)] (.load props (FileInputStream. f)) props))) --~--~-~--~~~---~--~~ 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: reading properties file: does this helper already exist?
I don't like that if you treat properties as a seq you get Java Hashtable$Entry objects, instead of a vector as you would with a map, hence my into {}. But maybe it is a silly quibble since destructuring works fine with either. Stuart Can't you just write: (.load (Properties.) (FileInputStream. f)) and skip separate function altogehter? Err.. that should be: (doto (Properties.) (.load (FileInputStream. f))) .. point remains. -- Krešimir Šojat --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Java 6 dependency in clojure-contrib ok?
Perry's proposed props functions (http://groups.google.com/group/clojure/browse_thread/thread/c8ec751b8e66b019/d56ed1200aa95bca ) uses some Java 6 methods. Is it ok for me to add such things to contrib, or are we maintaining Java 5 compatibility? Stu --~--~-~--~~~---~--~~ 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: DISCUSS: clojure.contrib.java-utils/the-str
Changed to as-str (r654). Stu In Compojure, I called this str*, but I think I like as-str a little better. - James On Apr 5, 5:19 pm, Stuart Halloway stuart.hallo...@gmail.com wrote: Never worry about the distinction between symbols, keywords, and strings when working with Java APIs that know only strings! (doc the-str) - clojure.contrib.java-utils/the-str ([x]) Returns the name or string representation of x Notes: (1) You will need to build contrib from source to see this. (2) This function is moved from Steve Gilardi's sql.internal contrib. (Steve, I broke sql in r636 but I think I fixed it now. Are there tests I can run?) (3) I believe that the-str in miglayout can also be eliminated in favor of this standard version. Steve, do you agree? Questions: (1) I kept the original name the-str but would prefer as-str. Community, what say ye? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: clojure dependency management and build
Lancet is more at proof-of-concept stage than ready for heavy lifting -- I am using a mix of Ant and Rake on my own Clojure stuff. :-) I am happy to contribute to solving some of these issues but don't have time to lead the effort. Stuart When you are building something real with Clojure and Emacs/Slime/ Swank - things can get a bit hairy with dependency management. I have scoured the inter-tubes in the past couple days to see what I could find. I found Lancet, for builds: http://github.com/stuarthalloway/lancet/tree/master I haven't tried it yet. I found some people doing things with Maven: Creating a clojurue app with maven: http://pupeno.com/blog/how-to-create-a-clojure-application?set_language=eo http://pupeno.com/blog/iterative-coding-with-a-clojure-application clojure-pom: http://github.com/dysinger/clojure-pom/tree/master I heard some chatter yesterday on #clojure about using Ivy with Clojure. So there is a flurry of activity. Please let me know if there are other things that I am missing. What I am doing now from my emacs / slime-repl is hacking things in manually to my swank-clojure-extra-classpaths. This doesn't scale for working with multiple clojure projects in emacs. I will probably create a script to make things a bit nicer. But I'd like something fundamentally better. Here are the issues: -I download lots of little projects things from github and i want to munge them all together for my app. This means I need to build jars (some with ant, otehrs with maven, etc.) and in other cases I want to depend directly on the .clj files using clojures namespace-to-dir- structure conventions. So there are a couple different ways to build of the classpath - one for .clj and one for .jar. -Many projects also have their own lib foler - with both jars and cljs, so I need to pick those deps up transatively. -The work in the Clojure community is proceeding very fast, so I'd like updating all the projects from git to be automated as well. So what is a good solution to these problems? Perhaps it would be cool to build some git/maven/lancet aware infrastructure to do this refreshing of deps, building the deps, and building up the classpath. It may also be good to configure .emacs to be able to load projects and rebuild the classpath dynamically based on lancet build files - much in the way that intelliJ or eclipse load projects from ant .builds or maven poms. Is all this too much, am I missing something that already exists? --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
getting code coverage into clojure-contrib builds?
I spent a few minutes this morning trying to get an emma coverage report over contrib. Short answer is that it doesn't work -- emma throws an exception while instrumenting the code (see attached console.txt). I will go and bug the emma folks, but first wanted to ask here if there is any specific reason that Clojure-generated bytecode might surprise emma? I have attached a modified build.xml if anybody wants to try this out. Stu --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~--- project name=clojure-contrib default=jar xmlns:mvn=urn:maven-artifact-ant description Pack all clojure-contrib sources into a JAR. Compile those that can be compiled standalone if the clojure.jar property points us to clojure.jar. /description property name=src location=src/ property name=build location=classes/ available property=hasclojure file=${clojure.jar}/ !-- The JAR file to create. -- property name=jarfile location=clojure-contrib.jar/ property name=slimjarfile location=clojure-contrib-slim.jar/ !-- These make sense for building on tapestry.formos.com -- property name=snapshot.repo.dir location=/var/www/maven-snapshot-repository/ property name=stable.repo.dir location=/var/www/maven-repository/ target name=init tstamp/ mkdir dir=${build}/ /target target name=clean description=Remove generated files and directories. delete file=${jarfile}/ delete file=${slimjarfile}/ delete dir=${build}/ /target target name=test_clojure description = Run clojure tests if=hasclojure java classname=clojure.main classpath path location=${build}/ path location=${src}/ path location=${clojure.jar}/ /classpath arg value=-e/ arg value=(require '(clojure.contrib [test-clojure :as main])) (main/run)/ /java /target target name=test_contrib description = Run contrib tests if=hasclojure mkdir dir=coverage/ emmajava classname=clojure.main libclasspathref=emma.lib classpath path location=${build}/ path location=${src}/ path location=${clojure.jar}/ /classpath arg value=-e/ arg value=(require '(clojure.contrib [test-contrib :as main])) (main/run)/ txt outfile=coverage/coverage.txt / xml outfile=coverage/coverage.xml / html outfile=coverage/coverage.html / filter includes=clojure.contrib.*/ /emmajava /target !-- you will need to grab these files from http://emma.sourceforge.net/ -- path id=emma.lib pathelement location=emma/emma.jar / pathelement location=emma/emma_ant.jar / /path taskdef resource=emma_ant.properties classpathref=emma.lib / target name=emma description=turns on EMMA's on-the-fly instrumentation mode property name=emma.enabled value=true / /target target name=test_datalog description = Run datalog tests if=hasclojure java classname=clojure.main classpath path location=${build}/ path location=${src}/ path location=${clojure.jar}/ /classpath arg value=-e/ arg value=(require '(clojure.contrib.datalog.tests [test :as main])) (main/run)/ /java /target target name=test depends=test_clojure,test_contrib,test_datalog description=Run all tests/ target name=check_hasclojure description=Print a warning message if clojure.jar is undefined unless=hasclojure echoWARNING: You have not defined a path to clojure.jar so I can't compile files. This will cause some parts of clojure.contrib not to work (e.g., pretty print). To enable compiling, run ant -Dclojure.jar=lt;...path to clojure.jar..gt; /echo /target target name=compile_clojure depends=init,check_hasclojure description=Compile Clojure sources. if=hasclojure java classname=clojure.lang.Compile classpath path location=${build}/ path location=${src}/ path location=${clojure.jar}/ /classpath sysproperty key=clojure.compile.path value=${build}/ arg value=clojure.contrib.accumulators/ arg value=clojure.contrib.command-line/ arg value=clojure.contrib.complex-numbers/ arg value=clojure.contrib.cond/ arg value=clojure.contrib.core/ arg value=clojure.contrib.def/ arg value=clojure.contrib.duck-streams/ arg value=clojure.contrib.except/ arg value=clojure.contrib.fcase/ arg value=clojure.contrib.generic/ arg value=clojure.contrib.generic.arithmetic/ arg value=clojure.contrib.generic.collection/ arg
Re: getting code coverage into clojure-contrib builds?
OK, I'll try Cobertura next. There is a reason my Java knowledge sounds about 5 years old ... :-) Stu Stuart Halloway wrote: I will go and bug the emma folks, but first wanted to ask here if there is any specific reason that Clojure-generated bytecode might surprise emma? I might be totally wrong, but from what I've heard, Emma's development has stopped a few years ago and it doesn't support some Java 5 features, including annotations. A quick search seems to confirm the development has stopped scenario, at the very least. That said, I know cobertura is used successfully nowadays in java projects; it also works at the bytecode level. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
OK, cobertura runs, but...
I have Cobertura running and producing reports against contrib, sort-of. Problems: (1) AFAICT, cobertura *insists* in trying to parse the source code as Java to do cyclomatic complexity analysis. This blows up, of course. (2) The red/green coloring of the lines does not match what I know is happening in the test run. This may be caused by #1 but I doubt it. I have attached a modified contrib build.xml if anyone wants to play with this. Note that you will need to drop cobertura and its various jars into a cobertura directory. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~--- project name=clojure-contrib default=jar xmlns:mvn=urn:maven-artifact-ant description Pack all clojure-contrib sources into a JAR. Compile those that can be compiled standalone if the clojure.jar property points us to clojure.jar. /description property name=src location=src/ property name=build location=classes/ property name=test.temp.dir location=test/tmp/ available property=hasclojure file=${clojure.jar}/ !-- The JAR file to create. -- property name=jarfile location=clojure-contrib.jar/ property name=slimjarfile location=clojure-contrib-slim.jar/ !-- These make sense for building on tapestry.formos.com -- property name=snapshot.repo.dir location=/var/www/maven-snapshot-repository/ property name=stable.repo.dir location=/var/www/maven-repository/ target name=init tstamp/ mkdir dir=${build}/ /target target name=clean description=Remove generated files and directories. delete file=${jarfile}/ delete file=${slimjarfile}/ delete dir=${build}/ /target target name=test_clojure description = Run clojure tests if=hasclojure java classname=clojure.main classpath path location=${build}/ path location=${src}/ path location=${clojure.jar}/ /classpath arg value=-e/ arg value=(require '(clojure.contrib [test-clojure :as main])) (main/run)/ /java /target target name=test_contrib description = Run contrib tests if=hasclojure mkdir dir=${test.temp.dir}/ java classname=clojure.main classpath path location=${build}/ path location=${src}/ path location=${clojure.jar}/ /classpath arg value=-e/ arg value=(require '(clojure.contrib [test-contrib :as main])) (main/run)/ /java /target target name=cover_contrib description = Run contrib tests for coverage if=hasclojure depends=instrument mkdir dir=${test.temp.dir}/ java fork=yes classname=clojure.main sysproperty key=net.sourceforge.cobertura.datafile file=${basedir}/cobertura.ser / sysproperty key=clojure.jar file=${clojure.jar} / classpath path location=cobertura/instrumented/ path refid=cobertura.classpath/ path location=${src}/ path location=${clojure.jar}/ /classpath arg value=-e/ arg value=(require '(clojure.contrib [test-contrib :as main])) (main/run)/ /java cobertura-report format=html srcdir=${src} destdir=cobertura/report/ /target target name=test_datalog description = Run datalog tests if=hasclojure java classname=clojure.main classpath path location=${build}/ path location=${src}/ path location=${clojure.jar}/ /classpath arg value=-e/ arg value=(require '(clojure.contrib.datalog.tests [test :as main])) (main/run)/ /java /target target name=test depends=test_clojure,test_contrib,test_datalog description=Run all tests/ target name=check_hasclojure description=Print a warning message if clojure.jar is undefined unless=hasclojure echoWARNING: You have not defined a path to clojure.jar so I can't compile files. This will cause some parts of clojure.contrib not to work (e.g., pretty print). To enable compiling, run ant -Dclojure.jar=lt;...path to clojure.jar..gt; /echo /target target name=compile_clojure depends=init,check_hasclojure description=Compile Clojure sources. if=hasclojure java classname=clojure.lang.Compile classpath path location=${build}/ path location=${src}/ path location=${clojure.jar}/ /classpath sysproperty key=clojure.compile.path value=${build}/ arg value=clojure.contrib.accumulators/ arg value=clojure.contrib.command-line/ arg value=clojure.contrib.complex-numbers/ arg value=clojure.contrib.cond/ arg value=clojure.contrib.core/ arg value=clojure.contrib.def/
Re: DISCUSS: tests that read and write files
Three concerns: (1) Would like to see the file after a failed test. (2) Also have tests that read a file, and I would be much more comfortable not having to rely on code to write the file first. Doesn't feel like a unit test. (3) The macro is more complex than the code being tested. :-) (The net effect of my build.xml changes might also be...) But I am much more interested in having a shared approach that all contrib users adhere to than in getting my way. :-) Stu My recommendation would be to use a temporary file that is created and deleted in a macro or fixture. (defmacro with-tmp-properties-file [ body] `(binding [*tmp-properties-file* (File/createTempFile temp .properties)] (spit *tmp-properties-file* contents of the test file) ~...@body (.delete *tmp-properties-file*))) -Stuart Sierra On Apr 9, 1:54 pm, Stuart Halloway stuart.hallo...@gmail.com wrote: In r659 I added a unit test to clojure-contrib that needed to read and write from the filesystem. I picked a dumb and simple convention, and welcome review from other committers to move to something that is just- smart-enough. Stu --~--~-~--~~~---~--~~ 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: set-system-properties
Yes to almost all of this (r662). I am not totally comfortable with the false/false conversion. Stu Hi Stuart H! Comment on: (defn set-system-properties [settings] Set some system properties. Nil clears a property. (doseq [[name val] settings] (if val (System/setProperty (as-str name) val) (System/clearProperty (as-str name) What if that were: (if (nil? val) (System/clearProperty (as-str name)) (System/setProperty (as-str name) (as-str val)) The change allows: 1. Using boolean false as a value (converted to the string false) 2. Using keywords/symbols as values. Also, get-system-property could support multiple arities: (defn get-system-property ([stringable] (System/getProperty (as-str stringable))) ([stringable default] (System/getProperty (as-str stringable) (as- str default -Stuart S --~--~-~--~~~---~--~~ 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: The Path to 1.0
I would love to see 1.0, and the sooner the better. At Relevance we are doing real work in Clojure today. As for wish list I would love to see improvements to the development process: * move from svn to git * move regression tests from contrib into clojure itself But neither of these need necessarily to block 1.0 IMO. When I release software that depends on Clojure I pin it to a commit number, not to a named release. For me the named release is more about public recognition than anything else. Cheers, Stu P.S. Git is to svn as functional languages are to mutable languages. Git repositories are immutable data structures, and repos-local pointers such as HEAD are like atoms. It would be interesting to see Clojure's data structures have a canonicalized serialization and play around with content addressability. When we release software that depends on Clojure we don't care about numbered releases at all -- we will run regression tests of our own production app against the Clojure and contrib repositories and pin our releases to a commit number, not a specif People (and not just book authors :) often ask - whither 1.0? [Ok, maybe they don't use 'whither']. The fact remains, some people want a 1.0 designation, and I'm not unwilling, providing we as a community can come to an understanding as to what that means, the process it implies, and the work it will require (and who will do it). Here are some of the relevant issues, IMO: - Stability/completeness/robustness This is mostly about - does it work? Is it relatively free of bugs? Is it free of gaping holes in core functionality? I think Clojure is in a pretty good place right now, but am obviously biased. This in no way implies there isn't room for improvement. - API stability With the semantic changes of fully lazy sequences behind us, I think the syntax and semantics of existing functions is largely stable. - Development process stability Currently all new work (fixes and enhancements) occurs in trunk. There's no way to get fixes without also getting enhancements. I think this is the major missing piece in offering stable numbered releases. While I've cut a branch for each of the prior two releases, no one has ever submitted a bugfix patch for either. If people are going to want to work with a particular release version for an extended period of time, someone (other than me) will have to produce patches of (only!) fixes from the trunk for the release branch, and occasionally produce point releases (1.0.x) from that branch. I'd like to continue to do the bulk of my work in trunk, without messing anyone up or forcing everyone to follow along. - Freedom from change Numbered releases are most definitely not about absence of change in general. There are more things I want to add and change, and there will be for some time. That will keep Clojure a living language. 1.0 or any numbered release can't and won't constitute a promise of no further change. But there are different kinds of change, changes that fix bugs and changes that add new capabilities or break existing code. People need to be able to choose the type of change they can tolerate, and when to incur it. - Perception Obviously, a 1.0 designation impacts perception. I am not interested in pursuing it just to influence perception, but rather to (collectively) acknowledge a milestone in usability and stability. However there may be other perceptions, good/bad or simply wrong (e.g. that Clojure is finished). Will the general perception engendered by 1.0 be met in the large, or a mismatch? What does 1.0 mean to you? Are we there yet? Any recommendations for the organization of the release branches, patch policy etc? Feedback 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 -~--~~~~--~~--~--~---
Re: str-utils change proposal, round 2
FYI: I am working on an open-source CSV parser in Clojure. Splitting on delimiters is rarely enough in my experience. Stu would you consider adding support of a split by passing a delimiter? since parsing csv/tsv is a pretty common task. I know it can be done by using re-split. but it seems to occur common enough that it's not a bad idea. On Thu, May 14, 2009 at 1:12 AM, Sean Devlin francoisdev...@gmail.com wrote: Hello again everyone, I've added a few new routines to a string library I've been working on. I mentioned it about a month ago, as a proposed change to str- utils. Original Thread: http://groups.google.com/group/clojure/browse_thread/thread/42152add46b851a0# Github: http://github.com/francoisdevlin/clojure-str-utils-proposal/tree/master Most notable I've created two new functions in this addition, str-take str-drop They have a simple form (str-take 7 Clojure Is Awesome) = Clojure (str-drop 8 Clojure Is Awesome) = Is Awesome But the can also take a regex (str-take #\s+ Clojure Is Awesome) = Clojure (str-drop #\s+ Clojure Is Awesome) = Is Awesome You can check the tests and README.html for more usage. I'm looking for feedback. If anyone else has string functions that I haven't covered, let me know. Thanks, Sean -- Omnem crede diem tibi diluxisse supremum. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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 -~--~~~~--~~--~--~---
monad tutorial question
When working through Part 3 of the monad tutorial [1], I am seeing the following behavior for fib-trace: (fib-trace 3) = [2 [[[1 1] [[[0 0] []] [[2 1] [[[1 1] [ According to the tutorial, it should be: (fib-trace 3) = [2 [[1 1] [0 0] [2 1] [1 1]]] Am I doing something wrong? Stu [1] http://onclojure.com/2009/03/23/a-monad-tutorial-for-clojure-programmers-part-3/ --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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 -~--~~~~--~~--~--~---
is there a sibling of fmap that maps keys instead of values?
clojure.contrib.generic.functor.fmap will return a map with values updated by a function. What if I wany *keys* updated by a function? Does this exist yet? If not, what should I name it for inclusion in contrib? Stu --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: is there a sibling of fmap that maps keys instead of values?
Thanks Konrad. I certainly do not want to add this to fmap. However, I think there are lots of situations where mapping keys is well-defined. For example, you have a tree of data from XML or JSON, and you want to replace the keys (strings) with instances of their actual type. I guess given the ambiguity that names like mapkeys might be misleading. Other suggestions? Stu On 30.05.2009, at 17:11, Stuart Halloway wrote: clojure.contrib.generic.functor.fmap will return a map with values updated by a function. What if I wany *keys* updated by a function? Does this exist yet? If not, what should I name it for inclusion in contrib? Speaking strictly from an implementation point of view, you could add a type tag to your map that identifies it as a map for which fmap acts on keys, and implement the multimethod fmap for that type. However, transforming keys is a much less well-defined operation than transforming values. You can consider a map a function from keys to values; fmap then returns the composition of that function with an arbitrary function f. That's always well-defined. A transformation of keys can lead to ambiguities: what if two different keys are transformed to the same new key, but the associated values differ? For this reason, the operation you want does not satisfy the conditions for fmap. Finally, I don't know of any other module that implements such a function, perhaps because of the ambiguity problem. Konrad. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Good examples of defmulti polymorphism
Hi Glen, (1) Real-world example: I use polymorphism on the types of two different arguments to define implicit conversions: (defmulti coerce (fn [dest-class src-inst] [dest-class (class src-inst)])) (defmethod coerce [java.io.File String] [_ str] (java.io.File. str)) (defmethod coerce [Boolean/TYPE String] [_ str] (contains? #{on yes true} (.toLowerCase str))) (2) Made-up, but realistic example: using polymorphism on two different inheritance hierarchies on a single argument: (defmulti service-charge (fn [acct] [(account-level acct) (:tag acct)])) (defmethod service-charge [::acc/Basic ::acc/Checking] [_] 25) (defmethod service-charge [::acc/Basic ::acc/Savings][_] 10) (defmethod service-charge [::acc/Premium ::acc/Account] [_] 0) (3) Example from inside Clojure itself: using external tags to layer a hierarchy onto existing objects without their knowledge (inspector.clj). All of these are documented in the book [1] and you can view the sample code at [2]. Cheers, Stu [1] http://www.pragprog.com/titles/shcloj/programming-clojure [2] http://github.com/stuarthalloway/programming-clojure/. See examples/multimethods* I'm used to polymorphism in OO systems where everything in driven from inheritance hierarchy. Clojures defmulti style polymorphism seems powerful but has left me wondering how to most effectively use it. I'm looking for some good real world examples of how people have used polymorphism in clojure. Regards, Glen Stampoultzis --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: You know you've been writing too much Clojure when...
People keep looking at me funny when I point out variables as code smells during code review... Stu Same here with the commas. Since I've been neck deep in Clojure, I've been pathologically forgetting to add them with other languages. On Jun 2, 10:06 am, Shawn Hoover shawn.hoo...@gmail.com wrote: On Tue, Jun 2, 2009 at 9:52 AM, Michael Reid kid.me...@gmail.com wrote: On Fri, May 29, 2009 at 2:51 PM, Paul Stadig p...@stadig.name wrote: You meant to type disclosure, but instead you typed disclojure. Paul How about when you try to write code in other languages, and reflexively place parentheses before function/method names? (len 'Foo') -- not valid Python. :( /mike. Don't forget, commas are NOT optional! irb(main) a = [1 2 3] SyntaxError: compile error! --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
feature request: docstring for defstruct
I would like to see defstruct take an optional docstring. Would such a patch be welcome? Stu --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: filter on sequence
Ditto what everyone else said, plus let's get rid of the duplicated call to Math/log by splitting the iterate into an iterate + a map: (take-while (fn [[_ second]] ( second 10)) (map (fn [x] [x (/ x (Math/log x))]) (iterate #(* % 2) 2))) Stu On 02.06.2009, at 17:35, Wilson MacGyver wrote: for example, the first 10 produces. ([2 2.8853900817779268] [4 2.8853900817779268] [8 2.8853900817779268] [16 3.8471867757039027] [32 5.7707801635558535] [64 9.233248261689365] [128 15.38874710281561] [256 26.380709319112476] [512 46.16624130844683] [1024 82.07331788168325]) what if I want to filter so I only get pairs for which the 2nd value is 10. I couldn't figure out how to get filter to work for pair values. Try this: (take 3 (filter #( (second %) 10) (iterate (fn [[a b]] [(* 2 a) (/ a (Math/log a))]) [2 (/ 2 (Math/log 2))]))) If you try to take 10 values, you will create an endless loop because with the given parameters your sequence actually has less than ten elements that satisfy the condition! a 2nd question is more of general clojure idiom, in trying to covert the following java code from michaelg's java 1 presentation private int calcSize(){ int max = 2; while ((max/Math.log(max)) size max Integer.MAX_VALUE max 0){ max *=2; } return max; } My first reaction was to do it using a sequence. Is this the clojure idiomatic way to convert a while loop from other languages? Clojure has loops as well: (let [size 10] ;made up (loop [max 2] (if (or (= (/ max (Math/log max)) size) (= max Integer/MAX_VALUE) (= max 0)) max (recur (* 2 max) Konrad. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: unit testing private methods?
Hi Allen, You could write a function that uses the clojure.contrib.with-ns/with- ns macro to dip into the namespace being tested and return the private function, assigning it to a local name in the test namespace. I need this too, and have been meaning to ping the other Stuart about either (a) adding something like this to test-is, or (b) creating a new test-helpers library in contrib that would include this function. Stu I have a namespace with some public functions, and some private functions. I would like to write unit tests for the functions, and put them in a separate file from the main name space. I would also like to have an (ns) declaration in my tests file, because the tests require several libraries. Of course, if I have private methods in namespace A, I can't call them from namespace B. Right now, it seems I have several options: 1) put the unit tests in the same file 2) put the unit tests in a separate file, in the same namespace 3) make the private functions public 4) ??? I don't really like the first three options. Ideally, the private functions would remain private to every namespace except the testing name space. Is there a good solution for this? Allen --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: unit testing private methods?
2) put the unit tests in a separate file, in the same namespace This works for me, but since it won't work with the normal use/require idiom, I would like to see a standard convention evolve to make it easy to read other people's code. Stu --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Spring and Clojure
I think Clojure addresses (at the language level, and better) all the issues that Spring addresses. So in the long run Spring is unnecessary in a Clojure world. But in the short run you have the codebase you have, and the skills that you have. So if it makes sense, do it. Stu At this point I have no particular use case. We are solely a Spring shop where we build Spring web apps and we use Groovy beans (using dynamic lang support in Spring) for some stuff like MVC controllers, XML parsing, etc. I thought that it would be interesting to incorporate some Clojure beans for some tasks (perhaps some concurrent processing tasks, etc.) Does it even make saense? Anyway, if someone would come up with a way to integrate Clojure code into Spring ApplicationContext and show the example, that would be interesting. Best regards, Dmitriy. 2009/6/3 Luc Prefontaine lprefonta...@softaddicts.ca We did the reverse (using Spring directly from Clojure) without any difficulty. Never thought about creating Clojure beans however. We had already some code to bootstrap Spring from Java. Just called it from Clojure. We wanted to drop Java as much as possible but did not want to loose some of the low level stuff we wrote in Java. Being curious, can you shed any light of the use you would make of Clojure beans ? Luc P. On Wed, 2009-06-03 at 09:02 -0700, Dmitriy Kopylenko wrote: Hello. I'm just wondering is there a way to create Clojure beans and inject them into other Spring beans (given that Clojure code implements Java interface) inside Spring ApplicationContext, similar to other dynamic langs support: http://static.springframework.org/spring/docs/2.5.x/reference/dynamic-language.html ? Thanks, Dmitriy. Luc Préfontaine Armageddon was yesterday, today we have a real problem... --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: [ANN] test-expect functional mocking/expectation library
Hi Matt, I would like to move this to contrib, if you will sign the CA. I'll be moving my simple binding-based stubs to use this and will send along suggestions if I have any. Thanks for writing this! Stu P.S. Apologies if variants of this message show up twice. Mail client wonkiness... When I started working on this library, I thought to myself, I can't believe no one has put together an expectation/mocking library but I couldn't find one so I went ahead and started my own. Of course, it was not until I had an early working version that I discovered Allen Rohner's expectation tools, but I figured that mine were sufficiently different to merit further development (at least relative to the latest code of his I could find). In the past week or so I've been refactoring and fixing bugs on my test-expect library and I find it much improved over what I previously had. The salient improvements on the latest on trunk include: - Removal of dependency on test-is. Tests have been moved to a separate file instead. The library is still geared toward easy integration with test-is, but the explicit dependency is gone. - Replaced exceptions on error with the new and improved error functions that are ready to be overridden or used as-is. They also include reporting the expected behavior in an unevaluated form, a la test-is. - Added convenience methods such as (once) (more-than x) for invocation count and argument matching.\ - Default has-args argument matchers to being equality matchers so you can say (has-args [5]) instead of (has-args [#(= 5 %)]) - Bug fixes The latest is available for public consumption at http://code.google.com/p/test-expect/ Basically the gist of it is it sets up the bindings for any functions you'd rather not touch while testing the function you're working on. So, you just say: (expect [dep-fn1 (has-args [5 (less-than 4)] (returns a string!))] (fn-under-test-which-calls-dep-fn1)) Any unexpected or unmatched calls are reported. Successful execution is silent, which mirrors other libraries I have used in other languages. Further details to be found in the source. Suggestions for further changes or improvements are more than welcome. If people find this library useful I'd be more than happy to sign the CA and put this in contrib. Also, Allen, if you are interested in merging our efforts let me know. Is your latest code available? -Matt --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: [ANN] test-expect functional mocking/expectation library
Hi Matt, I would definitely like to see test-expect added to contrib. If you will sign the CA I will move it there. I have a bunch of existing tests that are simply using binding to do cheap stubbing, and will be converting those tests to test-expect over the next several days. Thanks for writing this! Stu When I started working on this library, I thought to myself, I can't believe no one has put together an expectation/mocking library but I couldn't find one so I went ahead and started my own. Of course, it was not until I had an early working version that I discovered Allen Rohner's expectation tools, but I figured that mine were sufficiently different to merit further development (at least relative to the latest code of his I could find). In the past week or so I've been refactoring and fixing bugs on my test-expect library and I find it much improved over what I previously had. The salient improvements on the latest on trunk include: - Removal of dependency on test-is. Tests have been moved to a separate file instead. The library is still geared toward easy integration with test-is, but the explicit dependency is gone. - Replaced exceptions on error with the new and improved error functions that are ready to be overridden or used as-is. They also include reporting the expected behavior in an unevaluated form, a la test-is. - Added convenience methods such as (once) (more-than x) for invocation count and argument matching.\ - Default has-args argument matchers to being equality matchers so you can say (has-args [5]) instead of (has-args [#(= 5 %)]) - Bug fixes The latest is available for public consumption at http://code.google.com/p/test-expect/ Basically the gist of it is it sets up the bindings for any functions you'd rather not touch while testing the function you're working on. So, you just say: (expect [dep-fn1 (has-args [5 (less-than 4)] (returns a string!))] (fn-under-test-which-calls-dep-fn1)) Any unexpected or unmatched calls are reported. Successful execution is silent, which mirrors other libraries I have used in other languages. Further details to be found in the source. Suggestions for further changes or improvements are more than welcome. If people find this library useful I'd be more than happy to sign the CA and put this in contrib. Also, Allen, if you are interested in merging our efforts let me know. Is your latest code available? -Matt --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
(re)setting a function globally
Matt Clark's test-expect library includes two versions of a report- problem function: a standalone version, and another that integrates with test-is. The comments suggest two ways to active the test-is version: wrapping calls to expect in a binding, and interning the specialized version of report-problem back into the main test namespace. After playing with it for a few minutes, I decided I preferred the latter approach, and would suggest adding the following function to test-expect: (defn use-test-is! [] (require 'mdc.common.test-expect.test-is-adapter) (def report-problem (ns-resolve 'mdc.common.test-expect.test-is- adapter 'report-problem))) This feels a little hacky, but is there a better way? I don't see how binding/set! get me there, because I do not want to repeat bindings for every test, nor do I want to have to create a top level binding context. Stu --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: (re)setting a function globally
Matt is signing the CA and I will be adding test-expect to contrib. Stu Can I help from the test-is side? Could test-expect be added to clojure-contrib? -Stuart On Jun 10, 1:36 pm, Matt Clark matt.clar...@gmail.com wrote: Thanks for these ideas, I will give them a try tonight and update the adapter namespace with the changes. If anyone knows of a more idiomatic way I could have implemented the problem reporting functionality that would prevent the necessity of these hacky solutions, I'm all ears. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: (re)setting a function globally
Hi Matt, I think it is important to have a one-line solution for using the library with test-is. If you are going this route, I would have the adapter namespace immigrate in all (except expect) from the test- expect namespace. That way a single (use 'clojure.contrib.test- expect.test-is) would be sufficient to get started. You can write a specific immigrate function based on the generic one in Compojure. While you are at it, send James an email asking him to sign the CA and donate immigrate to contrib. :-) Once Rich confirms the signed CA, I will add the library to contrib. Stu The agreement is signed and in the (snail) mail. Also, I think I found a solution to the original problem that spurred this thread. In the test-is-adapter namespace I have added an expect macro that wraps the standard expect macro with a binding for the test- is specific report-problem function. So now when you want to use test- expect and test-is together, just :use all of test-expect excluding the expect macro, :use the expect macro from the test-is-adapter, :use test-is and you should be good to go. This way you should get the best of both worlds with no destructive global function changes. Go figure I come up with this after reading the entire clojure modules thread and starting a solution using deftemplate :) - Matt On Jun 11, 8:36 am, Stuart Halloway stuart.hallo...@gmail.com wrote: Matt is signing the CA and I will be adding test-expect to contrib. Stu Can I help from the test-is side? Could test-expect be added to clojure-contrib? -Stuart On Jun 10, 1:36 pm, Matt Clark matt.clar...@gmail.com wrote: Thanks for these ideas, I will give them a try tonight and update the adapter namespace with the changes. If anyone knows of a more idiomatic way I could have implemented the problem reporting functionality that would prevent the necessity of these hacky solutions, I'm all ears. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: will clojure evolve to be able to do systems programming?
Would be interesting to combine Clojure with NailGun for utility scripting... http://sourceforge.net/projects/nailgun/ Due to the startup cost of the JVM, Clojure and Java probably aren't the best choices for tiny five to ten line utility scripts. That being said, Clojure works well for level stuff like bit twiddling, I/O, and socket programming. If you're in an environment where Java is available on your servers, it can be a good bet due to the extreme simplicity of deployment. Travis On Jun 16, 9:30 am, hari sujathan hari.sujat...@gmail.com wrote: thanks regards, Hari Sujathan --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
binding at the REPL
This surprised me. What part of my mental model needs to be adjusted? :-) user= (def dozen 12) #'user/dozen user= (binding [dozen 13] dozen) 12 ; hunh? user= (#(binding [dozen 13] dozen)) 13 --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: binding at the REPL
OK, just updated the repos. and this isn't happening anymore. Kind of a strange bug though. Rich, do you know why this happened (and did you explicitly fix it at some point?) Strange, I get the expected result, Clojure SVN revision 1382: user (def dozen 12) #'user/dozen user (binding [dozen 13] dozen) 13 user (#(binding [dozen 13] dozen)) 13 user -the other Stuart On Jun 16, 2:08 pm, Stuart Halloway stuart.hallo...@gmail.com wrote: This surprised me. What part of my mental model needs to be adjusted? :-) user= (def dozen 12) #'user/dozen user= (binding [dozen 13] dozen) 12 ; hunh? user= (#(binding [dozen 13] dozen)) 13 --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: clojure.contrib.*
Hi Justin, The easiest solution is to download the sample code for the book from [1] (this is referenced in the Preface under Downloading Sample Code). The sample code includes everything you need: clojure, clojure- contrib, and the book samples, plus launch scripts that get all the classpath stuff right. That way you can focus on learning the language first, and postpone classpath hell for a little later. :-) Best, Stuart [1] http://github.com/stuarthalloway/programming-clojure Is clojure.contrib.* not included with clojure? I'm reading the book and in chapter two re-split doesnt work for me. I may have missed some instructions- was I supposed to install something else? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
ANN: libraries promoted from contrib to clojure
If you are following the github head of the Clojure and contrib projects, you will see that several libraries have moved from contrib into Clojure: * clojure.contrib.test-is becomes clojure.test * clojure.contrib.stacktrace becomes clojure.stacktrace * clojure.contrib.template becomes clojure.template * clojure.contrib.walk becomes clojure.walk Thanks to Stuart Sierra for writing all these libraries. If you are using one of them (and working with head), you will need to rename it in your use/require/ns forms. Also, the signature and implementation of test/are has changed, and is now more idiomatic. For example: (deftest test-count (are [x y] (= x y) ; instead of (are (= _1 _2)) (count nil) 0 (count ()) 0 (count '(1)) 1 (count '(1 2 3)) 3 ; etc. The purpose of this change (other than the general usefulness of the libraries!) is to let Clojure host its own test suite. You can now run Clojure's tests with ant test. Go ye now, sign the CA, and write some great tests for Clojure. You know you want to. Stu --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
executing tasks on a schedule
I am working on a Clojure project that is becoming more and more schedule-oriented. So far I have been using Clojure's native concurrency constructs, but I am becoming tempted to use Java's concurrency primitives to get interruptability, etc. -- or maybe even wrap a Java library like Quartz. Has anyone else been down this road? Stu --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
porting Practical Common Lisp examples to Clojure
Hi all, I am porting [1] the Practical Common Lisp examples [2] to Clojure, and blogging notes [3] as I go. Feedback of all kinds is most welcome, and I hope that some folks here will find this useful. Cheers, Stuart [1] http://github.com/stuarthalloway/practical-cl-clojure [2] http://gigamonkeys.com/book/ [3] http://blog.thinkrelevance.com/2008/9/16/pcl-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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: (seq? abc)
Right. So, should sort work? user= (sort bca) java.lang.IncompatibleClassChangeError: Class java.lang.String does not implement the requested interface java.util.Collection Stuart (seq? ...) tests for whether or not the argument is a sequence, i.e. an instance of ISeq. (seq ...) works on things that are seq-able, basically any kind of collection (instances of IPersistantCollection, instances of java.util.Collection, Strings, Arrays, etc.), not solely instances of ISeq. If you look at their docs, they all say they accept a collection, not a sequence. So, the String abc is seq-able, but it is not a sequence itself. HTH, - J. On Thu, Oct 2, 2008 at 2:46 PM, Fogus [EMAIL PROTECTED] wrote: OK. So we can do: (map (fn [x] x) abc) (first abc) (rest abc) (filter (fn [x] (if (= x \b) false true)) abc) (seq abc) etc... So why is (seq? abc) false? -m --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: (seq? abc)
True, but what I am concerned about is cognitive load in understanding the language. Right now, there is some set of functions that work on seq-able things, and another set of functions that work only on actual seqs. Is there a reason that sort belongs in the latter camp? Stuart You could sort this way: user (apply str (sort (seq bac))) abc On Oct 2, 11:58 am, Stuart Halloway [EMAIL PROTECTED] wrote: Right. So, should sort work? user= (sort bca) java.lang.IncompatibleClassChangeError: Class java.lang.String does not implement the requested interface java.util.Collection Stuart --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
class weirdness
Does this make sense? user= (let [x Integer] (.getName x)) java.lang.Integer user= (.getName Integer) java.lang.NoSuchFieldException: getName --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
safe navigation operator
Groovy has a safe navigation operator. Yes, this probably enables Law of Demeter violations, but it is darn useful when you are dealing with existing Java APIs that required lots.of.dotted.notation. I would like to have this in Clojure. Anybody else like it? (defmacro ?. like .. but drops out on null object ([x form] `(. ~x ~form)) ([x form more] `(if-let x# (. ~x ~form) (.? x# [EMAIL PROTECTED] BTW, my use case was (?. someClass getProtectionDomain getCodeSource getLocation). This needs to drop out for null whenever someClass comes from a ClassLoader that cannot report its location. Stuart P.S. A cooler name than save navigation operator would be welcome, and I am not wedded to the Groovy syntax. I initially misremembered it as .? which I think I may like better. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: class weirdness
Thanks Stephen, Chouser, and Rich. Understanding the historical reason that (. SomeClass method) doesn't work, I would be in favor of the deprecation Rich mentioned, leading to (. SomeClass method) being able to work in the future. Cheers, Stuart --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: safe navigation operator
Yes, that's better. Glad you like the idea. Does anybody not named Stuart also want to see this added to Clojure? ;-) Stuart On Oct 3, 3:13 pm, Stuart Halloway [EMAIL PROTECTED] wrote: (defmacro ?. like .. but drops out on null object ([x form] `(. ~x ~form)) ([x form more] `(if-let x# (. ~x ~form) (.? x# [EMAIL PROTECTED] Interesting -- I like it. It doesn't seem to be totally compatible with .., though: user= (?. System (getenv SHELL) (startsWith /bin) getClass getName) java.lang.Exception: Unable to resolve symbol: startsWith in this context (NO_SOURCE_FILE:62) Also, if-let could give the wrong result in the (admittedly unlikely) situation that one of the methods returns Boolean.FALSE. Here's another take: (defmacro ?.. like .. but stops and returns nil if any method returns nil ([x form] `(.. ~x ~form)) ([x form more] `(let [x# (?. ~x ~form)] (if (nil? x#) nil (?. x# [EMAIL PROTECTED]) user= (?.. System (getenv SHELL) (startsWith /bin) getClass getName) java.lang.Boolean user= (?.. System (getenv FOO) (startsWith /bin) getClass getName) nil -the other Stuart --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
followup on struct inheritance
This is a tangent from Brian's question about struct inheritance: While I am not sure that I want struct inheritance, it seems unnecessarily hard to write the macro for it. Structs are not first class citizens, in that you cannot reflect against them. I want to ask: (defstruct person :fname :lname) (struct-keys person) ;hypothetical function - (:fname, :lname) Of course, by poking around a little bit I can get the answer: ; reflective goo (.get (.getDeclaredField (class person) keys) person) - (:fname :lname) Two questions: (1) Should Clojure provide a function to reflect on a PersistentStructMap$Def's keys? (2) Philosophical question: Why not make fields like Def.keys public to begin with? They are they key public contract of the Def class anyway. With keys public I would be comfortable with just saying (.keys person) for the scenario of reflecting against structure definitions. Stuart --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: help a journalist: why Clojure?
Clojure: - Reach and performance of Java - Elegance of Ruby* - Scales like nothing else** *Lisp would be more accurate than Ruby, but managers have probably been hearing more about Ruby than Lisp. ** (Functional Programming + Software Transactional Memory) = Multicore applications programmed by real humans. I am nominally a pointy-headed boss and I am already convinced. Stuart Halloway CEO Relevance, Inc. I'm doing an article for CIO.com on 5 [or whatever] languages that ought to be on your [IT Manager's] radar, and I'd like to include Clojure. I'm looking for a short statement on why it's useful, and why the boss ought to let you use it for enterprise work. Any takers? This is meant to be a short-and-sweet article: just its name, URL, a quick formal definition, and then one or two quotes from developers about why they think it's valuable. Imagine that you're trying to convince someone's boss to let you use it. What would you say? (This is a follow-up to http://www.cio.com/article/446829/PHP_JavaScript_Ruby_Perl_Python_and_Tcl_Today_The_State_of_the_Scripting_Universe in case you care. Some folks pointed out that a few obvious languages should have been included. I'm happy to comply.) --Esther Schindler senior online editor, CIO.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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
ANN: Clojure book
Hi all, I am working on what I hope will become the first Clojure book in print: http://www.pragprog.com/titles/shcloj/programming-clojure If you are interested in being a reviewer please let me know off-list. Regards, Stuart --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Dealing with keyword-keyed maps in Java land
Hi Paul, I think that I would rather see things remain explicit, i.e. if you need to interoperate with Java you convert manually before throwing the map over. In the Rails world they tried to solve a similar problem (string vs. symbol keys) by wrappering Hash to be indifferent between string and symbol keys, and it is still confusing. Now you have to remember whether you have the wrappered kind or not... Stuart Now that clojure maps are Java Maps, it is easier to inter-operate with Java code that has methods that take a Map as one of its arguments, because you can just pass the Map right into the Java code. The problem is that often times, the Java method is expecting the Map to have String values in the keys, definitely not clojure's Keywords. So if you have a {:foo 1} clojure map that you pass to a Java method, which then calls map.get(foo), you won't find that value. Does anyone have any suggestions for how to handle this? You could just use Strings for the keys in the clojure map, but then that map might not work with other clojure functions that expect the keys to be Keywords, not Strings. You could pass the map through a function that converts the Keywords to Strings before using it in Java, but I thought that was the whole point of making clojure maps implement Map, so I wouldn't have to do (jmap {:foo 1}) everytime I want to pass a Map to Java. I'm wondering if there is some way to make a clojure Map be smart enough to return the value even if you give it string. Probably not, because then what do you do with {:foo 1 foo 2}. Anyway, just wondering if anyone else has run into this Keyword/String mismatch problem and if you have an elegant 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: recur question
Hi Michael, The multiplication by n comes after the recur. Cheers, Stuart Giving the factorial function as: (def factorial (fn [n] (cond (= n 1) ( n 1) (* n (recur (dec n)) the compiler complains Can only recur from tail position. Isn't really the recur in tail position? It is the last expresson to be evaluated. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
are pr friends correct for regexps?
(prn #\\w+) - \w+ I was expecting something the reader could handle... Cheers, Stuart --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Nested Multimethods
Hi Patrick, How about: (defmulti length (fn [x] (if (= :stateMachine (:class x)) (:state x) (:class x (defmethod length :yardstick [x] 36) (defmethod length :walking [x] short) (defmethod length :running [x] long) user= (length {:class :yardstick}) 36 user= (length {:class :stateMachine :state :walking}) short user= (length {:class :stateMachine :state :running}) long It would probably be better to have the fn return a vector so you don't have to worry about :state and :class values with colliding names, but that's the basic idea. Cheers, Stuart Is there anyway to do the following with the existing multi-method facilities? There is a general multi-method length(object) that splits off to different methods depending on the :class of the object. And then specifically for objects with :class = :stateMachine, I want to define it's method to split off further depending on the :state of the object. (defmulti length :class) (defmethod-multi length :stateMachine :state) (defmethod length :stateMachine :walking (println Short distance)) (defmethod length :stateMachine :running (println Long distance)) Thanks very much for your help. -Patrick --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: are pr friends correct for regexps?
Yep, I was on an older build. Nevermind. :-) On Mon, Oct 13, 2008 at 9:06 AM, Stuart Halloway [EMAIL PROTECTED] wrote: (prn #\\w+) - \w+ Works for me, SVN 1067: user= #\\w+ #\\w+ user= (prn #\\w+) #\\w+ nil --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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: max
+1. And I like compact as a name (my Ruby is showing). Stuart OK. Then next question. Is there some reason we don't have a remove the nils function in the 'clojure namespace? Something like (filter #(identity %) coll) works, but would it be possible to add a 'squeeze or 'compact function so we could do something like (apply max (compact coll))? Paul On Thu, Oct 16, 2008 at 3:22 PM, Stuart Halloway [EMAIL PROTECTED] wrote: Hi Paul, I think the current behavior is reasonable. It is consistent across all the numeric functions. And if the nil got into max by being a sentinel value from some other function, I don't think there is a right way to interpret it. Stuart Currently, (max 1 2 nil 4) throws a NPE. Would it be reasonable to expect it to return 4? Or is it right that it throws an NPE? Paul --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: max
Just to add to the confusion: I want compact to remove nil and false. :-) Perhaps another nudge for compact is that it's not as simple as (filter identity coll), to wit: user (filter identity [1 2 nil false 4]) (1 2 4) user (filter #(not (nil? %)) [1 2 nil false 4]) (1 2 false 4) So unless you want to catch false in your net you really need to be doing the latter, which again is not unreasonable, but just a little messy to be using frequently. Paul --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
should (test ...) resolve symbols?
I was surprised to find that test does not resolve symbols into Vars: ; don't do this (test 'foo) - :no-test ; do this (test #'foo) - :ok Is there a conceptual reason that test should not resolve symbols into Vars? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Beginners (and idiomatic Clojure)
Hi Krukow, The quality will definitely be higher than this: http://blog.thinkrelevance.com/2008/9/16/pcl-clojure Same author, more time. :-) Stuart On Oct 20, 12:30 am, Paul Barry [EMAIL PROTECTED] wrote: Krukow, I agree, it would help to have a resource for learning Clojure. For now, my best advice is to pick a real project to start working and then specific questions in the IRC room, #clojure on irc.freenode.net. Within a few months, we'll have the beta book:http://www.pragprog.com/titles/shcloj/programming-clojure Wow, I wasn't expecting a book this early. Hope the quality will be as high as the other material on the web -- will definitely pre-order it. Thanks for the hint. /krukow --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
destructuring/multimethods vs. pattern matching
Hi all, I seem to recall Rich saying I like the destructuring part of pattern matching. In my efforts to appreciate that statement, I am playing around with porting simple Haskell examples to Clojure, trying to use destructuring (and multimethods) where the Haskell does pattern matches. For example: -- Haskell qsort [] = [] qsort (x:xs) = qsort smaller ++ [x] ++ qsort bigger where smaller = filter (x) xs bigger = filter (=x) xs ; Clojure, destructuring pivot and vals (defn quicksort-1 [[pivot vals]] (if pivot (let [smaller (partial filter #( % pivot)) bigger (partial filter #(= % pivot))] (lazy-cat (quicksort-1 (smaller vals)) [pivot] (quicksort-1 (bigger vals nil)) ; Clojure again, using multimethod to separate base and recur (defmulti quicksort-2 first) (defmethod quicksort-2 nil [_] nil) (defmethod quicksort-2 :default [[pivot vals]] (let [smaller (partial filter #( % pivot)) bigger (partial filter #(= % pivot))] (lazy-cat (quicksort-2 (smaller vals)) [pivot] (quicksort-2 (bigger vals) I am confident that the Clojure could be prettier, but not sure how. Suggestions? Cheers, Stuart --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: destructuring/multimethods vs. pattern matching
Hi Steve, Thanks! I like quicksort-4. It all fixes a problem that bugged me in all the other examples, which is that bigger is a lie. The real semantic is not smaller, which quicksort-4 captures perfectly. I will have to get used to thinking of remove as the opposite of filter. The English connotations of the former are too imperative for me, but I don't know a better word for it. Stuart On Oct 20, 2008, at 11:16 AM, Stuart Halloway wrote: Hi all, I seem to recall Rich saying I like the destructuring part of pattern matching. In my efforts to appreciate that statement, I am playing around with porting simple Haskell examples to Clojure, trying to use destructuring (and multimethods) where the Haskell does pattern matches. For example: -- Haskell qsort [] = [] qsort (x:xs) = qsort smaller ++ [x] ++ qsort bigger where smaller = filter (x) xs bigger = filter (=x) xs [...] I am confident that the Clojure could be prettier, but not sure how. Suggestions? Here are a couple of ideas: The first is a more literal translation of the Haskell code with 'when providing the nil case: (defn quicksort-3 [[x xs]] (when x (let [smaller (filter #( % x) xs) bigger (filter #(= % x) xs)] (lazy-cat (quicksort-3 smaller) [x] (quicksort-3 bigger) The second uses the filter/remove complementary pair so there's only one predicate: (defn quicksort-4 [[x xs]] (when x (let [smaller #( % x)] (lazy-cat (quicksort-4 (filter smaller xs)) [x] (quicksort-4 (remove smaller xs)) --Steve --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: destructuring/multimethods vs. pattern matching
Hi Achim, Nice--I like this one, except for needing to apply. What I really want is arity overloading *within* the first argument, which is what led me down the path to multimethods. Is there a reason to prefer concat over lazy-cat here? Cheers, Stuart Hi! Here's a variadic version: (defn qsort ([] []) ([x xs] (concat (apply qsort (filter #( % x) xs)) (cons x (apply qsort (filter #(= % x) xs)) user (qsort 1234 56 789 0) (0 56 789 1234) Kind regards, achim Am 20.10.2008 um 17:16 schrieb Stuart Halloway: Hi all, I seem to recall Rich saying I like the destructuring part of pattern matching. In my efforts to appreciate that statement, I am playing around with porting simple Haskell examples to Clojure, trying to use destructuring (and multimethods) where the Haskell does pattern matches. For example: -- Haskell qsort [] = [] qsort (x:xs) = qsort smaller ++ [x] ++ qsort bigger where smaller = filter (x) xs bigger = filter (=x) xs ; Clojure, destructuring pivot and vals (defn quicksort-1 [[pivot vals]] (if pivot (let [smaller (partial filter #( % pivot)) bigger (partial filter #(= % pivot))] (lazy-cat (quicksort-1 (smaller vals)) [pivot] (quicksort-1 (bigger vals nil)) ; Clojure again, using multimethod to separate base and recur (defmulti quicksort-2 first) (defmethod quicksort-2 nil [_] nil) (defmethod quicksort-2 :default [[pivot vals]] (let [smaller (partial filter #( % pivot)) bigger (partial filter #(= % pivot))] (lazy-cat (quicksort-2 (smaller vals)) [pivot] (quicksort-2 (bigger vals) I am confident that the Clojure could be prettier, but not sure how. Suggestions? Cheers, Stuart -- http://rauschabstand.twoday.net --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: destructuring/multimethods vs. pattern matching
What are your concerns re: apply? Are there performance issues? Or is it not being able to call qsort on a collection directly? I just want the code to look pretty, no deeper concerns than that. :-) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Beginners (and idiomatic Clojure)
Hi Krukow, The book will go electronic beta (60% complete) in early November, and should be available in print in March 2009. WRT to the case study, you are absolutely right. We will develop the Java and Clojure versions in parallel, so that neither one benefits unfairly from domain knowledge. We also have a pretty decent system for estimation, so we should get some real metrics of relative effort. Cheers, Stuart On Oct 20, 2:02 pm, Stuart Halloway [EMAIL PROTECTED] wrote: Hi Krukow, The quality will definitely be higher than this: http://blog.thinkrelevance.com/2008/9/16/pcl-clojure Same author, more time. :-) Stuart Hi Stuart, Sounds good - you have at least one buyer ;-) Will there be a pdf +hardcover option? I noticed your Clojure case study at Relevance -- nice initiative. I have a feeling the clojure version will be faster to develop, have fewer bugs, scale better and perhaps even perform better than the Java version. To be fair make sure you develop the versions in parallel so that experiences from building the Java version don't carry over to Clojure, or vice versa. /krukow --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: unit tests
Hi Tim, Example below. This is from a demo porting Java code to Clojure, the original Java code is in the Apache Commons [1]. Note that test does not resolve symbols: ; don't do this (test 'index-of-any) - :no-test ; do this (test #'index-of-any) - :ok Cheers, Stuart [1] http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/java/org/apache/commons/lang/StringUtils.java?view=markup -- (ns exploring.index-of-any (use clojure.contrib.seq-utils)) (defn #^{:test (fn [] (assert (nil? (index-of-any nil #{\a}))) (assert (nil? (index-of-any #{\a}))) (assert (nil? (index-of-any foo nil))) (assert (nil? (index-of-any foo #{}))) (assert (zero? (index-of-any zzabyycdxx #{\z \a}))) (assert (= 3 (index-of-any zzabyycdxx #{\b \y}))) (assert (nil? (index-of-any aba #{\z}} index-of-any [str chars] (some (fn [[idx char]] (and (get chars char) idx)) (indexed str))) I've noticed around the place a few hints at testing capabilities such as (test v) and contrib having a run tests, but I'm at a bit of a loss as to how it fits together. If there is a good example I can take a look at please point me toward it. Generally what I've been doing is writting a test case at the bottom of my function and commenting it out when I see the correct output. But if there is a more formal definition I'd prefer to use that. (defn poly-expand [points] (loop [aa (first points) remaining (rest points) built (empty points)] (if (empty? remaining) (concat built [aa (first points)]) (recur (first remaining) (rest remaining) (concat built [aa (first remaining)]) ;(pr (poly-expand '(a b c d))) ; - (a b b c c d d a) ie: lines of polygon connected I imagine what I should be doing is somehow attaching a :test metadata which checks that a given input equates to a given output, I just need an example to follow. Coming from an imperitive background, I have to say that unit testing seems to be one of the stand out advantages to the functional approach. I can't even begin to imagine how to represent test cases for the C/C++ projects I've worked on hahahahaha, but it just feels like a natural part of the development cycle in clojure which is really great. 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Testing Clojure (was Re: Bug? Strange set equality (r1075))
Since there is now a movement afoot to write a comprehensive test suite, I want to re-post the spike I did earlier on ClojureCheck. It would be cool to use check-style tests for at least part of the Clojure suite. If there is interest in this, I hope to have time to work on this in late November, or would be delighted if someone else picks up the idea and runs with it. Original message follows: --- At the JVM summit Clojure breakout someone suggested a Haskell QuickCheck/ScalaCheck library for Clojure. I am attaching a small spike in that direction below. A few questions: (1) Is anybody interested? (2) If the answer to (1) is yes, do you like the direction I am going in the public API, e.g. (for-all [x Integer y Integer] (some stuff that must be true)) (3) Any suggestions about implementation detail? (E.g. I like using a multimethod for arbitrary--is there a prettier syntax for ignoring the argument after using it for dispatch?) Cheers, Stuart ;;; clojure_check.clj: quick check framework for Clojure ;; Copyright (c) 2008 Stuart Halloway. All rights reserved. ;; Inspired by Scalacheck et al (http://code.google.com/p/scalacheck/) ;; Licensed under the same CPL as Clojure (http://clojure.org) ;; Uses clojure.contrib.test-is for assertions ;; ;; Example (passing) ;; (for-all [x Integer y Integer] (= (+ x y) (+ y x))) ;; ;; Example (failing) ;; (for-all [x Integer y Integer] (= (+ x y) (- y x))) (ns clojure-check (:import (java.util Random)) (:use clojure.contrib.test-is)) (defmulti arbitrary identity) (def random (Random.)) (defn collection-size [] (.nextInt random 100)) (def *check-count* 50) (defn choose [rng] (nth rng (.nextInt random (count rng (defmethod arbitrary Integer [_] (.nextInt random)) (defmethod arbitrary Character [_] (char (.nextInt random))) (defmethod arbitrary :ascii-character [_] (char (choose (range 32 128 (defmethod arbitrary String [_] (apply str (take (collection-size) (iterate (fn[_] (arbitrary Character)) nil (defmethod arbitrary :ascii-string [_] (apply str (take (collection-size) (iterate (fn[_] (arbitrary :ascii- character)) nil (defmacro binding-values [ vars] `(vector ~@(map (fn [v] `['~v ~v]) vars))) (defmacro for-all [args forms] (let [vars (take-nth 2 args) value-generators (map (fn [x] `(arbitrary ~x))(take-nth 2 (rest args)))] `(do ~@(map (fn [f] `(dotimes i# *check-count* (let ~(apply vector (interleave vars value-generators)) (is (true? ~f) (pr-str (binding-values [EMAIL PROTECTED])) forms --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: unit tests
Hi Tim, You have run afoul of the automagical conversion between Lispy - and Javaish _: ' sad (use 'clojure.contrib.test_is) java.lang.Exception: namespace 'clojure.contrib.test_is' not found after loading '/clojure/contrib/test_is/test_is.clj' (NO_SOURCE_FILE:0 ; happy user= (use 'clojure.contrib.test-is) nil Cheers, Stu (H) There's a simple unit testing library in clojure.contrib.test-is. Look at the source code comments there for examples of how you can define tests. Thanks Stuart S, I did a subversion grab of the source and well that looks extreemly useful. I'm a bit stuck on how to load test_is... I've added a tiny section to the wiki because I couldn't find any instructions on using contrib, and well I made a lot of mistakes along the way that other people might avoid: http://en.wikibooks.org/wiki/Clojure_Programming#clojure.contrib I think that it is set up correctly because I can use fcase, but can't use test_is. Maybe I don't need to explicitly or something, my brain is a bit fried atm please see below: user= (use 'clojure.contrib.fcase) nil user= (use 'clojure.contrib.test_is) java.lang.Exception: namespace 'clojure.contrib.test_is' not found after loading '/clojure/contrib/test_is/test_is.clj' --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Idiomatic Clojure code?
Chouser, I think I am missing something here, can you elaborate? By the way, difference is eager, so I'm not sure there's much point in using lazy-cat. :-) I am using lazy-cat *because* difference is eager. Is that mistaken? For example, the first expression below returns immediately, and the second does not. (take 1 (lazy-cat [1 2] [(Thread/sleep 1)])) (1) user= (lazy-cat [1 2] [(Thread/sleep 1)]) (1 2 nil) Stuart --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
troubleshooting classloader problems
Hi all, When I am troubleshooting classloader problems I find myself wanting to know the list of URLs currently on the classpath. I didn't find this exposed anywhere, so I wrote the functions below. Usage: (take 3 (classpath-url-seq)) - (file:/Users/stuart/relevance/personal/SHCLOJ_svn/Book/code/ file:/Users/stuart/repos/clojure-contrib/clojure-contrib.jar file:/Users/stuart/devtools/java/joda-time-1.5.2/joda- time-1.5.2.jar) Of course to be most helpful this needs to be in clojure.jar -- otherwise you might have classloader problems loading the classloader help code. :-) Not sure if this is general enough to deserve to be in clojure.jar, but you're welcome to it if others find it useful. Stuart ; --- (defn classloader-seq ([] (classloader-seq (clojure.lang.RT/baseLoader))) ([cl] (loop [loaders (vector cl)] (if (nil? (last loaders)) (drop-last loaders) (recur (conj loaders (.getParent (last loaders (defn classpath-url-seq [ args] (map (memfn toExternalForm) (reduce concat (map (memfn getURLs) (apply classloader-seq args) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: idiomatic Clojure for agents?
I have not looked at pmap yet, but I expect it will be a better fit, since Monte Carlo is a good fit for Fork/Join. I am considering using this example across a variety of implementation strategies for the concurrency chapter in the book. Aside from agents and pmap, any other approaches spring to mind? Stuart P.S. I think that is the second time you have had to tell me to stop using count as a local name. Bad habits die slowly... :-) On Mon, Oct 27, 2008 at 10:06 PM, Stuart Halloway [EMAIL PROTECTED] wrote: The code below implements a Monte Carlo simulation to estimate the value of pi. It works, and it was easy to reuse the original single- threaded approach across multiple agents. How idiomatic is this use of agents? Other than bringing in ForkJoin, are there other idiomatic ways to parallelize divide-and-conquer in Clojure? Did you look at pmap? You might be able to use something like (pmap (fn [_] (sample-for-pi count)) (range count)), and then use that in your guess-from-samples reduce. I'm thinking this might be better because it would handle more of the work: scaling to the number of CPUs, launching the agents, waiting for the results. I'm not sure it's a perfect fit -- perhaps pmap adds unneeded overhead. BTW, using count as a local name can cause surprises later when someone tries to use the clojure/count function. --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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: idiomatic Clojure for agents?
Hi Bill, Thanks, that's a good point re: await. It would also be interesting to have the agents run for a certain length of time, rather than a certain number of iterations. What do you think of using a map argument to a reduce fn? Idiomatic Clojure seems to prefer using a vector, but I am biased toward a map based on Ruby experience. I haven't decided which is more readable. Stuart Hi Stuart, On Mon, Oct 27, 2008 at 7:06 PM, Stuart Halloway [EMAIL PROTECTED] wrote: Hi all, The code below implements a Monte Carlo simulation to estimate the value of pi. It works, and it was easy to reuse the original single- threaded approach across multiple agents. How idiomatic is this use of agents? Other than bringing in ForkJoin, are there other idiomatic ways to parallelize divide-and-conquer in Clojure? Cheers, Stuart (defn in-circle? [[x y]] (= (Math/sqrt (+ (* x x) (* y y))) 1)) (defn random-point [] [(dec (rand 2)) (dec (rand 2))]) ; take samples, tracking number that land ; :in circle and :total number (defn sample-for-pi [count] (reduce (fn [{in :in total :total} point] {:in (if (in-circle? point) (inc in) in) :total (inc total)}) {:in 0 :total 0} (take count (repeatedly random-point (defn guess-from-samples [samples] (assoc samples :guess (/ (* 4.0 (:in samples)) (:total samples ; guess pi by running Monte Carlo simulation count times (defn guess-pi [count] (guess-from-samples (sample-for-pi count))) ; guess pi by running Monte Carlo simulation count times ; spread across n agents (defn guess-pi-agent [n count] (let [count (quot count n) agents (for [_ (range n)] (agent count))] (doseq a agents (send a sample-for-pi)) (apply await agents) (guess-from-samples (reduce (fn [a1 a2] {:in (+ (:in @a1) (:in @a2)) :total (+ (:total @a1) (:total @a2))}) agents I've not gotten around to playing with the concurrency features of Clojure yet, so I'm just commenting theoretically on your code. In guess-pi-agent, you use await to wait for the results from the agents. If one of the agents dies, won't your code wait forever? I would think that it would be preferable to use await-for (with a timeout) so that the result can still be guessed based on the samples that have come back from the other agents. If you plan to use a variation of this code in a multi-processor example, some degree of agent failure is even more likely. -- Bill Clementson --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: idiomatic Clojure for agents?
Java does thread protect, but it is synchronized. Also java.math and java.util's random number generator aren't pluggable with alternate implementations. For that I would need SecureRandom. For my simple example I think I will use a per-thread java.util.Random, note the issues, and point interested readers to the literature. This has me wondering: should Clojure's rand and rand-int default to use a thread-bound instance of java.util.Random? Stuart On Oct 27, 7:06 pm, Stuart Halloway [EMAIL PROTECTED] wrote: ; take samples, tracking number that land ; :in circle and :total number (defn sample-for-pi [count] (reduce (fn [{in :in total :total} point] {:in (if (in-circle? point) (inc in) in) :total (inc total)}) {:in 0 :total 0} (take count (repeatedly random-point You'll need to use a different pseudorandom number generator / pseudorandom stream for each thread. Otherwise adding more threads won't help performance much, because they will serialize on the PRNG. (Hopefully Java thread-protects the PRNG's state -- the C library doesn't, which makes for interesting errors ;-) .) Using Pthread mutexes to protect the thread state, in a C implementation of a Monte Carlo method on an 8-core 2-socket recent Intel box, I was only able to get 2x speedup. (For game tree search I can get 8x speedup on the same machine.) Check out the following parallel PRNG tutorial for more info: http://www.cs.berkeley.edu/~mhoemmen/cs194/Tutorials/prng.pdf 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
commutes do not trigger validate-fn?
Is this by design? It surprised me, as I expected all transactional updates to be protected by validate-fn. Stuart --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Using a Java Debugger with Clojure
Hi Luc, Do you have any special sauce for Spring/Clojure integration that the community might be interested in? Or is it just so easy that there is nothing to say? :-) Stuart Debugging presently with JSwat and it works fine. We have extensive logging (javalog) and use some trace macros from time to time. Of course you have to get acquainted with the internal Clojure representation as shown by the debugger but that's not a big learning curve. Presently we use a mix of Spring beans, Java and Clojure components. Luc On Tue, 2008-10-28 at 11:58 -0700, Scott Hickey wrote: It should work. Before I had a debugging working in Eclipse with Groovy, I used JSwat, JEdit and Ant for project work with success. Scott Hickey Senior Consultant Object Partners, Inc. - Original Message From: Bill Clementson [EMAIL PROTECTED] To: clojure@googlegroups.com Sent: Tuesday, October 28, 2008 1:43:58 PM Subject: Re: Using a Java Debugger with Clojure Hi Peter, On Tue, Oct 28, 2008 at 11:27 AM, Peter Wolf [EMAIL PROTECTED] wrote: Hello all, I am new to Clojure, but not Java or LISP (I used to work at LMI). I am considering a project written in a mixture of Clojure, Java and Groovy. Clojure for the concurrent inner loop. Groovy/Grails for the Web UI. And lots of Java reused from other projects. How would I debug something like this? Can I compile Clojure so that a standard Java debugger understands it? I don't know about Groovy, but some people have used standard Java debuggers to debug Clojure code. For example: 1. Read Rich's section on debugging in Getting Started: http://clojure.org/getting_started#toc5 2. Have a look at my blog post: http://bc.tech.coop/blog/081023.html 3. There was a recent discussion on this group where another individual had some problems getting JSwat working: http://groups.google.com/group/clojure/browse_thread/thread/403e593c86c2893f# 4. A general search for debugger on this group will also bring up some other relevant threads. Is there a better way? Better is subjective. ;-) You could use traditional lisp debugging techniques as well. I've covered some of these on my blog: http://bc.tech.coop/blog/040628.html Cheers, 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Documentation string in metadata?
Axel, The second function definition doesn't have a documentation string, it has a string form in its body. Valid behavior, but potentially confusing. Stuart the metadata for the second function definition doesn't contain the documentation string. I was wondering if this is valid behaviour or a bug? user (defn foobar foobar [] ()) user (:doc (meta #'foobar)) foobar user (defn foobar [] foobar ()) user (:doc (meta #'foobar)) nil Regards, Axel --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Ants and agents
Hi Jim, send-off is never immediate. It schedules a function for execution later. The call to send-off queues execution of the next evaporation, and the code continues on. Agents cannot do more than one thing at once, so the queued evaporation cannot possibly happen while this evaporation is sleeping. Stuart I was looking at the same code today. My question is slightly different. In the code (defn evaporation [x] (when running (send-off *agent* #'evaporation)) (evaporate) (. Thread (sleep evap-sleep-ms)) nil) it looks like the next request (when running (send-off...)) is sent immediately, the sleep happens after the evaporate and, more confusingly, happens after the next request is sent. Naively, it looks like you'd get an infinite number of send-off messages before the evaporate and the sleep happened. What am I misunderstanding? Jim -- Jim Menard, [EMAIL PROTECTED], [EMAIL PROTECTED] http://www.io.com/~jimm/ --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---