Re: Get digits of a number
Qiu Xiafei qiuxia...@gmail.com writes: (defn num-digits [num] (loop [n num res []] (if (zero? n) res (recur (long (/ n 10)) (cons (mod n 10) res) How about (quot n 10) instead of (long (/ n 10))? No sense in the extra step. David -- You 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: if-let/when-let
On Thu, Jan 03, 2013 at 11:14:30PM -0800, Evan Mezeske wrote: Wouldn't it be more accurately named if-and-let if it supported that? E.g. (if (and x y z) ...). I can see regular if-let being useful with more than one form, just using the last value for the conditional. (if-let [a expr, b expr] ii ee) could become (let [a expr, b expr] (if a ii ee)) Often, it is useful to have several intermediate results in a let: (if-let [subpart (complex-to-compute ...) part (other-expr subpart ... subpart)] ...) David On Thursday, January 3, 2013 10:24:57 PM UTC-8, Edward Tsech wrote: Hey guys, if-let and when-let macros support only 2 forms in binding vector: (if-let [x 1 y 2] ...) java.lang.IllegalArgumentExcepdtion: if-let requires exactly 2 forms in binding vector(NO_SOURCE_FILE:1) Why doesn't if-let support any even amount of binding forms as let does? e.g. (if-let [x 1 y 2 z 3] (+ x y z) 0) ; = 6 (if-let [x 1 y nil z 3] (+ x y z) 0) ; = 0 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 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 -- You 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: if-let/when-let
On Fri, Jan 04, 2013 at 08:58:40AM +0100, Tassilo Horn wrote: At least in my experience, it usually matters a lot which form actually evaluated to nil. But it's easy to write a macro `if-let-all' or so, which would expand into (let [x 1 y nil z 3] (if (and x y z) (+ x y z) 0)) if you really feel a need for it. Seems like it's be a lot more useful to expand that to: (let [x 1] (if x (let [y nil] (if y (let [z nil] (if z (+ x y z) else-clause)) else-clause)) else-clause)) With maybe a fn thrown in to avoid repeating the else-clause. This allows constructs where successive values need to be computed, that depend on the previous, and if we get a nil, we need to stop. It's especially useful when interfacing with Java code with things that really like to return nil on errors, and raise exceptions if you pass the nil to the next step. David -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Dependency management
On Thu, Jan 21, 2010 at 10:23:10PM -0800, Richard Newman wrote: I'm somewhat swayed by Leiningen because it makes doing some things easy (uberjar! starting a REPL! neat!), at the cost of making other things (such as managing dependencies myself) more frustrating. However, if it wasn't for all the people blindly deleting their Ant build scripts, I would be sticking with my Ant workflow for another few months. I don't think Lein is quite targeted at users like me.* For one project, I have a JNI that needs to be built as part of it. I tried converting this to Maven, and once I realized that I needed numerous fake subprojects to work around Maven's rigid flow model, I ended up going back to ant. I ended up making a fairly general ant script that I can drop into any project and build java/JNI/clojure source as needed. If anyone is interested, the code is at http://github.com/d3zd3z/webweight The build.xml is at the top, and the support files are under 'etc'. David -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: how to create instance of java class that is internal of other?
On Sat, Jan 16, 2010 at 03:30:49PM -0800, Sergey wrote: But how?:) Use a '$' character to delimit the internal class. ... (:import com.google.template.soy.SoyFileSet$Builder) ... ... (new SoyFileSet$Builder) ... That's the real class name. It's fairly easy to figure this out by looking at the names of the class files that the Java compiler generates. David -- You 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: Language similarities
On Fri, Jan 01, 2010 at 12:31:16PM -0500, Mike Meyer wrote: On Fri, 1 Jan 2010 13:45:43 -0300 Angel Java Lopez ajlopez2...@gmail.com wrote: I would like to add Ada exception management. I don't know if there were previous work on the field. Any info? I worked with Algol, but I don't remember if something like exceptions was present those days. Any early Lisp exception management? Try/Catch were add to MacLisp in 1972, because the previous error handling facilities (ERR/ERRSET) were being abused to get that behavior. This predates the formation of the Ada working group by a couple of years. I don't think I've ever seen any cross references between any of the Lisp documentation and any of the Ada documentation. The Ada rationale only references a couple of obscure papers about exceptions. Perhaps they didn't want to scare people by mentioning where they got the idea. I guess another concept that wasn't really accepted until a mainstream language started using it. David -- You 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: NPE in reify.
On Tue, Dec 29, 2009 at 01:58:45PM -0500, Rich Hickey wrote: (type (Small)) :user/Small You can use this keyword type tag for multimethod dispatch. I did eventually figure this out. I am a bit confused as to why you would want to reify a deftype. You can reify protocols, however. I need to make something that defines it's own Comparable, and I also want a custom printer for it. Once I figured out that the multimethod dispatch in the printer uses type, and I can just use that on the deftype name, it got much easier. Hopefully there isn't too painful a transition period moving from multimethods to protocols. Thanks, David -- You 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: Why use monads
On Mon, Dec 28, 2009 at 12:44:31PM +0100, Konrad Hinsen wrote: This fact is realized even in haskell community: http://lambda-the-ultimate.org/node/2749#comment-41078 That article is about monad transformers, not monads themselves. BTW, monad transformers are simpler in Clojure than they are in Haskell (they are ordinary functions), so some arguments in that thread don't apply to the same degree. Well, they still end up mostly as just functions in Haskell, with lots of extra wrapping and unwrapping to get the type system to work. The advantage in Haskell, is that 'lift' and friends (liftIO) figure out at compile time how many invocations are needed to get to the right monad. My biggest complaint about the monad transformers was that they make the program design fragile. Having to make small changes to what monads were used tended to have a pervasive effect on the rest of the code. Much of this had to do with type declarations, so this might not be as much of an issue with Clojure. David -- You 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: Access to nested static classes
On Mon, Dec 28, 2009 at 02:50:59PM -0800, Mark Tomko wrote: This, however, does not work: (ns org.tomko.konkordans.analysis (:import (org.tomko.konkordans NestedStatics))) (def foo NestedStatics$LevelOne$LevelTwo/NO) The class is called NestedStatics$LevelOne$LevelTwo, so you would have to import that if you wanted to use it. As far as the JVM is concerned, NestedStatics, NestedStatics$LevelOne and NestedStatics$LevelOne$LevelTwo are just three independent classes. Java added nested classes, but didn't really add them to the JVM. It just makes longer class names using the '$'. It's probably safe to rely on this behavior, since there is plenty of code that depends upon it working this way. David -- You 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
NPE in reify.
The following generates an NPE during compilation: (deftype Small []) (defn wrap [] (reify Small)) Obviously, my real use has more interfaces I implement, but this shows the problem. My problem is that I need to override 'print-method', which is using defmulti off of 'type' of it's argument. I guess I could also implement IMeta and provide a tag as well. But, the workaround I've been using is to create an empty interface in Java, which reify is happy to implement. David -- You 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: Parenthesis Inference
On Sun, Dec 20, 2009 at 02:30:58PM -0500, Luc Préfontaine wrote: People bought HP calculators not for the Postfix notation but for all the others things it offered at the time... Some of us _still_ only buy HP calculators because of the postfix notation. Oh, the other things are nice, too. David -- You 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: Code arrangement for understandability
On Thu, Dec 10, 2009 at 09:26:07AM -0500, Graham Fawcett wrote: (let [x 1 _ (f x) y (+ x 2) _ (g y)] ...) What do people in general think of this style? I remember using this trick a lot with O'Caml, and I've certainly used it a few times in Clojure, but something feels icky about it. Where it's most useful, though is with stuff like this: (let [x ... y ... _ (prn y is y) ...] ...) I have found I sometimes find something like: (let [x ... x (... x ...) x (... x ...) x (... x ...)] x) easier to write, even if it is just how I write it the first time, and then later change it to something looking more like function application. Sometimes, I've found the let-chain is easier to modify in the future. I guess, realizing it's still not imperative (necessarily), it shouldn't bother me as much. David -- You 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: Code arrangement for understandability
On Thu, Dec 10, 2009 at 09:13:33AM -0800, samppi wrote: notation before, and it is fine. For my tastes, however, I think that it repeats the symbol (in this case, 'x) too much. Sometimes it may be the best way, but usually I would instead use -, -, and/or letfn. The problem I have using - and - is that I often find inconsistency as to which argument the value should be placed at. David -- You 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: Trouble implementing Dijkstra algorithm in Clojure
On Tue, Dec 08, 2009 at 03:22:47PM -0800, ataggart wrote: I would be very surprised if getting the first element from a sorted- set wasn't ~O(1). As has been mentioned, it probably isn't if the set is a tree. But, also, usually, in addition to getting the first element, we also are going to want a set without the first element to represent the rest of the data. Both a sorted-set and a priority-queue are probably O(log n) for the first/rest operation, but the constant factor is likely to be quite different. David -- You 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: Generalizing - -
On Sat, Dec 05, 2009 at 01:38:36AM +0300, Ivan Sagalaev wrote: Cliff Wells wrote: I am unable to see why someone shouldn't be able to receive a signed PDF via email and achieve a similar level of confidence that the signor was legitimate. BTW Canonical does exactly that[1]. I've just recently signed their CCA which consisted of downloading a PDF from the site and sending it back to them with the words like I agree with this. It's going to depend a lot on who is interpreting the laws and what decisions they make. I've done contributor agreements via scanned documents and via fax. I don't think I've yet actually mailed one (although that may change if I contribute something to Clojure). David -- You 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: Space usage of lazy seqs
On Wed, Dec 02, 2009 at 08:18:33PM -0800, Dave M wrote: On Dec 2, 9:09 pm, David Brown cloj...@davidb.org wrote: ... If you're running JDK 6, you can run the virtualvm, or jconsole to get a better handle on the memory usage, and even dig into what it might used for. Google does not return useful references to a tool called virtualvm; perhaps you mean VisualVM (jvisualvm)? Yes, that is indeed what I meant to type. David -- You 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: Space usage of lazy seqs
On Wed, Dec 02, 2009 at 02:01:36PM -0800, Johann Hibschman wrote: There is a qualitative difference between the runs, though. I can run test-split-3 five times in a row, all with similar times, without having the java process size get bigger than 0.6 GB. When I run any of the others, the size quickly balloons up to something more like 8.5 GB. How much memory do you have on your machine. A recent Sun JVM on a machine with a bunch of memory will consider it to be a server machine. It will set the heap max to 1/4 of total physical memory (which suggests you might have 16GB of RAM). You can tune the max with -Xmx1G for example, to limit it to one GB. The actual interaction with the GC can be hard to predict, and Sun's GC seems to like to sometimes use as much memory as it has been given. If you're running JDK 6, you can run the virtualvm, or jconsole to get a better handle on the memory usage, and even dig into what it might used for. David -- You 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: Web application framework (beta)
On Sun, Nov 29, 2009 at 11:09:38PM -0500, Jim Powers wrote: Clearly what would be desired is portable continuations that can be loaded on any machine and/or duplicated/replicated for failure cases. All of the persistent classes in Clojure, including continuations claim to implement Serializable. Not sure how well it actually works, but if implemented, it should be possible to send a closure even to a different machine. David -- You 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
'sync' call in writeClassFile
This commit: commit 5577a47a390782d7ab911c2e3c4c8be1b0341aa8 Author: Rich Hickey richhic...@gmail.com Date: Sat Feb 7 14:46:56 2009 + added sync to writeClassFile Adds a 'sync()' call to the class file write. On systems where the underlying fsync() call causes a flush all the way to disk (Linux) this makes AOT compilation about an order of magnitude slower, especially given the large number of functions in typical clojure code. Anyone know the history behind this? It makes AOT compilation on Linux about 5x slower than on OSX. The call to sync() takes longer than the compilation did. It would be a win to just clean all of the class files and rebuild after a crash. The current behavior makes working off of battery on a laptop unworkable, since it keeps the harddisk from spinning down. These are just the output of the compiler, easily regenerated. David -- You 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: Space leak with lazy sequences.
On Fri, Nov 27, 2009 at 01:52:05PM +0200, Miron Brezuleanu wrote: not sure if it works here, but what about adapting advice from Stuart Halloway's Programming Clojure (pages 159-160, 'Losing your head') and use a function returning a sequence instead of a 'bound by let' name (the actual advice in the book is to use functions returning sequences instead of vars holding the head)? This is basically a delayed evaluation trick similar to your workaround with atoms. That seems to work as long as you aren't using the sequence as part of IO where the sequence is consumed in the middle. I think the atom trick is needed for my case as far as I can tell. David -- You 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: Space leak with lazy sequences.
On Thu, Nov 26, 2009 at 04:00:34PM -0800, David Brown wrote: For now, I'll do without the with-open, since in this particular case, errors are going to be fairly fatal anyway. BTW, I still haven't been able to figure out how to write this function without hanging onto the collection across the call to 'write-mapping'. Any ideas? ;; (ns leak1) (import '[java.io FileOutputStream BufferedOutputStream DataOutputStream]) (defn make-name [ _]) (defn make-tmp-name [ _]) (defn store-properties [ _]) (defn write-mapping [ _]) (defn get-codec [ _]) (defn raise[ _]) (def error nil) ;;; The generated code creates a 'fn' class for the body of the ;;; with-open. This class binds several of the names, including ;;; 'coll', which it keeps through the lifetime of the function. (defn- store-index-file [index idx props coll] (let [path (make-name index idx) tmp-path (make-tmp-name path) fos (FileOutputStream. tmp-path) bos (BufferedOutputStream. fos)] (with-open [dos (DataOutputStream. bos)] (store-properties dos (assoc props :version 1.0)) (write-mapping dos (get-codec index) coll) (.flush bos) ;; Calls fsync to make sure data gets written to disk. (.force (.getChannel fos) true)) (when-not (.renameTo tmp-path path) (raise error (str Unable to rename pool index file: tmp-path to path) ;; -- You 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: Space leak with lazy sequences.
On Thu, Nov 26, 2009 at 05:05:17PM -0800, David Brown wrote: On Thu, Nov 26, 2009 at 04:00:34PM -0800, David Brown wrote: For now, I'll do without the with-open, since in this particular case, errors are going to be fairly fatal anyway. BTW, I still haven't been able to figure out how to write this function without hanging onto the collection across the call to 'write-mapping'. Ugh, I have found a very ugly hack that works. It seems that the compiler only nulls out locals before a call in the tail position, even if earlier calls don't reference the value any more. So, I went down in my call-chain to the first function that uses the sequence directly (in a doseq), and do something like this: (let [real-coll @coll] (swap! coll (constantly nil)) (doseq [item real-coll] ...)) I just have to wrap the collection in an atom up where I create it, and make sure I never keep a reference to it around. David -- You 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: Recursions under lazy-seq - how does it work?
On Wed, Nov 25, 2009 at 09:40:44AM -0800, Gabi wrote: Very interesting indeed. I am not sure I understand completely, but by intuition I presume that the recursive call actually creates a new heap allocated LazySeq (with the function definition inside) . So is there some help from the compiler for this? How does the recursive call suddenly transfers into a call to a LazySeq object ? Actually, the compiler doesn't really do anything. lazy-seq is a macro, a very short one at that. I suggest making sure you have cloure.contrib.repl-utils available, and just try: (source lazy-seq) and see for yourselves. The only real compiler magic is that it sets the metadata {:once true} on the function it creates which makes for a bit better code for functions that will only ever be called once. But yeah, (defmacro lazy-seq ... [ body] (list 'new 'clojure.lang.LazySeq (list* '#^{:once true} fn* [] body))) That's it. The neat thing is that you or I can also write macros that do this kind of thing. It's one of the things that makes Lisp so powerful. David -- You 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 User Survey, preparation for 1.1
On Tue, Nov 24, 2009 at 01:04:57AM -0800, Meikel Brandmeyer wrote: Hi, On Nov 24, 9:44 am, bOR_ boris.sch...@gmail.com wrote: Can we get an option 'leiningen' at how do you get clojure? I think this is basically Maven/Ivy, no? Leiningen includes, within it's own Jar, a particular version of the clojure snapshot, which is why it currently only compiles against the one built into it. It uses Maven to download other dependencies, but not Clojure itself. David -- You 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: roll call of production use?
On Mon, Nov 23, 2009 at 03:00:16PM -0800, Raoul Duke wrote: i'd be interested to hear who has successfully used clojure in production. i know of some, as some folks have been vocal; any other interesting-but-so-far-silent uses people'd be willing to fess up about? I've thrown together a small clojure program to present an internal dashboard of active projects and states and stuff. Having the JVM was invaluable, since I could easily make postgreSQL queries as well as use JGit to walk the history of a git repository. I've mentioned this before, but http://github.com/d3zd3z/webweight is a small program I wrote to learn compojure. One significant part is that I've written an org.davidb.contrib.html and xml that wrap around the same data structure used by clojure.xml. It allows for easier construction of html/xml in code: (html/table :border 1 (html/tr (html/td :valign top Cell) ..)) I also wrote an html/xml emitter that uses ones from the standard Java libraries, since the one in clojure.xml doesn't actually generate valid xml. The other interesting part of webweight is that the build.xml and the ivy and files under etc are sufficient to build most Clojure projects. It's similar to the idea behind Leiningen, but it will also build Java and native code into the project as well. The production webpage is internal, and has a lot more data on it, but I've captured and scrubbed a snapshot http://www.davidb.org/dashboard/sample.html I was able to throw the whole thing together in just a couple of days using Clojure. I haven't really felt this productive writing code since using Common Lisp. David -- You 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 User Survey, preparation for 1.1
On Mon, Nov 23, 2009 at 09:55:46PM +, the.stuart.sie...@gmail.com wrote: Since the form only lets me answer one answer for each, but reality is much more complicated. How do you get Clojure? * Download release Github Maven or Ivy I primarily use the latest development snapshot that I pull down with Maven/Ivy. But, I also keep a git workspace and bounce between master and new. As far as chunked sequences, I started using clojure after they were already in place, so I don't really have anything to compare it with. David -- You 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: leiningen - a Clojure build tool
On Sun, Nov 22, 2009 at 01:05:43AM -0800, bOR_ wrote: elif [ ${1: -4} = .clj ]; then # Small hack to use lein to start clojure scripts java -cp $CLASSPATH clojure.main $1 How about elif [ ${1: -4} = .clj ]; then # Small hack to use lein to start clojure scripts java -cp $CLASSPATH clojure.main $@ So you can even pass arguments to the script. BTW, the leiningen.core invocation at the end should also be $@ so that arguments with spaces don't get expanded into multiple arguments. If you add arguments to the 'repl' case, then you can run scripts using that as well. David -- You 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: leiningen - a Clojure build tool
On Sun, Nov 22, 2009 at 07:14:33AM -0800, bOR_ wrote: What is the normal way to let Leiningen know about local jars? I am using brics automaton in one of my projects, and that jar is only downloadable after confirming the bsd licence (http://www.brics.dk/ automaton/), so I have it locally on my disk, but it isn't in clojars or mvnrepositiory.com. When the maven fails to find the package, it will spew out instructions on how to install it into your local maven cache. Something like: mvn install:install-file -DgroupId=org.domain -DartifactId=package -Dversion=1.2.3 -Dpackaging=jar -Dfile=path/to/file.jar But, on one line. Having to agree with a BSD license is a bit strange. David -- You 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: Oh, yeah, transients are fast!
On Sun, Nov 22, 2009 at 11:45:46AM -0500, John Harrop wrote: Nothing so serious as a hang, though, and at least I can do basic things in my IDE without reaching for the frelling manual every two minutes to look up some key-combination :) I suspect both models are going to be important. I feel the same way you do when I'm running an IDE rather than vim. Oddly enough, I've found myself most productive with a repl in it's own window, and a short script (below) in user.clj to let me specify a namespace to test. I put this in a 'repl' directory that I only add to my classpath for the repl script. David (println Running user startup) (use 'clojure.contrib.repl-utils) (use 'clojure.contrib.str-utils) (use 'clojure.contrib.java-utils) (use 'clojure.contrib.def) (use 'clojure.contrib.ns-utils) (use 'clojure.contrib.test-is) (use 'clojure.contrib.sql) (use 'clojure.stacktrace) (set! *warn-on-reflection* true) ;;; The NS that we are testing/working on. ;;; This can be given through the java property work-ns, e.g. ;;; ./run.sh -Dwork-ns=org.davidb.chunk-file (def *work-ns* (symbol (or (System/getProperty work-ns) 'org.davidb.foo))) ;;; A testing NS. (def *test-ns* (symbol (or (System/getProperty test-ns) (symbol (re-sub #[^\.]+$ #(str test- %) (name *work-ns*)) ; (use *work-ns*) (defn l [] (binding [*warn-on-reflection* true] (use *work-ns* :reload))) (defn t [] (binding [*warn-on-reflection* true] (require *test-ns* :reload) (run-tests *test-ns*))) (defn i [] (in-ns *work-ns*)) ; Load the User's test-user.clj if present. (try (load /test-user) (catch java.io.FileNotFoundException e (println No test-user.clj found in classpath.))) -- You 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
How to make this a non-reflecting call?
java.nio.channels.FileChannel contains some .write methods: [27] write : int (ByteBuffer) [28] write : int (ByteBuffer,long) [29] write : long (ByteBuffer[]) [30] write : long (ByteBuffer[],int,int) I have an array of ByteBufers, but I can't figure out how to call #29 without it being a reflecting call. Giving a type of #^objects doesn't seem to help. (defn foo [#^FileChannel chan, bufs] (.write chan (to-array bufs))) gives a reflection warning. Any ideas? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: How to make this a non-reflecting call?
On Sun, Nov 22, 2009 at 01:00:51PM -0500, John Harrop wrote: On Sun, Nov 22, 2009 at 12:55 PM, David Brown cloj...@davidb.org wrote: java.nio.channels.FileChannel contains some .write methods: [27] write : int (ByteBuffer) [28] write : int (ByteBuffer,long) [29] write : long (ByteBuffer[]) [30] write : long (ByteBuffer[],int,int) I have an array of ByteBufers, but I can't figure out how to call #29 without it being a reflecting call. Giving a type of #^objects doesn't seem to help. (defn foo [#^FileChannel chan, bufs] (.write chan (to-array bufs))) gives a reflection warning. Any ideas? Try #^[LByteBuffer; That doesn't parse. I did get it to work with reflection, by using (into-array ByteBuffer bufs) instead of to-array. That way I at least get the right array type, even if the compiler can't figure it out. Any idea what kind of performance hit this actually ends up being? David -- You 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: tree-shaking a jarred Clojure app?
On Fri, Nov 20, 2009 at 06:37:18PM +, Jim Downing wrote: I might have misunderstood, but isn't the problem the same as in Java; you can't know from a static analysis which classes are going to be loaded? Except that Clojure will load all of them so it can bind them to the vars in each namespace. Java code is usually much less dynamic, and makes some static analysis a lot easier. JVMs are pretty good about not loading classes until they are used, so I think the real problem is that the init code for each namespace loads all of the classes before it does anything. If that could be delayed, I suspect most of the startup delay would go away. The trick is figuring out how to do this without adding yet another level of indirection to vars. David -- You 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: Weird Java Interop Behaviour
On Fri, Nov 20, 2009 at 03:54:45PM -0800, Mike Hinchey wrote: It's the . special form that makes the difference. In (. System (getProperty)), the dot interprets System as a class and looks for a static method (at read/compile time). With (identity System), System resolves to a value, a Class object, returned by identity, then your outside dot looks for a getProperty instance method on that object(fallback to reflection, which fails) - it's like writing System.class.getProperty in java. There is no syntax for clojure to lookup a static method on a dynamically resolved class object because that is inherently reflection - dot is not about reflection, though it will do it as a last resort. So, if I've acquired a dynamically resolved class and want to invoke a static method, is my only choice to manually use reflection? David -- You 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: tree-shaking a jarred Clojure app?
On Sat, Nov 21, 2009 at 08:42:26PM -0500, John Harrop wrote: Are you talking about binding things like String.class to vars referenced by symbols like String? Not just String.class, every single class referenced by a given namespace will be loaded, and most of them instantiated before a single line of my code runs. It's why: $ time ant ... (no ant file, it just fails) real 0m0.155s $ time clj -e '(System/exit 0)' real 0m0.960s is so drastically different. Compiling this: (ns foo (:gen-class)) (defn -main []) and running $ time java -cp classes:clojure.jar foo real 0m0.749s still loads and instantiates every single function defined in core.clj. David -- You 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: tree-shaking a jarred Clojure app?
On Sat, Nov 21, 2009 at 11:14:52PM -0500, John Harrop wrote: 1 second instead of 1/6 of a second. Yeah, like users will notice that difference in startup times. :) I'm not actually complaining, but I do notice every single time I fire up a REPL. The more code that you have, the longer it takes. It's basically completely thwarting the JVM's attempt to lazily load classes. I have the same complaint about JRuby and Scala. Scala cheats a little, and their REPL prints a prompt before actually loading the classes. Honestly, I think it's a reasonable penalty to pay for a system that is both dynamic and very fast. David -- You 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.xml/parse of XHTML yields a 503 on the DTD
On Tue, Nov 17, 2009 at 10:12:19AM -0800, David Brown wrote: On Tue, Nov 17, 2009 at 08:03:59AM -0800, pkw wrote: I'm having this same problem. Did you find a way around it? I want to try changing the User-Agent, but I can't figure out how to do that. I suspect that the Sax parser by default is configured to not allow fetching of the DTD over the net. I worked around this by replacing the URL in the DOCTYPE declaration with a file one and fetching the files myself. But, admittedly that's not a good solution. BTW, the emitter in clojure.xml doesn't produce valid xml, either, unless your xml is very simple. It certainly doesn't work round-trip. David -- You 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: Proposal: Extend behavior of hash-map
On Tue, Nov 17, 2009 at 03:24:46PM -0800, Richard Newman wrote: Baby, bathwater. Making a persistent map out of a Java map is expensive. Not everything that implements Map is concrete; e.g., spending several seconds making a local persistent Clojure map out of a distributed hash table proxy, just to get a value, would cause programmers to drop down to Java to avoid this pointless restriction. Why bother? I wonder if there's a use for a lazy 'bean' call, then. Lots of things use bean properties to do things that can be quite expensive. David -- You 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.xml/parse of XHTML yields a 503 on the DTD
On Tue, Nov 17, 2009 at 08:03:59AM -0800, pkw wrote: I'm having this same problem. Did you find a way around it? I want to try changing the User-Agent, but I can't figure out how to do that. I suspect that the Sax parser by default is configured to not allow fetching of the DTD over the net. I worked around this by replacing the URL in the DOCTYPE declaration with a file one and fetching the files myself. But, admittedly that's not a good solution. David -- You 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: idomatic sudoku?
On Sun, Nov 15, 2009 at 09:43:38PM +0100, B Smith-Mannschott wrote: On Sun, Oct 11, 2009 at 22:12, Matt Wilson m...@problemattic.net wrote: The only hassle with a map is that iterating over it (in my case, with a `for`) turns it into a list of [key value], which makes it a pain to turn back into a map once you're done. The magical incantation for round-tripping turns out to be: (apply hash-map (apply concat seq-of-pairs)) Why not just (into {} seq-of-pairs) David -- You 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: Datatypes and Protocols - early experience program
On Sun, Nov 15, 2009 at 04:20:19PM -0500, John Harrop wrote: That's weird. It's not documented anywhere on the site. And it seems to hang the REPL: user= nil #!foo and nothing. Enter doesn't print nil and a fresh user= prompt as it should and nothing else apparently works either. The REPL is either wedged or interpreting everything as comment from then on. Weirdly enough, ; hangs the REPL likewise. How's the data getting to the REPL? jline, or ide? I'm using rlwrap at the console, and netierh seems to cause problems. However, #! eats everything, and doesn't prompt again, but does after the next line. The ; prints a new prompt, so they are definitely treated differently. David -- You 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 Web Libraries
On Jan 21, 4:39 pm, Frank ffai...@gmail.com wrote: I am interested in trying to use Clojure to develop web-based applications. Can someone point me to any Clojure libraries that have been written that I can use. Thanks. I spent a couple of days this week using Compojure both in anger, and for fun. The anger stuff isn't source-available, but my fun project is: http://github.com/d3zd3z/webweight There is (hopefully) a live version at: http://www.davidb.org/wlog? The app itself probably isn't that interesting itself, since it generates the reports for my weight management program. Part of my goal was to be well integrated with Maven, but also have decent interactive use. - setup-repl.sh uses Maven to download the dependencies and put them in a place that 'run.sh' is expecting them. Combined with the user.clj I wrote, it allows me to do things like: ./run.sh -Dwork-ns=org.davidb.webweight.daily and get a REPL where (l) will reload this namespace, (t) will load one with the name of org.davidb.webweight.test_daily and run tests on it (there aren't tests in this code yet), and (i) will switch to the dev namespace. It doesn't reload sub-required namespaces, so isn't perfect, but still quite useful. - mvn compile should work with the maven-clojure-plugin. It'll also package a jar file. - mvn assembly:assembly will make a jarfile containing the dependents. There's a org.davidb.webweight.main that can run it directly. All in all, it's a fairly quick framework to setup. My github page also has my patches to compojure to build it under Maven. The json library is from Tim Dysinger's repo: git://github.com/dysinger/clojure-json.git. I just installed these locally. The in anger project connects to a PostgreSQL database and interacts with a backend auto-build system. David -- You 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 vim shebang
On Thu, Nov 12, 2009 at 10:21:32AM +1100, John Ky wrote: Does anyone know why if the first character in my *.clj file is '#', then when I open it in VIM, ClojureVIM fails to recognise it as a Clojure file? Vim runs the type detectors that examine the file before the ones based on filename. The vimclojure name-based autodetector uses 'setfiletype' which only sets the filetype if it hasn't been detected already. The simplest fix is to change the 'setfiletype' in the ftdetect/clojure.vim file to 'filetype'. This tells it to force the filetype to clojure when it ends in '.clj' no matter what it was detected as. You can also make line 2 of the file be something like: ; vim: set filetype=clojure : and just override it on an individual basis. David -- You 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
vimclojure indentation problem.
Speaking of vimclojure, has anyone else encountered situations where the vimclojure indent decides that the indentation of top-level constructs should be two spaces over? I haven't been able to figure out a pattern, and sometimes I can even fix it by just scrolling up and back. David -- You 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: Problem w/ daemon threads
On Thu, Nov 12, 2009 at 07:50:31AM -0800, Sean Devlin wrote: (defn daemon Creates a new daemon thread and sets runnable to f [f] (let [t (Thread. f)] (do (.setDaemon t true) (.start t) t))) And I tried calling user=(daemon #(println foo)) I get the thread back, but it does not appear to execute. I've tried this on OSX and XP. Does anyone know what I'm doing wrong? I tried this on Linux, and prints foo once, which is what I would expect. If you want it to be period, though, you'll need to use something like Executors/newSingleThreadScheduledExecutor to create a scheduler for it. I tried writing a periodic scheduler using agents (and a ref to manage state). Turns out that getting shutdown working robustly is actually fairly tricky. I recommend just using the scheduler available in Java. David -- You 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: Using agents and blocking I/O.
On Tue, Nov 10, 2009 at 07:41:41AM -0800, pmf wrote: This thing could easily create a lazy sequence, in fact, the code would look a lot like the code for seque, with just a separation of the writer from the reader. I'll have to think about it to make sure that it can be used safely. You might want to look at the (recently added) fill-queue (in clojure.contrib.seq-utils), which provides a lazy seq that is filled by another thread and blocks if readers consume faster than the queue is filled; maybe your problem fits into this mechanism. Well, almost. Except that it would create a future that I really don't have any use for. Last night, I posted very similar code to do the same kind of thing with an agent (I have since fixed the exception handling in the agent so it terminates the queue so the reader will get an exception rather than just hang). With fill-queue, send-queued, and seque all looking nearly identical, I wonder if we're missing how this should be abstracted. I did learn, though from reading it that seque stops short if the computation runs ahead enough to fill up the queue. I'm not quite sure what this would be useful for. (import '(java.util.concurrent BlockingQueue LinkedBlockingQueue)) (defn send-queued Dispatch blocking action to agent. The state of the agent will be set to the value of: (apply action-fn state-of-agent enqueue args) The agent should call enqueue for each item to return to the caller of send-queued. send-queued returns a lazy sequence of the items the agent passes to enqueue (in order). The agent may enqueue 'n' items before blocking on its call to enqueue. [a n f args] (let [#^BlockingQueue q (LinkedBlockingQueue. (int n)) NIL (Object.) ;nil sentinel since LBQ doesn't support nils enqueue (fn [x] (.put q (if (nil? x) NIL x))) action (fn [state1] (try (let [state2 (apply f state1 enqueue args)] (.put q q) ; q itself is eos sentinel state2) (catch Exception e (.put q q) (throw e drain (fn drain [] (lazy-seq (let [x (.take q)] (if (identical? x q) ;q itself is eos sentinel (do @a nil) ;touch agent just to propagate errors (cons (if (identical? x NIL) nil x) (drain))] (send-off a action) (drain))) -- You 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: Better documentation and error messages are needed for the ns macro
On Tue, Nov 10, 2009 at 09:08:31PM -0500, John Harrop wrote: In case anyone was wondering, apparently it wants (ns foo.bar.baz (:use [clojure.contrib.core :only (seqable?)])) (and thus violates the usual clojure rule of using vectors rather than lists for groupings that are not invocations -- that is, function calls, macro calls, or special form calls). You can use vectors for everything other than the outside parens, if you'd like. They just need to be sequences. I'm guessing people usually use parens on the :use, because it at least looks like an invocation (and is similar to the (use ...) call). I've seen the :only followed by a vector. David -- You 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
Iterative collections.
Given the recent talk about iter and how most of the expressions can be done easily with sequences and map. I however, have found that map often makes these difficult to read because the names are up front in the function and the arguments follow this. So, I threw together the following macro that allows map of an anonymous function to be written more in the style of 'let'. If it isn't obvious, the bindings can be destructuring. (defmacro let-map Evaluates the exprs, each of which should return a sequence. These are bound to the binding forms for subsequent calls, and the results of the last expression in body are collected into a sequence. [bindings body] (assert (vector? bindings)) (assert (even? (count bindings))) (let [pairs (partition 2 bindings) bs (map first pairs) exprs (map second pairs)] `(map (fn [...@bs] ~...@body) ~...@exprs))) For evaluating to cause side-effects, you can do (dorun (let-map ...)), but I may also write a 'let-seq' that implements this using recur to avoid the allocation of the sequence. (let-map [x [31 41 59 26] y (iterate inc 1)] (+ x y)) Probably not that interesting in the simple case. David --~--~-~--~~~---~--~~ You 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: equivalent to Haskell's group function
On Mon, Nov 09, 2009 at 04:49:16PM +, Emeka wrote: What is the gain of using lazy-seq here? Why can't we go without laziness? - The lazy version doesn't consume stack per length of the sequence. - The lazy version works with unbounded sequences. For short sequences it probably doesn't matter much, but these are also probably the cases where performance isn't as much of a concern. David --~--~-~--~~~---~--~~ You 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: Iterative collections.
On Mon, Nov 09, 2009 at 09:07:31AM -0800, pmf wrote: On Nov 9, 5:39 pm, David Brown cloj...@davidb.org wrote: (let-map [x [31 41 59 26] y (iterate inc 1)] (+ x y)) Probably not that interesting in the simple case. How is this different from using for? It's also lazy and supports destructuring. (for [x [31 41 59 26] y (iterate inc 1)] (+ x y)) And gives very different results. 'for' iterates over it's sequences in a nested fasion. For your particular example, it will return the sequence from (+ 31 1) (+ 31 2) and so on, and never get to the second element of the first vector. 'let-map' walks through the sequences together, like 'map', hence the name. The given 'let-map' example returns a sequence of 4 elements. David --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to convert java Complex type to Clojure type?
On Mon, Nov 09, 2009 at 11:42:32PM +0100, Michael Jaaka wrote: How to convert HashMapString, String to Clojure map, sorted-map, tree-map (into {} hm) or (into (sorted-map) hm) where hm is the hash map. You can also just use the hash map like you would a Clojure map, but it might change on you, since it is mutable. David --~--~-~--~~~---~--~~ You 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: Consistency of the API
On Mon, Nov 09, 2009 at 08:41:25PM -0500, John Harrop wrote: In the meantime, the main thing still missing from Clojure is a convenient queue. Lists and vectors both add and remove efficiently only at one end, and at the same end for add and remove in both cases. Doubly-linked lists can't be made persistent without massive problems, but laziness has its own issues: Perhaps the GHC Data.Sequence library could be ported. It's based on 2-3 finger trees, and allows efficient adding and removal from either end of the sequence. Depending on use behavior, you can also make a decent lazy queue just out a two lists, where you reverse and append whenever the source side fills up. David --~--~-~--~~~---~--~~ You 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: Consistency of the API
On Mon, Nov 09, 2009 at 05:53:28PM -0800, Mark Engelberg wrote: On Mon, Nov 9, 2009 at 5:41 PM, John Harrop jharrop...@gmail.com wrote: In the meantime, the main thing still missing from Clojure is a convenient queue. What's wrong with clojure.lang.PersistentQueue? The only clojure constructor I could find for this is in clojure.contrib.accumulators. But, once you have the empty one 'clojure.lang.PersistentQueue/EMPTY' you can use it pretty well with the rest of the language. Perhaps 'empty-queue' should be moved into core? David --~--~-~--~~~---~--~~ You 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: Consistency of the API
On Mon, Nov 09, 2009 at 05:54:36PM -0800, David Brown wrote: Depending on use behavior, you can also make a decent lazy queue just out a two lists, where you reverse and append whenever the source side fills up. Ok, this is what PersistentQueue is, except without the reverse and append, so it actually performs well. David --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~---
Using agents and blocking I/O.
I'm trying to get a better grasp of how Agents are intended to be used, so let me give an example scenario. Let's say I have some thing that keeps track of the state of some I/O entity, let's say some kind of file-based storage. There is state associated with the entity. It's important that only one thread be able to read or write from this storage at a time, since the state has to match what the external store's state is (say it's a cache or something). Write requests seems like a perfect match for agents, since they will be serialized and will happen asynchronously. But, what about reads. The reader needs to be able to get the result back from the read, how to do this. I can think of a few ways: - The reader passes in an atom to hold the result. After issuing the request, awaits for the agent to process the request, and then retrieves the answer from the agent. - It could use a BlockingQueue of some type to wait for the answer. In both cases, the reads run completely synchronously, waiting for their answer, and really the whole thing isn't really any better than just using locks. Or, should I rethink the whole thing, and try to represent my entire problem reactively? The essentially means converting my entire problem in to continuation-passing style, and giving some of the continuations to agents. Possible, but very pervasive. Any suggestions? Thanks, David --~--~-~--~~~---~--~~ You 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: Using agents and blocking I/O.
On Mon, Nov 09, 2009 at 08:28:43PM -0800, David Brown wrote: In both cases, the reads run completely synchronously, waiting for their answer, and really the whole thing isn't really any better than just using locks. I guess a deeper concern is that there seems to only be a single call in the entire Clojure concurrency system: 'await'. One very useful extension GHC adds to STM is the 'retry' call, which causes the transaction to retry, but it blocks until something else modifies one of the refs that it has read. It allows any arbitrary concurrency to be implemented, since now a thread can wait for a result, for example. Should I just be less afraid of using the Java concurrency classes? David --~--~-~--~~~---~--~~ You 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: Vector manipulation problem, possible function for a solution.
On Mon, Nov 09, 2009 at 05:19:41PM -0800, Don wrote: I am having a problem with vectors. It seems there should be a function for this however I am not sure. I have a vector a [ [2 3] [4 5] [6 7] ] And I want to be able to get [2 3 4 5 6 7] There's a flatten in clojure.contrib.seq-utils that does this. Well, it gives you a sequence when you can put back into a vector if you need. David --~--~-~--~~~---~--~~ You 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: Using agents and blocking I/O.
On Mon, Nov 09, 2009 at 09:42:28PM -0800, Mark Engelberg wrote: But let's say the agent is responsible some enormous database, and it's impractical for the in-memory state to hold all the information that readers might find useful. In this case, I think you're right that the basic agent functionality doesn't map well to this without some additional work. It seems like you would need to create a read message which essentially is a function that reads the relevant data from the database and stores it in some sort of future-like stateful entity that will block when you deref it until it has been filled by the agent. Ok. So, it's the existence of this future-like entity that blocks upon deref until filled is indeed somewhat missing. It's not particularly difficult to implement. This thing could easily create a lazy sequence, in fact, the code would look a lot like the code for seque, with just a separation of the writer from the reader. I'll have to think about it to make sure that it can be used safely. Making it a full queue unstead of just an event handles the common case where I will have a sequence of reads to make. Thanks, David --~--~-~--~~~---~--~~ You 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: Using agents and blocking I/O.
On Mon, Nov 09, 2009 at 10:07:41PM -0800, David Brown wrote: On Mon, Nov 09, 2009 at 09:42:28PM -0800, Mark Engelberg wrote: But let's say the agent is responsible some enormous database, and it's impractical for the in-memory state to hold all the information that readers might find useful. In this case, I think you're right that the basic agent functionality doesn't map well to this without some additional work. It seems like you would need to create a read message which essentially is a function that reads the relevant data from the database and stores it in some sort of future-like stateful entity that will block when you deref it until it has been filled by the agent. Making it a full queue unstead of just an event handles the common case where I will have a sequence of reads to make. Ok, here's my first attempt. It seems to work. It's basically like send-off, except that it wants a queue size, and it returns a lazy sequence. It passes an extra argument to the agent function that the agent should call with each item it wishes to queue. This is largely modelled after seque from core. (import '(java.util.concurrent BlockingQueue LinkedBlockingQueue)) (defn send-queued Dispatch blocking action to agent. The state of the agent will be set to the value of: (apply action-fn state-of-agent enqueue args) The agent should call enqueue for each item to return to the caller of send-queued. send-queued returns a lazy sequence of the items the agent passes to enqueue (in order). The agent may enqueue 'n' items before blocking on its call to enqueue. [a n f args] (let [#^BlockingQueue q (LinkedBlockingQueue. (int n)) NIL (Object.) ;nil sentinel since LBQ doesn't support nils enqueue (fn [x] (.put q (if (nil? x) NIL x))) action (fn [state1] (let [state2 (apply f state1 enqueue args)] (.put q q) ; q itself is eos sentinel state2)) drain (fn drain [] (lazy-seq (let [x (.take q)] (if (identical? x q) ;q itself is eos sentinel (do @a nil) ;touch agent just to propagate errors (cons (if (identical? x NIL) nil x) (drain))] (send-off a action) (drain))) David --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~---
Avoiding reflection/hinting with byte-array.
I can't figure out how to avoid reflection, in the 'update' method of MessageDigest. It is overloaded on a single argument with either 'byte', 'byte[]', or 'java.nio.ByteBuffer'. (import '(java.security MessageDigest)) (set! *warn-on-reflection* true) The compiler didn't seem to like a tag that wasn't actually a class name: (def byte-array-class (class (make-array Byte/TYPE 0))) ;; Unable to resolve classname: byte-array-class (defn update1 [#^MessageDigest md #^{:tag byte-array-class} item] (.update md item)) And it seems to have no effect if I expand it as the tag: ;; call to update can't be resolved. (defn update2 [#^MessageDigest md #^{:tag (class (make-array Byte/TYPE 0))} item] (.update md item)) In this particular case, I was able to work around the issue one of two ways, basically by using a different type. (defn workaround [#^MessageDigest md item] (.update md item 0 (count item))) (defn workaround2 [#^MessageDigest md item] (.update md (java.nio.ByteBuffer/wrap item))) Any ideas? BTW, my real use case is in a defmethod, where I handle several other types for the update. Thanks, David --~--~-~--~~~---~--~~ You 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: Avoiding reflection/hinting with byte-array.
On Sat, Nov 07, 2009 at 11:48:32AM -0500, Chouser wrote: This should work: (defn update1 [#^MessageDigest md, #^bytes item] (.update md item)) This does seem to work, thanks. Any reason that 'doubles' is also defined as an array cast function, but 'bytes' is not? David --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~---