using custom zippers from clojure.zip
Hello everybody, I am trying to figure out how to use the zippers. And I wrote the following code https://gist.github.com/1172883 It seems to get in-to an infinite loop ..can somebody help me figure it out. The purpose of the last s-expression is to simply return a new s where all the values stored in :val is incremented by one. The reason that the branch? function is (constantly true) is because it is asked to return true for any node that can be potentially a branch whether it has any children or not. As you can notice, each node has 3 fields ( :val :l (left) :r (right) ) . The children function is simply returning the non-nil sequence of nodes at :l and :r. Hoping somebody can help me with this. Thanks, Sunil. -- You 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 custom zippers from clojure.zip
as it always happens.. I figured the problem as soon as I posted it . I just had to replace the branch? function from (constantly true) with identity . The problem was it was treating even nil values as valid nodes and hence getting into an infinite loop. Sorry for this. Thanks again, Sunil. On Fri, Aug 26, 2011 at 12:52 PM, Sunil S Nandihalli sunil.nandiha...@gmail.com wrote: Hello everybody, I am trying to figure out how to use the zippers. And I wrote the following code https://gist.github.com/1172883 It seems to get in-to an infinite loop ..can somebody help me figure it out. The purpose of the last s-expression is to simply return a new s where all the values stored in :val is incremented by one. The reason that the branch? function is (constantly true) is because it is asked to return true for any node that can be potentially a branch whether it has any children or not. As you can notice, each node has 3 fields ( :val :l (left) :r (right) ) . The children function is simply returning the non-nil sequence of nodes at :l and :r. Hoping somebody can help me with this. Thanks, Sunil. -- You 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
uberjar starts a repl
Hello, I have an application written that gets deployed using a uberjar built with leiningen. Works perfectly fine. For training purposes, I want to give a training version of that application that does not start the application (the -main routine) but a REPL so users can interactively use functions from the namespace and can explore it so that they end up with the same function calls like in the production version that has a -main function. How can I build such a uberjar that starts a repl instead of -main? The REPL should have also some nice editing features (I think I have to add jLine or how is it called?) Thx for any advice. - Finn -- You 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: JVM 7 support (invokedynamic)
On Thu, Aug 25, 2011 at 5:41 PM, Tal Liron tal.li...@gmail.com wrote: So, after setting up a JVM 7 environment to play with Clojure, and enthusiastically rummaging through the codebase, I have good news and bad news. :) So, when Clojure calls a function, it either already has the instance in its entirety (a lambda) or it finds it by dereferencing a binding. Since all functions are instances that implement IFn, the implementation can then call invokeinterface, which is very efficient. [See clojure.lang.Compiler#InvokeExpr.emitArgsAndCall] What I said in another post was that with invokedynamic (assuming you could just go whole hog into Java 7) you don't need the IFn interface. You just need a MethodHandle. So yes, I agree that given all the existing Clojure code, and the desire to stay compatible with Java 5 or 6 or whatever, invokedynamic isn't very compelling. If you were going to do a green field project, and didn't mind the Java 7 requirement, invokedynamic is very compelling, because you can basically push a bunch of code down into the JVM. This mean much less work, and it means you get to benefit from any improvements and optimizations that get built into the JVM. Even for Clojure having an optional Java 7 target may still be interesting in that it allows you to hook into all the work that will be done on invokedynamic to support the whole dynamic language ecosystem on the JVM. Clojure can get away with this especially easily because the only variant for function signatures in Clojure is arity. So, all we need is a simple switch to call the IFn method with the correct arity. (Interestingly, this means that Clojure has a fixed set of such signatures, and thus a fixed upper limit to arity: 20, in case you were wondering.) In a language like Ruby, methods are not so free floating, and have much more complex invocation styles as well as flexible signatures. (Clojure has only one style: function calls are simple forms.) So, in order to use invokeinterface, JRuby implementors would have had to create special classes *per* method *per* invocation style if they wanted to be efficient. But this is impossible, because so many classes would exhaust the perm-gen. For those languages, invokedynamic is a terrific solution, because it lets them dynamically link the implementation to the caller via a flexible bootstrapping mechanism, allowing them to do entirely without the extra class definition. Since all Clojure functions share essentially the same class as well as interface, none of these challenges exist. It's very possible that I'm missing something, but I'm not quite sure what you're getting at here. In JRuby, for instance, the method overloading is the same as in Clojure, it is based on arity. The slowdown is in dispatch where you have to check a singleton class, your class, your ancestors, then method_missing, etc. Once you've looked this all up you cache it to speed it up later. Then you want to invalidate the cache when the world changes. Clojure has similar needs. For instance, Clojure has protocol dispatch and multimethod dispatch as well as Var based dispatch. The multimethod dispatch does a look up in the derivation hierarchy. All of this stuff can change at runtime, just like in Ruby you can add methods to a class, change methods on a class, etc. I don't see how Clojure's dispatch needs are much different than what other dynamic languages are doing. Another aspect is the immutability of these IFn instances: you can't refactor them at runtime, all you can do is change the bindings to refer to new functions. So, Clojure achieves runtime dynamics by letting you simply rebind new functions to existing Vars, Refs, Atoms, etc., and the same invocation route continues as usual. In a language like Ruby, the bootstrapping mechanism of invokedynamic lets implementors change the base linkage to reflect a new signature for the method. Again, a terrific JVM 7 feature that Clojure simply does not need. The signature of a JRuby method is not much different than a Clojure method. It is an arity overloaded method with generic arguments. They do similar things to lots of other dynamic languages (including Clojure) like generating a class with a bunch of different versions of the same method with different numbers of generic arguments ( http://jruby.org/git?p=jruby.git;a=blob;f=src/org/jruby/internal/runtime/methods/DynamicMethod.java;h=b65854c057c8a1acec57d6dad95158f08c960dcc;hb=HEAD#l203). invokedynamic isn't about method signatures it's about dynamic dispatch, which is what Clojure does. Another issue I examined was how Clojure calls non-Clojure JVM code, thinking that perhaps there invokedynamic would be useful. But, Clojure again has a straightforward approach that poses no problems. Here, Clojure very directly calls non-Clojure code using invokestatic, invokevirtual or invokeinterface as appropriate. A Clojure form with the . or .. notations translates quite
Re: JVM 7 support (invokedynamic)
On Thu, Aug 25, 2011 at 6:05 PM, Tal Liron tal.li...@gmail.com wrote: Hmm... If you didn't have to worry about Java 7 compatibility, for one thing with invokedynamic you could remove a lot of code from Clojure. No more IFn or AFn. You simply have a method handle. Actually, Clojure's solution is almost identical to a method handle. An instance of AFn is not much different from an instance of MethodHandle, from the JVM's standpoint. The problem MethodHandle solves for languages like JRuby is that they need *different classes* for each method handling, whereas Clojure gets away with instances. Where using MethodHandle becomes important is when you want to participate in the invokedynamic bootstrapping, which expects MethodHandle instances. If Clojure ever needs to do this, it would be a simple one-to-one translation from AFn. I may be missing something, but I don't see how JRuby needs different classes. If you look at the JRuby code at the most basic level a method on a class is an instance of org.jruby.internal.runtime.methods.* or something else and those classes don't have so much to do with dispatch styles as optimizations. See, JRuby is able to achieve performance that is pretty darn close to Java, while still doing dynamic dispatch (without type hints). Clojure can not even get close to Java performance without type hints. All those different Method classes and all the complex stuff that JRuby does to make *dynamic* dispatch fast now gets pushed down into the JVM, and if Clojure taps into it, we could also get performance for dynamic dispatch that is much closer to Java. One could say, If you want performance use type hints, and that's a valid opinion, but again it's a different thing. Using type hints you are switching to static dispatch. If you want much better performance for *dynamic* dispatch, if you want much better performance without having to do type hints, then invokedynamic is here to help. Also, there's actually a huge difference between IFn and MethodHandle. When you invoke an IFn you have to cast your arguments into Objects, which for primitives means you have to box them. When you invoke a MethodHandle, this does not happen. You push your primitive arguments onto the stack, then when the invokedynamic instruction is executed the arguments are boxed only if necessary. Same thing with casting objects. You push the raw arguments onto the stack, and at runtime you can do casts, if necessary. IFn is a static, compile-time interface, and when using it you must force your arguments into it's compile-time signature. MethodHandles are not compile-time. Second, I think it would allow the JVM to have a better view into optimization, and would allow the JVM to optimize something speculatively and allow for Clojure tell the JVM when to deoptimize with a SwitchPoints and MutableCallSites. Except that there's no functional mutability in Clojure! I tried hard, but I could not come up with a case in which this could be used. What are you thinking of, specifically? A function value is immutable in Clojure, but Vars are not. Protocols are not. Multimethods are not. Those are the cases I'm thinking of where you could use SwitchPoints to tell the JVM, hey, I know you optimized this MethodHandle by inlining all the code, but now the Var has changed (sorry). 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 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: I/O
On Aug 25, 2011, at 11:39 PM, Dave Ray wrote: user.dir is the directory from which the JVM was launched, i.e. the initial working directory of the process. So, you're probably double-clicking the Clooj jar which resides in your Downloads folder and thus all further file system operations will be relative to that. Ah. Exactly right. That explains why. Thanks also for all of the other details and workaround suggestions on the clooj list. Alas, the bottom line does seem to be that there's no simple way to get simple file I/O to work relative to a project's location without launching the JVM in a specific way. -Lee -- You 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: Lein uberjar hangs when swank is required in the namespace.
On 25 Sie, 23:10, Lars Rune Nøstdal larsnost...@gmail.com wrote: It's hanging here too, but I have no idea why; I'm not including swank. Is there any verbose mode for lein? Maybe there is some problem with network (firewall or something) and you can not get jars from remote repository. Does it work for you: D:\lein repl user= (slurp http://clojars.org/repo/swank-clojure/swank-clojure/ 1.2.1/) ? Br, Rob -- You 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: I/O
I disagree. Simply use: (System/getProperty user.home) This will give you a useful path to work with, no matter where you start from. Works on my Mac. Should work on Windows. From there I would build a simple library which tests which OS I am on, and gives me the paths to the conventional locations on each plattform for applications-support, prefs, caching, documents, desktop, etc. I.e. (cache-dir my-application-name). On 26 Aug, 13:35, Lee Spector lspec...@hampshire.edu wrote: On Aug 25, 2011, at 11:39 PM, Dave Ray wrote: user.dir is the directory from which the JVM was launched, i.e. the initial working directory of the process. So, you're probably double-clicking the Clooj jar which resides in your Downloads folder and thus all further file system operations will be relative to that. Ah. Exactly right. That explains why. Thanks also for all of the other details and workaround suggestions on the clooj list. Alas, the bottom line does seem to be that there's no simple way to get simple file I/O to work relative to a project's location without launching the JVM in a specific way. -Lee -- You 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: I/O
On Aug 26, 2011, at 9:15 AM, Terje Dahl wrote: I disagree. Simply use: (System/getProperty user.home) This will give you a useful path to work with, no matter where you start from. Works on my Mac. Should work on Windows. From there I would build a simple library which tests which OS I am on, and gives me the paths to the conventional locations on each plattform for applications-support, prefs, caching, documents, desktop, etc. I.e. (cache-dir my-application-name). None of this gets you to the directory of your project, unless you hard code the path from your home directory. That said, it looks like Arthur Edelstein is working on a promising approach: https://github.com/arthuredelstein/local-file -Lee -- You 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: Peculiar transients behaviour
Adding the additional zero did trigger the issue for me. I have bumped the ticket into Release.Next. Thanks for the clarification. Cheers, Aaron Bedra -- Clojure/core http://clojure.com On 08/25/2011 01:21 PM, Alan Malloy wrote: Update: just built master, and issue still exists. If you want to be sure you get it, just add another zero to the input range. I'll mention that in the ticket as well. On Aug 25, 10:14 am, Alan Malloya...@malloys.org wrote: I did, of course. I searched for transient, and didn't find any describing this issue. And looking at the issue you link to, I still don't see how it's related: it's a patch specifically for vectors, and this code doesn't touch vectors; and it involves changes to a transient leaking back into the original persistent, while this code is about getting the wrong persistent object back after some changes. I don't have a lot of experience with building clojure, but I'll try compiling latest master and trying it out. In the meantime, did you try this code more than once? Because it includes randomness, sometimes it works without problems. On Aug 25, 6:03 am, Aaron Bedraaaron.be...@gmail.com wrote: Please search through previous messages/tickets before posting new issues. This issue has been fixed as of commit da412909d36551a526ed and will be included in the -beta2 release. It was originally ticketed here: http://dev.clojure.org/jira/browse/CLJ-816 (let [m (into {} (for [x (range 10)] [(rand) (rand)]))] (println (count (distinct (map hash (keys m) ((juxt count identity) (persistent! (reduce dissoc! (transient m) (keys m) 10 [0 {}] Cheers, Aaron Bedra -- Clojure/corehttp://clojure.com On 08/24/2011 04:32 AM, Alan Malloy wrote: On Aug 24, 12:27 am, Alan Malloya...@malloys.orgwrote: On Aug 23, 11:38 pm, Ken Wessonkwess...@gmail.comwrote: What does zipmap do if the key seq contains duplications? That was my instinct too, but (a) a few thousand numbers won't collide very often at all given the problem space, and (b) some experimenting indicates that the key-seq is always 100k elements large - no duplicates. HOWEVER, I did find the problem: the keys themselves don't collide, but their hashes do. The number of elements that get messed up is related to the number of hash collisions, but I still don't quite understand how they interact. Here's a modified code snippet that demonstrates the issue: user(let [m (apply zipmap (repeatedly 2 #(repeatedly 10 rand)))] (println (count (distinct (map hash (keys m) ((juxt count identity) (persistent! (reduce dissoc! (transient m) (keys m) 10 ;; no collisions [0 {}] ;; map is empty at the end user(let [m (apply zipmap (repeatedly 2 #(repeatedly 10 rand)))] (println (count (distinct (map hash (keys m) ((juxt count identity) (persistent! (reduce dissoc! (transient m) (keys m) 6 ;; four collisions [8 {0.30426231137219917 0.8531183785687654, 0.8893047006425385 0.4788315896128895, 0.47854633997540674 0.45133768991797785, 0.5265638224227486 0.7724779126227945}] ;; a four-element map that reports its count as eight!!! That last comment seems to indicate a very serious error somewhere: not only is the transient map broken, but it creates a broken persistent object. I'll file a JIRA issue for this, and see if I can find out any more about the cause. FWIW, I'm using 1.2.1 for the above output. Ticket is athttp://dev.clojure.org/jira/browse/CLJ-829 -- You 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
Notation conventions
I find myself making alot of mistakes when dealing with atoms. I usually remember the datatype and/or structure returned by a function, or held in a binding or symbol - but not wether it is an atom or not. Any naming-conventions for atoms, such as ending with ? for predicate, or ! for sideeffect? But at the same time i don't want to end up with some sort of Hungarian Notation. -- You 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: Notation conventions
I guess the first question is; why so many atoms? But regardless, there is no standard for naming such things. If you know you're dealing with atoms only (as opposed to a reference in general) then something like `foo-atom` would suffice I'd say. -- You 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
StackOverflowError with lazy qsort of The Joy of Clojure
Hi all, I'm toying around with the lazy, tail-recursive quick-sort implementation Michael Fogus and Chris Houser present in their book The Joy of Clojure: --8---cut here---start-8--- (in-ns 'user) (defn sort-parts Lazy, tail-recursive, incremental quicksort. Works against and creates partitions based on the pivot, defined as 'work'. [work] (lazy-seq (loop [[part parts] work] (if-let [[pivot xs] (seq part)] (let [smaller? #( % pivot)] (recur (list* (filter smaller? xs) pivot (remove smaller? xs) parts))) (when-let [[x parts] parts] (cons x (sort-parts parts))) (defn qsort [xs] (sort-parts (list xs))) --8---cut here---end---8--- It works fine for smaller seqs: --8---cut here---start-8--- user (time (first (qsort (take 1000 (iterate dec 500) Elapsed time: 142.61696 msecs -499 --8---cut here---end---8--- Well, except that being lazy is about 20 times faster than the standard sort, although taking only the first (smallest) element of a possibly large collection is the exact use-case for the lazy-sort, isn't it? --8---cut here---start-8--- user (time (first (sort (take 1000 (iterate dec 500) Elapsed time: 7.298069 msecs -499 --8---cut here---end---8--- But that's only the minor issue. The major issue is that I get a StackOverflowError when the seq passed to qsort becomes too large. And that error is not in the sorting code, but in clojure itself! --8---cut here---start-8--- user (first (qsort (take 10 (iterate dec 5 ; Evaluation aborted. No message. [Thrown class java.lang.StackOverflowError] Restarts: 0: [QUIT] Quit to the SLIME top level Backtrace: 0: clojure.core$take$fn__3836.invoke(core.clj:2500) 1: clojure.lang.LazySeq.sval(LazySeq.java:42) 2: clojure.lang.LazySeq.seq(LazySeq.java:60) 3: clojure.lang.RT.seq(RT.java:466) 4: clojure.core$seq.invoke(core.clj:133) 5: clojure.core$filter$fn__3830.invoke(core.clj:2469) 6: clojure.lang.LazySeq.sval(LazySeq.java:42) 7: clojure.lang.LazySeq.seq(LazySeq.java:60) 8: clojure.lang.RT.seq(RT.java:466) 9: clojure.core$seq.invoke(core.clj:133) 10: clojure.core$filter$fn__3830.invoke(core.clj:2469) 11: clojure.lang.LazySeq.sval(LazySeq.java:42) 12: clojure.lang.LazySeq.seq(LazySeq.java:60) 13: clojure.lang.RT.seq(RT.java:466) 14: clojure.core$seq.invoke(core.clj:133) 15: clojure.core$filter$fn__3830.invoke(core.clj:2469) 16: clojure.lang.LazySeq.sval(LazySeq.java:42) 17: clojure.lang.LazySeq.seq(LazySeq.java:60) 18: clojure.lang.RT.seq(RT.java:466) 19: clojure.core$seq.invoke(core.clj:133) 20: clojure.core$filter$fn__3830.invoke(core.clj:2469) --more-- --8---cut here---end---8--- Is that a bug? It occurs in both clojure 1.2.1 and a 1.3 snapshot. The standard sort function works, though: --8---cut here---start-8--- user (first (sort (take 10 (iterate dec 5 -4 --8---cut here---end---8--- Bye, Tassilo -- You 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: I/O
Friends, Thank you for the replies. I think you have proved my point. -- You 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: about the lazy-seq
you mean this? http://clojure.org/lazy maybe this can be helpful: http://en.wikipedia.org/wiki/Lazy_evaluation On Wed, Aug 24, 2011 at 1:48 PM, xiaoguizi87 xiaogui...@gmail.com wrote: I feel it is too difficult to understand the 'lazy-seq'.Can someone recommend something may help me? I have goolge it, but found nothing helpful. -- You 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
problems with gen-class :exposes-methods
Hello. This is with Clojure 1.2. This works: (gen-class :namecom.nsn.isar.saxon.ext_funcs.ClojureReceiver :extends net.sf.saxon.event.ProxyReceiver :exposes {nextReceiver { :get getReceiver :set setReceiver } } :exposes-methods { startDocument superStartDocument, endDocument superEndDocument, startElement superStartElement, endElementsuperEndElement, attribute superAttribute, startContent superStartContent, getNamePool superGetNamePool } ) If I however write a function to compute the map for exposes-methods, nothing seems to work. I also don't understand why the method names have to be given as symbols here and not as strings. { endDocument superEndDocument } would not work. It's probably because of this in gen-class: (if (contains? exposes-methods (symbol name)) However, not even this would work: :exposes-methods { (symbol startDocument) superStartDocument } I wrote this to compute me a map of name mappings for the :exposesMethods (the definition of classMethods is of the web, though): (defn classMethods Discovers all the public methods of a class or object by introspection and returns their names in order. [x] (let [c (if (class? x) x (class x))] (distinct (sort (seq (map #(.getName %1) (.getMethods c))) (defn makeCamelCase Upper-cases the first letter of a String. [x] (str (.toUpperCase (.substring x 0 1)) (.substring x 1))) (defn createSuperName [x] (str super (makeCamelCase x))) (defn exposeMethods Will compute a :exposes-methods spec for gen-class. Provide it with a class or object and it will discover all public methods names and prefix them with 'super'. [x] (loop [resultMap {} methodNames (classMethods x)] (if (empty? methodNames) resultMap (let [firstMethod (first methodNames) restMethods (rest methodNames)] (recur (assoc resultMap (symbol firstMethod) (createSuperName firstMethod)) restMethods) In the REPL it works correctly and gives me a map of the style that exposes-methods should accept. But if I make a call (exposeMethods net.sf.saxon.event.ProxyReceiver) within the gen-class macro, it does not work. My questions are: 1) Is this a problem of evaluation? Does my call not to exposeMethods not get evaluated at compile time? (My assumption would have been that in a Lisp dialect it would get expanded even at compile-time.) 2) Why does only the format { symbol string } work for the map? What is the I tried to read the definition of the gen-class macro, but it is beyond me on my first week of Clojure. ;-) Thank you in advance, Oliver -- You 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: Compojure
You might want to check out this excellent article by Andrew Brehaut that covers a typical web stack in clojure with many examples - http://brehaut.net/blog/2011/ring_introduction Jaskirat On Wed, Aug 24, 2011 at 6:43 PM, Michael Jaaka michael.ja...@googlemail.com wrote: RESTFUL in Clojure? Hi I have found http://groups.google.com/group/clojure/browse_thread/thread/cfb2e5c29bb1337/92e2b8356a50189c?lnk=gstq=web+services#92e2b8356a50189c But it doesn't work anymore. Anyone can point to fresh tutorial? Bye! -- You 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: Why can't I print new sequence?
Any reason not to use a Set ? On Wed, Aug 24, 2011 at 3:57 PM, Ken Wesson kwess...@gmail.com wrote: On Wed, Aug 24, 2011 at 5:58 PM, octopusgrabbus octopusgrab...@gmail.com wrote: (defn f1 [in-seq] (loop [new-seq [] cur-seq in-seq] (if (nil? (first cur-seq)) new-seq (if-not (nil? (x-in-seq (first cur-seq) new-seq)) (recur (conj new-seq (first cur-seq)) (rest cur-seq)) You don't have a second branch for that last if, so the whole thing evaluates to nil if there are any duplicates, which there are. You need an else clause of (recur new-seq (rest cur-seq)). Or you could just use clojure.core/distinct :) -- Protege: What is this seething mass of parentheses?! Master: Your father's Lisp REPL. This is the language of a true hacker. Not as clumsy or random as C++; a language for a more civilized age. -- You 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: JVM 7 support (invokedynamic)
This means I can read the rest of the logs http://clojure-log.n01se.net/date/2008-09-03.html and it stills hold up ? i.e we want tagged numbers ? /Kevin On Thu, Aug 25, 2011 at 2:51 PM, Aaron Bedra aaron.be...@gmail.com wrote: That's correct. That is why Clojure/core hasn't prioritized this work. Cheers, Aaron Bedra -- Clojure/core http://clojure.com On 08/25/2011 08:37 AM, Meikel Brandmeyer (kotarak) wrote: Hi, Disclaimer: I have no clue whatsoever about the low-level JVM stuff. I remember Rich saying in one of his talks/interviews, that invokedynamic is not very interesting for Clojure and that Clojure won't really benefit from it. I'm far from understanding these things. So details on what's improved would be very interesting, I guess. Sincerely Meikel -- You 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 -- You 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
weird behavior: what is the difference between sequential? and my own predicate?
Dear Clojurians, while playing with http://4clojure.com I found a perplexing behavior when I submit my own code for implementing my own poor implementation of my-flatten for problem 28: (defn my-flatten [coll] (loop [acc [] coll coll] (if-let [[a coll] coll] (if (or (list? a) (vector? a)) (recur acc (if (empty? coll) (vec a) (conj (vec a) coll))) (recur (conj acc a) coll)) acc))) The above code failed the second test: [a [b] c]. Instead of producing the correct result, it produces: [a b (c)]. But if I replace (or (list? a) (vector? a)) with (sequential? a), the code works as expected. (defn my-flatten2 [coll] (loop [acc [] coll coll] (if-let [[a coll] coll] (if (sequential? a) (recur acc (if (empty? coll) (vec a) (conj (vec a) coll))) (recur (conj acc a) coll)) acc))) While (or (list? a) (vector? a)) will evaluates to true given a being '(c), somewhow in the above function it was evaluated to being false. Can anyone help me understand what is going on here? Thanks! shouxun -- You 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: StackOverflowError with lazy qsort of The Joy of Clojure
Looking at the stack trace, I suspect this is the old problem of layering too many filters on top of the same seq. If I understand the issue correctly, when you have enough layers of filter on top of a seq, when you finally try to access elements, as it evaluates each layer, it is going to be making a call for each layer of filter. With enough layers, you'll blow your stack. I've seen people solve these issues by forcing the intermediate seqs, but that doesn't work well for a lazy situation such as this. On Aug 26, 7:42 am, Tassilo Horn tass...@member.fsf.org wrote: Hi all, I'm toying around with the lazy, tail-recursive quick-sort implementation Michael Fogus and Chris Houser present in their book The Joy of Clojure: --8---cut here---start-8--- (in-ns 'user) (defn sort-parts Lazy, tail-recursive, incremental quicksort. Works against and creates partitions based on the pivot, defined as 'work'. [work] (lazy-seq (loop [[part parts] work] (if-let [[pivot xs] (seq part)] (let [smaller? #( % pivot)] (recur (list* (filter smaller? xs) pivot (remove smaller? xs) parts))) (when-let [[x parts] parts] (cons x (sort-parts parts))) (defn qsort [xs] (sort-parts (list xs))) -- You 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: JVM 7 support (invokedynamic)
On Thu, Aug 25, 2011 at 9:05 AM, Kevin Ilchmann Jørgensen kijm...@gmail.com wrote: This means I can read the rest of the logs http://clojure-log.n01se.net/date/2008-09-03.html and it stills hold up ? i.e we want tagged numbers ? /Kevin 1.3 went a different route. Fast path for 64bit arithmetic. 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 behavior: what is the difference between sequential? and my own predicate?
Hi On 25 August 2011 18:16, Shouxun Yang yang.shou...@gmail.com wrote: Dear Clojurians, while playing with http://4clojure.com I found a perplexing behavior when I submit my own code for implementing my own poor implementation of my-flatten for problem 28: (defn my-flatten [coll] (loop [acc [] coll coll] (if-let [[a coll] coll] (if (or (list? a) (vector? a)) (recur acc (if (empty? coll) (vec a) (conj (vec a) coll))) (recur (conj acc a) coll)) acc))) The above code failed the second test: [a [b] c]. Instead of producing the correct result, it produces: [a b (c)]. But if I replace (or (list? a) (vector? a)) with (sequential? a), the code works as expected. (defn my-flatten2 [coll] (loop [acc [] coll coll] (if-let [[a coll] coll] (if (sequential? a) (recur acc (if (empty? coll) (vec a) (conj (vec a) coll))) (recur (conj acc a) coll)) acc))) While (or (list? a) (vector? a)) will evaluates to true given a being '(c), somewhow in the above function it was evaluated to being false. Can anyone help me understand what is going on here? Does this help? user= (class '(c)) clojure.lang.PersistentList user= (if-let [[a coll] coll] coll) ([b] c) user= (class (if-let [[a coll] coll] coll)) clojure.lang.PersistentVector$ChunkedSeq user= (list? (if-let [[a coll] coll] coll)) false user= (vector? (if-let [[a coll] coll] coll)) false -- Michael Wood esiot...@gmail.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 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 behavior: what is the difference between sequential? and my own predicate?
Shouxun Yang yang.shou...@gmail.com writes: (defn my-flatten [coll] (loop [acc [] coll coll] (if-let [[a coll] coll] (if (or (list? a) (vector? a)) (recur acc (if (empty? coll) (vec a) (conj (vec a) coll))) (recur (conj acc a) coll)) acc))) The above code failed the second test: [a [b] c]. Instead of producing the correct result, it produces: [a b (c)]. The problem is that in [a b (c)], (c) is neither a list nor a vector. It's a seq. Unfortunately, seqs and lists have the same print syntax, so you were not able to easily see that. BTW: You should use coll? instead of sequential? or seq? if your intention is only to check if the thing is some collection. For example, (sequential? #{1 2 3}) is false. (sequential? only works for ordered collections like vectors, lists and seqs.) BTW2: Instead of (empty? coll), use the idiomatic (seq coll) recipe. Bye, Tassilo -- You 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 behavior: what is the difference between sequential? and my own predicate?
Michael, thank you very much. I never paid much attention to the chunked seq feature before. The effect is surprising to my Common Lisp / OCaml background. I thought my code good enough to cover the test cases. Always new thing to learn. shouxun 在 2011-8-26 下午11:42,Michael Wood esiot...@gmail.com写道: Hi On 25 August 2011 18:16, Shouxun Yang yang.shou...@gmail.com wrote: Dear Clojurians, while playing with http://4clojure.com I found a perplexing behavior when I submit my own code for implementing my own poor implementation of my-flatten for problem 28: (defn my-flatten [coll] (loop [acc [] coll coll] (if-let [[a coll] coll] (if (or (list? a) (vector? a)) (recur acc (if (empty? coll) (vec a) (conj (vec a) coll))) (recur (conj acc a) coll)) acc))) The above code failed the second test: [a [b] c]. Instead of producing the correct result, it produces: [a b (c)]. But if I replace (or (list? a) (vector? a)) with (sequential? a), the code works as expected. (defn my-flatten2 [coll] (loop [acc [] coll coll] (if-let [[a coll] coll] (if (sequential? a) (recur acc (if (empty? coll) (vec a) (conj (vec a) coll))) (recur (conj acc a) coll)) acc))) While (or (list? a) (vector? a)) will evaluates to true given a being '(c), somewhow in the above function it was evaluated to being false. Can anyone help me understand what is going on here? Does this help? user= (class '(c)) clojure.lang.PersistentList user= (if-let [[a coll] coll] coll) ([b] c) user= (class (if-let [[a coll] coll] coll)) clojure.lang.PersistentVector$ChunkedSeq user= (list? (if-let [[a coll] coll] coll)) false user= (vector? (if-let [[a coll] coll] coll)) false -- Michael Wood esiot...@gmail.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 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: weird behavior: what is the difference between sequential? and my own predicate?
Hi On 26 August 2011 17:44, Tassilo Horn tass...@member.fsf.org wrote: [...] BTW2: Instead of (empty? coll), use the idiomatic (seq coll) recipe. You have that one backwards :) user= (doc empty?) - clojure.core/empty? ([coll]) Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x)) nil -- Michael Wood esiot...@gmail.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 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: I/O
2011/8/26 Lee Spector lspec...@hampshire.edu On Aug 25, 2011, at 9:27 PM, Ken Wesson wrote: On Thu, Aug 25, 2011 at 6:49 PM, Lee Spector lspec...@hampshire.edu wrote: While slurp and spit are beautifully elegant it's not so elegant to tell slurp how to find the file you want it to slurp. In many other languages/environments there's a concept of the working directory or project directory, relative to which you can specify locations. In Clojure you have to deal with the classpath, outside of the language proper, and many of the common ways of running Clojure programs handle this differently. I don't know if there's a good, general solution to this, but for me (both as a programmer and especially as a teacher) it is definitely a pain point. What about (System/getProperty user.dir)? The value of user.dir depends on how the code is run. Now that I check I see that if I run a lein repl in a project directory then it is set to that directory, which is great. But if I run the code in some other way it may be set to something different. For example, in clooj currently it's set to my Downloads directory. I'll write to the clooj list to see if this can be changed, but I also had problems with this sort of thing in Eclipse/Counterclockwise and I'm wondering: Is it specified somewhere that this should always be set to the project directory? What kind of problem with Eclipse / CCW ? CCW uses a standard java launcher, so to say it uses the Eclipse Java Development Tools defaults, which are to create a launch configuration with the project's path as the current directory (of course you can change that by editing the associated launch configuration, later on : Run Run as ... [choose the launch configuration, edit, save]) Cheers, -- Laurent If I run a lein repl from a non-project directory then it's set to my home directory, which makes some sense I guess, but why not the directory from which the repl was launched? FWIW my larger point was just that all of this is less clear than it is in many other languages, and that simple file I/O is therefore less simple than one might hope. Thanks, -Lee -- You 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: weird behavior: what is the difference between sequential? and my own predicate?
在 2011-8-26 下午11:44,Tassilo Horn tass...@member.fsf.org写道: Shouxun Yang yang.shou...@gmail.com writes: (defn my-flatten [coll] (loop [acc [] coll coll] (if-let [[a coll] coll] (if (or (list? a) (vector? a)) (recur acc (if (empty? coll) (vec a) (conj (vec a) coll))) (recur (conj acc a) coll)) acc))) The above code failed the second test: [a [b] c]. Instead of producing the correct result, it produces: [a b (c)]. The problem is that in [a b (c)], (c) is neither a list nor a vector. It's a seq. Unfortunately, seqs and lists have the same print syntax, so you were not able to easily see that. BTW: You should use coll? instead of sequential? or seq? if your intention is only to check if the thing is some collection. For example, (sequential? #{1 2 3}) is false. (sequential? only works for ordered collections like vectors, lists and seqs.) Thanks. For this case, I actually need an atom? predicate as in CL. BTW2: Instead of (empty? coll), use the idiomatic (seq coll) recipe. Good point. I read about the tip before, but forgot in my own code. Bye, Tassilo -- You 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: I/O
On Aug 26, 2011, at 12:01 PM, Laurent PETIT wrote: What kind of problem with Eclipse / CCW ? CCW uses a standard java launcher, so to say it uses the Eclipse Java Development Tools defaults, which are to create a launch configuration with the project's path as the current directory (of course you can change that by editing the associated launch configuration, later on : Run Run as ... [choose the launch configuration, edit, save]) Sorry Laurent -- I can't back up my memory of this with details and I shouldn't have made this slur against CCW. I do recall being generally confused (so maybe it's more of a self slur :-) about which run configuration was being used at which time (e.g. when I started a run by saying to evaluate a file or an expression in a repl), and that might have been part of the problem. And I was also often confused about how to get code that I run in CCW to find source (.clj) files, because of the way the project had to be synced with the file system, and how things had to be added to the classpath… and I guess a bunch of how do I make it find my stuff, which is right here questions may have gotten mixed up in my head… All of which maybe helps to make the point that this cluster of issues can be confusing to people new to the java ecosystem. FWIW it turns out that I can't easily check my memory because I recently transitioned to a new OS and machine and my Eclipse is failing to run at all, and I've been working only in clooj since the transition… but I'll sort this out and let you know if I still have issues. Thanks for your great help as always. -Lee -- You 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 behavior: what is the difference between sequential? and my own predicate?
Michael Wood esiot...@gmail.com writes: BTW2: Instead of (empty? coll), use the idiomatic (seq coll) recipe. You have that one backwards :) Ah, that must be the reason my apps don't ever work! ;-) So BTW3: Use (seq coll) and swich the then/else parts of the if. Bye, Tassilo -- You 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: StackOverflowError with lazy qsort of The Joy of Clojure
Paul Mooser taron...@gmail.com writes: Hi Paul, Looking at the stack trace, I suspect this is the old problem of layering too many filters on top of the same seq. If I understand the issue correctly, when you have enough layers of filter on top of a seq, when you finally try to access elements, as it evaluates each layer, it is going to be making a call for each layer of filter. With enough layers, you'll blow your stack. Do you have a link to the issue? I've tried searching for filter or layer at dev.clojure.org, but I can't find anything... I've seen people solve these issues by forcing the intermediate seqs, but that doesn't work well for a lazy situation such as this. Indeed, putting a doall around the filter and remove seems to prevent the stack overflow. Bye, Tassilo -- You 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: StackOverflowError with lazy qsort of The Joy of Clojure
Tassilo Horn tass...@member.fsf.org writes: I've seen people solve these issues by forcing the intermediate seqs, but that doesn't work well for a lazy situation such as this. Indeed, putting a doall around the filter and remove seems to prevent the stack overflow. A better solution seems to be to use a sequence comprehension: --8---cut here---start-8--- (defn sort-parts Lazy, tail-recursive, incremental quicksort. Works against and creates partitions based on the pivot, defined as 'work'. [work] (lazy-seq (loop [[part parts] work] (if-let [[pivot xs] (seq part)] (let [smaller? #( % pivot)] (recur (list* (for [x xs :when (smaller? x)] x) pivot (for [x xs :when ((complement smaller?) x)] x) parts))) (when-let [[x parts] parts] (cons x (sort-parts parts))) (defn qsort [xs] (sort-parts (list xs))) --8---cut here---end---8--- It also seems to perform a bit better than the original solution. However, I cannot see any big difference in speed compared to my simple straight-forward solution: --8---cut here---start-8--- (defn qsort2 [xs] (lazy-seq (when (seq xs) (let [[p r] xs] (concat (qsort (for [y r :when ( y p)] y)) [p] (qsort (for [y r :when (= y p)] y))) --8---cut here---end---8--- Bye, Tassilo -- You 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: I/O
On Thu, 25 Aug 2011 19:24:13 +0300 Mats Rauhala mats.rauh...@gmail.com wrote: The simplest way is to slurp or spit. slurp reads a file into a string, and spit writes a string into a file. Yes, true, but first you have to know them. And slurp is not the first think I am looking for when attempting to read a file, nor is spit for reading. (That said I quite like the easy IO in Clojure, the verbose IO was something I always disliked on the JVM) regards, Marek signature.asc Description: PGP signature
Re: StackOverflowError with lazy qsort of The Joy of Clojure
If you search for filter and StackOverflowError in this group, you will find people discussing related issues. On Aug 26, 10:30 am, Tassilo Horn tass...@member.fsf.org wrote: Do you have a link to the issue? I've tried searching for filter or layer at dev.clojure.org, but I can't find anything... -- You 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
Joy of Clojure lazy quicksort doesn't seem to save comparisons?! (was: StackOverflowError with lazy qsort of The Joy of Clojure)
Tassilo Horn tass...@member.fsf.org writes: Now I'm really a bit confused. I've just added atom counters and increased them in the comparison functions in order to check if the lazy variants really test less than the standard sort. A better solution [that doesn't overrun the stack] seems to be to use a sequence comprehension [instead of filter/remove]: (defn sort-parts Lazy, tail-recursive, incremental quicksort. Works against and creates partitions based on the pivot, defined as 'work'. [work] (lazy-seq (loop [[part parts] work] (if-let [[pivot xs] (seq part)] (let [smaller? #( % pivot)] (recur (list* (for [x xs :when (smaller? x)] x) pivot (for [x xs :when ((complement smaller?) x)] x) parts))) (when-let [[x parts] parts] (cons x (sort-parts parts))) (defn qsort [xs] (sort-parts (list xs))) (take 2 (qsort [1 9 2 8 3 7 4 6 5])) executes #( % pivot) 42 times. [I replaced the compare fn with #(do (swap! q1 inc) ( % pivot)) to get to this result where q1 was (atom 0) initially.] (defn qsort2 [xs] (lazy-seq (when (seq xs) (let [[p r] xs] (concat (qsort (for [y r :when ( y p)] y)) [p] (qsort (for [y r :when (= y p)] y))) (take 2 (qsort2 [1 9 2 8 3 7 4 6 5])) executes the 2 :when predicates only 16 times in total. [Same counting approach as above.] The standard sort function given #(do (swap! q3 inc) (compare %1 %2)) as its comparison function compares 21 times. So my simple qsort2 seems to have saved 5 comparisons. But the adapted JoC-version takes twice as many comparisons as the standart sort of the whole seq! Why is that? Then I tried sorting the complete seq using my qsort2 instead of only taking the two first items. That also takes 16 comparisons, but well, that's clear because of the min-max structure of the vector. Taking only the first item takes only 8 comparisons as it should. So it seems, qsort is flawed, and the difference in comparisons between qsort2 and sort when sorting the complete seq is that the latter uses merge-sort, not quick-sort, right? But what I don't understand is why qsort, although it compares nearly thrice as often than qsort2, is still about as fast as qsort2. I'd really appreciate if someone could share some light. Bye, Tassilo -- You 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: StackOverflowError with lazy qsort of The Joy of Clojure
Paul Mooser taron...@gmail.com writes: Hi Paul, If you search for filter and StackOverflowError in this group, you will find people discussing related issues. Thanks, I've found some explanation by Meikel Brandmeier who explains the layering issue. But do we really have to live with that? I mean, replacing the filter/remove with a list comprehension solved the issue for me. And it's easy to define filter in terms of for. --8---cut here---start-8--- user (defn philter [pred coll] (for [x coll :when (pred x)] x)) #'user/philter user (filter even? (take 10 (iterate inc 0))) (0 2 4 6 8) user (philter even? (take 10 (iterate inc 0))) (0 2 4 6 8) --8---cut here---end---8--- I've tried benchmarking filter vs. philter with seqs of different sizes, and there seems to be no difference. So why not simply do it that way? Bye, Tassilo -- You 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: StackOverflowError with lazy qsort of The Joy of Clojure
On Aug 26, 12:40 pm, Tassilo Horn tass...@member.fsf.org wrote: Paul Mooser taron...@gmail.com writes: Hi Paul, If you search for filter and StackOverflowError in this group, you will find people discussing related issues. Thanks, I've found some explanation by Meikel Brandmeier who explains the layering issue. But do we really have to live with that? I mean, replacing the filter/remove with a list comprehension solved the issue for me. And it's easy to define filter in terms of for. --8---cut here---start-8--- user (defn philter [pred coll] (for [x coll :when (pred x)] x)) #'user/philter user (filter even? (take 10 (iterate inc 0))) (0 2 4 6 8) user (philter even? (take 10 (iterate inc 0))) (0 2 4 6 8) --8---cut here---end---8--- I've tried benchmarking filter vs. philter with seqs of different sizes, and there seems to be no difference. So why not simply do it that way? It would make no difference. philter is exactly as lazy as filter, and will have the same stacked-laziness problem. See http://stackoverflow.com/questions/2946764/recursive-function-causing-a-stack-overflow which in my opinion is a pretty clear presentation of the 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: uberjar starts a repl
On Fri, Aug 26, 2011 at 1:15 AM, finbeu info_pe...@t-online.de wrote: How can I build such a uberjar that starts a repl instead of -main? The REPL should have also some nice editing features (I think I have to add jLine or how is it called?) For a raw repl you should be able to do: $ lein uberjar clojure.main # requires Leiningen 1.6.1 Getting jline is a bit more work; you'll probably have to write your own alternate -main. Just give the uberjar task an argument to have it look in a different namespace for your jline-enabled -main though. If you can get your users to use rlwrap it would be much simpler. -Phil -- You 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: Notation conventions
OK. Thanks. Regarding why so many atoms: I have rewritten a GUI-based (Swing) app to Clojure (our company's product: A Java applet), and where I previously typically had extended JPanels, adding variables and methods to them, I have (for now) replaced them with maps in atoms, where the maps contain the same data (including the actual panel, which I prevously extended), and even som methods to work on those values, and then I am able to pass around references to data which can be altered with swap! - basically a form of mutable state. Not ideal, and I am certainly intend to refactor the code to make it more functional, but I am not sure how to better implement a more complex event-driven GUI application. I have your book, but haven't read most of it yet. Am still reading Clojure in Action. Any part of your book I should skip to directly that is specific to my problem? Any good articles og code samples you can point me to? On 26 Aug, 16:42, Fogus mefo...@gmail.com wrote: I guess the first question is; why so many atoms? But regardless, there is no standard for naming such things. If you know you're dealing with atoms only (as opposed to a reference in general) then something like `foo-atom` would suffice I'd say. -- You 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
Please optimize this with macro (grep and context result grabing)
Hi! I have got (def *g) (def *g1) (def *g2) (def *g3) (def *g4) (def *g5) (def *g6) (defmacro grep[ pat in body ] `(do (when-let[ r# (re-matches (re-pattern ~pat) ~in) ] (binding [ *g (first r#) *g1 (get r# 1) *g2 (get r# 2) *g3 (get r# 3) *g4 (get r# 4) *g5 (get r# 5) *g6 (get r# 6) ] ~@body (grep (.+)-(.+) 1-4 (println *g *g1 *g2) ) I need to optimize the *gx so it won't look like hand written. Anyone? I was trying to use with-bindings and #' but it doesn't work. Also push and pop of thread bindings didn't want to work. -- You 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
is there a 4Clojure forum anywhere?
I've just started going through the problems on http://4clojure.com . Very fun. Does anyone know if there's a discussion forum dedicated to that site? I've searched but nothing jumps out. I'm looking for a hint on how to solve the Nth Element problem (without cheating and using the nth function). -- You 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: JVM 7 support (invokedynamic)
This is the best summary of how Clojure *could* benefit from invokedynamic. Clojure doesn't dispatch as dynamically as JRuby, but there is a dynamic component...specifically, you have to go get the fn. That repeated get would disappear with invokedynamic, In fact, anywhere you're going after something that's immutable but requires a memory access, you could potentially use invokedynamic to eliminate repeat memory accesses. I assume that would help in many places. Also, as Paul notes below, there's no need for multiple-arity interfaces to get full-speed perf if you use invokedynamic; JRuby's invokedynamic-based dispatch ends up going directly from call site to target code body, with no intervening interface at all. Listen to Paul. He's right. - Charlie On Friday, August 26, 2011 5:37:53 AM UTC-5, Paul Stadig wrote: On Thu, Aug 25, 2011 at 5:41 PM, Tal Liron tal@gmail.com wrote: So, after setting up a JVM 7 environment to play with Clojure, and enthusiastically rummaging through the codebase, I have good news and bad news. :) So, when Clojure calls a function, it either already has the instance in its entirety (a lambda) or it finds it by dereferencing a binding. Since all functions are instances that implement IFn, the implementation can then call invokeinterface, which is very efficient. [See clojure.lang.Compiler#InvokeExpr.emitArgsAndCall] What I said in another post was that with invokedynamic (assuming you could just go whole hog into Java 7) you don't need the IFn interface. You just need a MethodHandle. So yes, I agree that given all the existing Clojure code, and the desire to stay compatible with Java 5 or 6 or whatever, invokedynamic isn't very compelling. If you were going to do a green field project, and didn't mind the Java 7 requirement, invokedynamic is very compelling, because you can basically push a bunch of code down into the JVM. This mean much less work, and it means you get to benefit from any improvements and optimizations that get built into the JVM. Even for Clojure having an optional Java 7 target may still be interesting in that it allows you to hook into all the work that will be done on invokedynamic to support the whole dynamic language ecosystem on the JVM. Clojure can get away with this especially easily because the only variant for function signatures in Clojure is arity. So, all we need is a simple switch to call the IFn method with the correct arity. (Interestingly, this means that Clojure has a fixed set of such signatures, and thus a fixed upper limit to arity: 20, in case you were wondering.) In a language like Ruby, methods are not so free floating, and have much more complex invocation styles as well as flexible signatures. (Clojure has only one style: function calls are simple forms.) So, in order to use invokeinterface, JRuby implementors would have had to create special classes *per* method *per* invocation style if they wanted to be efficient. But this is impossible, because so many classes would exhaust the perm-gen. For those languages, invokedynamic is a terrific solution, because it lets them dynamically link the implementation to the caller via a flexible bootstrapping mechanism, allowing them to do entirely without the extra class definition. Since all Clojure functions share essentially the same class as well as interface, none of these challenges exist. It's very possible that I'm missing something, but I'm not quite sure what you're getting at here. In JRuby, for instance, the method overloading is the same as in Clojure, it is based on arity. The slowdown is in dispatch where you have to check a singleton class, your class, your ancestors, then method_missing, etc. Once you've looked this all up you cache it to speed it up later. Then you want to invalidate the cache when the world changes. Clojure has similar needs. For instance, Clojure has protocol dispatch and multimethod dispatch as well as Var based dispatch. The multimethod dispatch does a look up in the derivation hierarchy. All of this stuff can change at runtime, just like in Ruby you can add methods to a class, change methods on a class, etc. I don't see how Clojure's dispatch needs are much different than what other dynamic languages are doing. Another aspect is the immutability of these IFn instances: you can't refactor them at runtime, all you can do is change the bindings to refer to new functions. So, Clojure achieves runtime dynamics by letting you simply rebind new functions to existing Vars, Refs, Atoms, etc., and the same invocation route continues as usual. In a language like Ruby, the bootstrapping mechanism of invokedynamic lets implementors change the base linkage to reflect a new signature for the method. Again, a terrific JVM 7 feature that Clojure simply does not need. The signature of a JRuby method is not much different than a Clojure
Re: is there a 4Clojure forum anywhere?
Is there a recovery group for 4clojure.com addicts? Stop now! Don't go further before it's too late and you are checking the website every five minutes waiting for the next problem, obsessing over every character in your code so you can get one of the best code golf scores, etc. But seriously, one of the greatest websites of its kind and kudos to the creators! I don't know of any discussion forums and probably would have stumbled on one over the past few weeks if there was one. On Aug 26, 3:53 pm, chepprey chepp...@gmail.com wrote: I've just started going through the problems onhttp://4clojure.com. Very fun. Does anyone know if there's a discussion forum dedicated to that site? I've searched but nothing jumps out. I'm looking for a hint on how to solve the Nth Element problem (without cheating and using the nth function). -- You 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: Please optimize this with macro (grep and context result grabing)
do you know about the re-groups function, or are you just doing this for an exercise? On Fri, Aug 26, 2011 at 6:57 PM, Michael Jaaka michael.ja...@googlemail.com wrote: Hi! I have got (def *g) (def *g1) (def *g2) (def *g3) (def *g4) (def *g5) (def *g6) (defmacro grep[ pat in body ] `(do (when-let[ r# (re-matches (re-pattern ~pat) ~in) ] (binding [ *g (first r#) *g1 (get r# 1) *g2 (get r# 2) *g3 (get r# 3) *g4 (get r# 4) *g5 (get r# 5) *g6 (get r# 6) ] ~@body (grep (.+)-(.+) 1-4 (println *g *g1 *g2) ) I need to optimize the *gx so it won't look like hand written. Anyone? I was trying to use with-bindings and #' but it doesn't work. Also push and pop of thread bindings didn't want to work. -- You 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: Please optimize this with macro (grep and context result grabing)
Well I think that this is a different case. On 27 Sie, 03:15, gaz jones gareth.e.jo...@gmail.com wrote: do you know about the re-groups function, or are you just doing this for an exercise? On Fri, Aug 26, 2011 at 6:57 PM, Michael Jaaka michael.ja...@googlemail.com wrote: Hi! I have got (def *g) (def *g1) (def *g2) (def *g3) (def *g4) (def *g5) (def *g6) (defmacro grep[ pat in body ] `(do (when-let[ r# (re-matches (re-pattern ~pat) ~in) ] (binding [ *g (first r#) *g1 (get r# 1) *g2 (get r# 2) *g3 (get r# 3) *g4 (get r# 4) *g5 (get r# 5) *g6 (get r# 6) ] ~@body (grep (.+)-(.+) 1-4 (println *g *g1 *g2) ) I need to optimize the *gx so it won't look like hand written. Anyone? I was trying to use with-bindings and #' but it doesn't work. Also push and pop of thread bindings didn't want to work. -- You 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: is there a 4Clojure forum anywhere?
I haven't heard of one either, and I'm maintainer and co-founder of 4clojure. If someone (that means you!) starts such a forum, I'm happy to link to it from 4clojure proper. On Aug 26, 5:59 pm, Bob Shock shock...@gmail.com wrote: Is there a recovery group for 4clojure.com addicts? Stop now! Don't go further before it's too late and you are checking the website every five minutes waiting for the next problem, obsessing over every character in your code so you can get one of the best code golf scores, etc. But seriously, one of the greatest websites of its kind and kudos to the creators! I don't know of any discussion forums and probably would have stumbled on one over the past few weeks if there was one. On Aug 26, 3:53 pm, chepprey chepp...@gmail.com wrote: I've just started going through the problems onhttp://4clojure.com. Very fun. Does anyone know if there's a discussion forum dedicated to that site? I've searched but nothing jumps out. I'm looking for a hint on how to solve the Nth Element problem (without cheating and using the nth function). -- You 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: mini-version of clojure.jar?
You might want to give Pack200 a try; it's a Java classfile-aware compression algorithm that can produce jars that are far more compact than e.g. if you were to only gzip applet jars on their way out to your users. Lots of info about it if you feel like googling. Using a build from the current HEAD of Clojure, this: pack200 clojure-1.3.0.pack.gz clojure-1.3.0-master-SNAPSHOT.jar results in decent savings: -rw-r--r-- 1 chas chas 835K Aug 26 22:57 clojure-1.3.0-master-SNAPSHOT-slim.jar -rw-r--r-- 1 chas chas 3.2M Aug 26 22:57 clojure-1.3.0-master-SNAPSHOT.jar -rw-r--r-- 1 chas chas 1.3M Aug 26 22:59 clojure-1.3.0.pack.gz So, pack200 won't get you down to the slim jar's 835K, but it will shave off ~60%, and shouldn't impact startup time at all. Whether that's a good tradeoff is up to you. :-) - Chas On Aug 25, 2011, at 4:26 AM, Terje Dahl wrote: My company (read: I) develop an web-based educational application (a language lab) implemented as a Java applet. I have spendt the summer porting it to Clojure. I am very happy with the results. Except: The download (and therefore the download-time) has increased dramatically, as I now include the clojure.jar as part of the download. (Actually, I repackage the content together with my application.) This, I fear is going to hit alot of the pupils hard, when 20 pupils at a time attempt to access the applet for the first time over the mediocre (at best) web-connections at their schools. Yes, I do manipulate the java applet cache-params. But There will always be a need for full downloads - both for first- time-users, and when I update the applet (frequently). My question: Is there anyway to reduce the size of the jar - drastically? Can I somehow remove most of the class-files generated from core.clj etc, and still have everything working properly? Tips/hints/suggestions? (Plug: See my open-source JS-embed code for Java applets: http://bitbucket.terjedahl.no/terjedahl/appletjs ) -- You 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