Bug? Definline arguments multiply evaluated.
user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b))) #'hxr.clj.util/addsq user=> (addsq (do (println "a evaluated") 1) 1) a evaluated a evaluated 2 --~--~-~--~~~---~--~~ You 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: Exit delay from java when lazy?
On Jul 29, 8:17 pm, Michael Wood wrote: > 2009/7/29 mwillson : > > > > I was experimenting with Clojure and XML and stumbled upon a lengthy > > hang when exiting java which was tracked down to the use of > > clojure.contrib.lazy-xml. Here's a toy example which exhibits the > > issue: > > I haven't looked at clojure.contrib.lazy-xml, but this sounds like > what happens if you make use of agents. Shutting down the agents with > (shutdown-agents) should fix it if so. Perhaps > clojure.contrib.lazy-xml uses agents. Michael, Thanks for your reply. You are quite right - adding (shutdown-agents) does allow the script using lazy-xml to exit promptly. From a cursory scan of the lazy-xml/parse-seq code, it does use agents. -mark --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: java 1.4 class files
Thank you Stuart and Daniel for the help. I think I have to step back from the idea to use clojure on this Java 1.4 project :-( Let's hope my next Java project addresses a less archaic Java version. --~--~-~--~~~---~--~~ You 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: Bug? Definline arguments multiply evaluated.
On Jul 30, 1:29 am, John Harrop wrote: > user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b))) > #'hxr.clj.util/addsq > user=> (addsq (do (println "a evaluated") 1) 1) > a evaluated > a evaluated > 2 You write the expansion, so you are in control of multiple evaluation. Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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 -~--~~~~--~~--~--~---
Bug? Primitives get boxed if passed out of let.
On Thu, Jul 30, 2009 at 1:28 AM, John Harrop wrote: > user=> (loop [i 0 j (double 1.0)] > (if (= i 1) j (recur 1 (+ j j > 2.0 > user=> (loop [i 0 j (double 1.0)] > (if (= i 1) j (recur 1 (let [a j b j] (+ a b) > # java.lang.IllegalArgumentException: recur arg for primitive local: j must be > matching primitive (NO_SOURCE_FILE:0)> > user=> (loop [i 0 j (double 1.0)] > (if (= i 1) j (let [a j b j] (recur 1 (+ a b) > 2.0 > So when j is a lowercase-d double, inside (let [a j b j] ... ) a and b are > lowercase-d doubles, and (+ a b) is a lowercase-d double, but the type of > the expression (let [a j b j] (+ a b)) is apparently capital-D Double. > This seems like a bug to me, and could cripple performance in some > conceivable cases. Primitives should not get boxed when not passed across > function-call boundaries, and let is not a function. > Currently only host expressions and bindings to host expressions of primitive types can have primitives type. let expressions etc cannot. One reason is that let etc can have more than one 'type' by containing conditionals or making calls to polymorphic functions: ;let might have type double or String (let [j (double 42.0)] (if x j "42")) Currently there is no analysis to determine that potentially composite expressions yield a uniform type, which would be required to let a primitive flow out of a let. It would be a nice enhancement. Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Possible bug report
On Jul 29, 6:09 pm, Jason Wolfe wrote: > Is this a bug? > > user> (eval `(make-array ~Byte/TYPE 2)) > ; Evaluation aborted. (ExceptionInInitializerError) > > Compare: > > user> (eval `(make-array ~Byte 2)) > # > > user> (eval `(make-array Byte/TYPE 2)) > # > > user> (make-array (eval Byte/TYPE) 2) > # > > If not, can someone please help me understand what's going on here? > Yes, currently you cannot embed constants of primitive Class types. This arises from an asymmetry in Java: user=> (.getName Byte) "java.lang.Byte" user=> (Class/forName "java.lang.Byte") java.lang.Byte user=> (.getName Byte/TYPE) "byte" user=> (Class/forName "byte") java.lang.ClassNotFoundException: byte (NO_SOURCE_FILE:0) A patch to support reading, and embedded constants, of primitive Class objects would be welcome. The current print-dup support won't do it. If anyone is interested in contributing this patch please bring it up on the clojure-dev group before proceeding and I can give you some guidance as to what needs to be changed. Thanks for the report, Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Possible bug report
At my day job, we've always used a custom classloader to get around that asymmetry. -- Aaron On Thu, Jul 30, 2009 at 9:51 AM, Rich Hickey wrote: > > > > On Jul 29, 6:09 pm, Jason Wolfe wrote: > > Is this a bug? > > > > user> (eval `(make-array ~Byte/TYPE 2)) > > ; Evaluation aborted. (ExceptionInInitializerError) > > > > Compare: > > > > user> (eval `(make-array ~Byte 2)) > > # > > > > user> (eval `(make-array Byte/TYPE 2)) > > # > > > > user> (make-array (eval Byte/TYPE) 2) > > # > > > > If not, can someone please help me understand what's going on here? > > > > Yes, currently you cannot embed constants of primitive Class types. > This arises from an asymmetry in Java: > > user=> (.getName Byte) > "java.lang.Byte" > > user=> (Class/forName "java.lang.Byte") > java.lang.Byte > > user=> (.getName Byte/TYPE) > "byte" > > user=> (Class/forName "byte") > java.lang.ClassNotFoundException: byte (NO_SOURCE_FILE:0) > > A patch to support reading, and embedded constants, of primitive Class > objects would be welcome. The current print-dup support won't do it. > > If anyone is interested in contributing this patch please bring it up > on the clojure-dev group before proceeding and I can give you some > guidance as to what needs to be changed. > > Thanks for the report, > > Rich > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: java 1.4 class files
This is slightly unrelated, but... How much work would it be to run the old code on a Java 5/6 VM? I didn't get into Java until 5, so I'm not sure how much work is actually involved w/ upgrading a JVM installation. On Jul 30, 7:07 am, Frank Koenig wrote: > Thank you Stuart and Daniel for the help. I think I have to step back > from the idea to use clojure on this Java 1.4 project :-( > > Let's hope my next Java project addresses a less archaic Java version. --~--~-~--~~~---~--~~ You 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: Possible bug report
On Jul 30, 2009, at 6:51 AM, Rich Hickey wrote: > On Jul 29, 6:09 pm, Jason Wolfe wrote: >> Is this a bug? >> >> user> (eval `(make-array ~Byte/TYPE 2)) >> ; Evaluation aborted. (ExceptionInInitializerError) >> >> Compare: >> >> user> (eval `(make-array ~Byte 2)) >> # >> >> user> (eval `(make-array Byte/TYPE 2)) >> # >> >> user> (make-array (eval Byte/TYPE) 2) >> # >> >> If not, can someone please help me understand what's going on here? >> > > Yes, currently you cannot embed constants of primitive Class types. > This arises from an asymmetry in Java: > > user=> (.getName Byte) > "java.lang.Byte" > > user=> (Class/forName "java.lang.Byte") > java.lang.Byte > > user=> (.getName Byte/TYPE) > "byte" > > user=> (Class/forName "byte") > java.lang.ClassNotFoundException: byte (NO_SOURCE_FILE:0) > > A patch to support reading, and embedded constants, of primitive Class > objects would be welcome. The current print-dup support won't do it. > > If anyone is interested in contributing this patch please bring it up > on the clojure-dev group before proceeding and I can give you some > guidance as to what needs to be changed. > > Thanks for the report, > > Rich Thanks for the clear explanation. -Jason --~--~-~--~~~---~--~~ You 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: Bug? Definline arguments multiply evaluated.
Hello, I am not sure to agree. If I get it right, definline is used to replace defn for function that we want to be inlined. So replacing defn by definline should have no impact on the semantic of the program. Best regards, Nicolas. On Thu, 2009-07-30 at 05:34 -0700, Rich Hickey wrote: > > > On Jul 30, 1:29 am, John Harrop wrote: > > user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b))) > > #'hxr.clj.util/addsq > > user=> (addsq (do (println "a evaluated") 1) 1) > > a evaluated > > a evaluated > > 2 > > You write the expansion, so you are in control of multiple evaluation. > > Rich > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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 -~--~~~~--~~--~--~---
Good memory profilers (program or human)?
I'm gradually adding a few more Clojure benchmark programs to my repository here: git://github.com/jafingerhut/clojure-benchmarks.git The one I wrote for the "reverse-complement" benchmark is here: http://github.com/jafingerhut/clojure-benchmarks/blob/4ab4f41c6f963445e1e0973a668ac64939be1c7f/rcomp/revcomp.clj-4.clj revcomp.clj-4.clj is the best I've got so far, but it runs out of memory on the full size benchmark. If you clone the repository, and successfully run the init.sh script to generate the big input and expected output files, the file rcomp/ long-input.txt contains 3 DNA sequences in FASTA format. The first is 50,000,000 characters long, the second is 75,000,000 characters long, and the third is 125,000,000 characters long. Each needs to be reversed, have each character replaced with a different one, and printed out, so we need to store each of the strings one at a time, but it is acceptable to deallocate/garbage-collect the previous one when starting on the next. I think my code should be doing that, but I don't know how to verify that. I've read that a Java String takes 2 bytes per character, plus about 38 bytes of overhead per string. That is about 250 Mbytes for the longest one. I also read in a seq of lines, and these long strings are split into lines with 60 characters (plus a newline) each. Thus the string's data needs to be stored at least twice temporarily -- once for the many 60-character strings, plus the final long one. Also, the Java StringBuilder that Clojure's (str ...) function uses probably needs to be copied and reallocated periodically as it outgrows its current allocation. So I could imagine needing about 3 * 250 Mbytes temporarily, but that doesn't explain why my 1536 Mbytes of JVM memory are being exhausted. It would be possible to improve things by not creating all of the separate strings, one for each line, and then concatenating them together. But first I'd like to explain why it is using so much, because I must be missing something. Thank, Andy --~--~-~--~~~---~--~~ You 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: Bug? Definline arguments multiply evaluated.
On Thu, Jul 30, 2009 at 1:26 PM, Nicolas Oury wrote: > > Hello, > > I am not sure to agree. > > If I get it right, definline is used to replace defn for function that > we want to be inlined. > > So replacing defn by definline should have no impact on the semantic of > the program. > The docs for definline state it is expansion like macro expansion. Rich > > On Thu, 2009-07-30 at 05:34 -0700, Rich Hickey wrote: >> >> >> On Jul 30, 1:29 am, John Harrop wrote: >> > user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b))) >> > #'hxr.clj.util/addsq >> > user=> (addsq (do (println "a evaluated") 1) 1) >> > a evaluated >> > a evaluated >> > 2 >> >> You write the expansion, so you are in control of multiple evaluation. >> >> Rich >> > > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Bug? Definline arguments multiply evaluated.
BTW, is definline still considered experimental (I know it is still mentioned in the doc, just asking whether it's up to date or not) ? 2009/7/30 Stuart Halloway > > The documentation is explicit that definline observes defmacro-like > semantics. > > A.K.A. "What Rich said" :-) > > Stu > > > Hello, > > > > I am not sure to agree. > > > > If I get it right, definline is used to replace defn for function that > > we want to be inlined. > > > > So replacing defn by definline should have no impact on the semantic > > of > > the program. > > > > > > Best regards, > > > > > > Nicolas. > > > > On Thu, 2009-07-30 at 05:34 -0700, Rich Hickey wrote: > >> > >> > >> On Jul 30, 1:29 am, John Harrop wrote: > >>> user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b))) > >>> #'hxr.clj.util/addsq > >>> user=> (addsq (do (println "a evaluated") 1) 1) > >>> a evaluated > >>> a evaluated > >>> 2 > >> > >> You write the expansion, so you are in control of multiple > >> evaluation. > >> > >> Rich > >>> > > > > > > > > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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 -~--~~~~--~~--~--~---
struct-map niggle
I understand what's going on here (and I don't regard it as a bug that needs fixing) but I thought I'd share something that caught me off- guard, and perhaps should be mentioned in the docs for struct-maps. Clojure 1.0.0- user=> (defstruct foo :bar :baz) #'user/foo user=> (def foo-bar (accessor foo :bar)) #'user/foo-bar user=> (= (struct foo 1 2) (eval (struct foo 1 2))) true user=> (foo-bar (struct foo 1 2)) 1 user=> (foo-bar (eval (struct foo 1 2))) java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.PersistentStructMap (NO_SOURCE_FILE:0) i.e., struct-map-ness does not persist through evaluation. Client code must either avoid accessors for data that might be evaluated, or post-process the result of calling eval. I have a defstruct* macro that defines a structure and its accessors, so it's straightforward for me to also define a map->foo function that rebuilds the struct from the resultant map. -R --~--~-~--~~~---~--~~ You 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: Bug? Definline arguments multiply evaluated.
The documentation is explicit that definline observes defmacro-like semantics. A.K.A. "What Rich said" :-) Stu > Hello, > > I am not sure to agree. > > If I get it right, definline is used to replace defn for function that > we want to be inlined. > > So replacing defn by definline should have no impact on the semantic > of > the program. > > > Best regards, > > > Nicolas. > > On Thu, 2009-07-30 at 05:34 -0700, Rich Hickey wrote: >> >> >> On Jul 30, 1:29 am, John Harrop wrote: >>> user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b))) >>> #'hxr.clj.util/addsq >>> user=> (addsq (do (println "a evaluated") 1) 1) >>> a evaluated >>> a evaluated >>> 2 >> >> You write the expansion, so you are in control of multiple >> evaluation. >> >> Rich >>> > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: struct-map niggle
The problem is you aren't quoting the forms fed to eval. This: (eval (struct foo 1 2)) mean this: (eval {:bar 1 :baz 2}) And small literal maps are eval'd as a PersistentArrayMap Now if instead you do: (eval '(struct foo 1 2)) then eval is eval'ing the form (struct foo 1 2), thus the return from eval is as you would expect: user=> (foo-bar (eval '(struct foo 1 2))) 1 On Jul 30, 11:57 am, Richard Newman wrote: > I understand what's going on here (and I don't regard it as a bug that > needs fixing) but I thought I'd share something that caught me off- > guard, and perhaps should be mentioned in the docs for struct-maps. > > Clojure 1.0.0- > user=> (defstruct foo :bar :baz) > #'user/foo > user=> (def foo-bar (accessor foo :bar)) > #'user/foo-bar > user=> (= (struct foo 1 2) (eval (struct foo 1 2))) > true > user=> (foo-bar (struct foo 1 2)) > 1 > user=> (foo-bar (eval (struct foo 1 2))) > java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot > be cast to clojure.lang.PersistentStructMap (NO_SOURCE_FILE:0) > > i.e., struct-map-ness does not persist through evaluation. > > Client code must either avoid accessors for data that might be > evaluated, or post-process the result of calling eval. I have a > defstruct* macro that defines a structure and its accessors, so it's > straightforward for me to also define a map->foo function that > rebuilds the struct from the resultant map. > > -R --~--~-~--~~~---~--~~ You 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: struct-map niggle
> The problem is you aren't quoting the forms fed to eval. That was intentional. Imagine a broader example, where I want to read in a form, examine/print/etc. parts of it, then evaluate it. Printing a struct-map produces map syntax. Reading the output produces a literal map with unevaluated contents. E.g., user=> (read-string "{:foo (fn [x] (+ 1 x)) :bar 2}") {:foo (fn [x] (+ 1 x)), :bar 2} ;; Now I can examine the syntactic form of the function, but fetch it with (:foo x). ;; I can eval this to get a final object. user=> (eval *1) {:foo #, :bar 2} Evaluating the read forms produces a literal map with evaluated contents. Modulo unreadable things like functions, the original struct- map and the read+eval'ed struct map are identical, but have different types. > This: >(eval (struct foo 1 2)) > mean this: >(eval {:bar 1 :baz 2}) > > And small literal maps are eval'd as a PersistentArrayMap I know. The reason this is a gotcha is that -- just like sorted maps and sets -- these data structures are not quite homoiconic. That is, reading the printed representation of a data structure returns a structure with similar but different properties. If I wasn't using accessors, it would never have occurred to me that my in-memory struct maps would come back as plain ol' maps. It doesn't confound me, I just didn't think of it in advance. > Now if instead you do: >(eval '(struct foo 1 2)) > then eval is eval'ing the form (struct foo 1 2), thus the return from > eval is as you would expect: > > user=> (foo-bar (eval '(struct foo 1 2))) Indeed. That is all basic stuff that a novice Lisper would know. The scenario here, though, is different: given an *existing* struct- map (which prints as {:foo 1 :bar 2} -- not a form), one cannot print it in such a way that the struct-map-ness is preserved when it is re- read. You can discover that it's a struct-map (type => PersistentStructMap), but not what kind of struct-map it is. The same is true of sorted maps and sets, and assorted other data structures. Clojure's situation is much better than that of Common Lisp, and (as I said) I don't regard it as a bug that not all attributes of a structure are preserved through printing and re- reading, but I thought others might benefit from my experience… particularly because accessors would seem to offer additional speed for free. -R --~--~-~--~~~---~--~~ You 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: struct-map niggle
On Thu, Jul 30, 2009 at 4:20 PM, Richard Newman wrote: > > The scenario here, though, is different: given an *existing* struct- > map (which prints as {:foo 1 :bar 2} -- not a form), one cannot print > it in such a way that the struct-map-ness is preserved when it is re- > read. You can discover that it's a struct-map (type => > PersistentStructMap), but not what kind of struct-map it is. > > The same is true of sorted maps and sets, and assorted other data > structures. Are you aware of *print-dup* ? It causes the printer to preserve more of the specific type information than normal printing: user=> (binding [*print-dup* true] (prn (hash-map :a 1, :b 2))) {:a 1, :b 2} nil user=> (binding [*print-dup* true] (prn (sorted-map :a 1, :b 2))) #=(clojure.lang.PersistentTreeMap/create {:a 1, :b 2}) nil user=> (binding [*print-dup* true] (prn {:a 1, :b 2})) #=(clojure.lang.PersistentArrayMap/create {:a 1, :b 2}) nil The #=() is an intentionally under-documented reader macro specifically to allow such preservation. Having said that, it's important to note it doesn't help your original scenario, because *print-dup* doesn't support struct maps (yet): (-> (binding [*print-dup* true] (prn-str (struct foo 1 2))) java.io.StringReader. java.io.PushbackReader. read class) java.lang.IllegalArgumentException: No matching method found: create (NO_SOURCE_FILE:0) sorted-maps work, but lose any custom sort-by fn: (-> (binding [*print-dup* true] (prn-str (sorted-map :a 1, :b 2))) java.io.StringReader. java.io.PushbackReader. read class) clojure.lang.PersistentTreeMap (-> (binding [*print-dup* true] (prn-str (sorted-map-by #(compare %2 %1) :a 1, :b 2))) java.io.StringReader. java.io.PushbackReader. read) {:a 1, :b 2} --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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 -~--~~~~--~~--~--~---
Idiomatic parsing of objects from several lines of a text file
I'm trying to find an idiomatic way to read through a text file (e.g. a Git history log) where an object will be represented by several lines of text, and when we find a line that starts a new entry we create the old entry and continue. For example here's my first clumsy attempt. Can anybody advise on how to do this in a more functional style? (def *line-re* #"[^\n]{1,}") (defstruct commit :id :parent :msg) (defn parse-log [filename] (let [text (slurp filename) lines (re-seq *line-re* text)] (with-local-vars [commits {} commit-id "" parent "" msg ""] (doseq [line lines] (if (.startsWith line "commit ") (do (if (not= @commit-id "") (do (var-set commits (conj @commits {...@commit-id (struct commit @commit-id @parent @msg)})) (var-set msg "") (var-set parent nil))) (var-set commit-id (subs line 7 (if (.startsWith line "parent ") (var-set parent (subs line 7))) (if (.startsWith line "") (var-set msg (str @msg "\n" (subs line 4) (var-set commits (assoc @commits @commit-id (struct commit @commit-id @parent @msg))) @commits))) --~--~-~--~~~---~--~~ You 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: Idiomatic parsing of objects from several lines of a text file
Hi, I would suggest to have a look at fnparse[1]. It's really cool. A commit-log parser might look like this: (def linebreak (alt (conc (opt (lit \return)) (lit \newline)) (lit \return))) (def hex-digit (alt-lit-seq "0123456789abcdef")) (def checksum (semantics (rep+ hex-digit) #(apply str %))) (def commit (complex [_ (conc-lit-seq "commit ") commit-id checksum _ linebreak _ (conc-lit-seq "parent ") parent-id checksum _ (rep= 2 linebreak) msg (semantics (rep* (except anything (conc linebreak (conc-lit-seq "commit " #(apply str %))] {:id commit-id :parent parent-id :message msg})) (def commit-log (rep* commit)) This should parse a log like: commit a2b5927f24c parent c726fe5211a This is the message commit 285abb36e12 parent 81f2e35bc61 Another message. The result would be: [{:id a2b5927f24c :parent c726fe5211a :message "This is\nthe\nmessage"} {:id 285abb36e12 :parent 81f2e35bc61 :message "Another\nmessage."}] Note, the code is not tested, but should be close. Hope this helps. Sincerely Meikel [1]: http://github.com/joshua-choi/fnparse/tree/master smime.p7s Description: S/MIME cryptographic signature
Re: struct-map niggle
> Are you aware of *print-dup* ? It causes the printer to > preserve more of the specific type information than normal > printing: It's one of those things that hasn't yet crept close enough on my radar for me to absorb. This is the impetus... > Having said that, it's important to note it doesn't help > your original scenario, because *print-dup* doesn't support > struct maps (yet): Ah, good and bad :) I expect there are plenty of dangerous edge cases to handle -- e.g., what to do if there is no struct by that name, or if it's a different struct with the same name. I suspect that in my case the right approach is either to switch to pure maps (which round-trip perfectly), or to take more control over the upstream serialization, and produce a (struct foo ...) form instead of just prn-ing the struct-map. I started down the avenue of converting maps into struct-maps, though, so perhaps I'll see how that turns out. This data is accessed much more often than it's loaded, so the overhead is likely worthwhile. Thanks for the discussion! -R --~--~-~--~~~---~--~~ You 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: Idiomatic parsing of objects from several lines of a text file
On 30 Jul 2009, at 2:26 PM, David Plumpton wrote: > I'm trying to find an idiomatic way to read through a text file (e.g. > a Git history log) Sidenote: I'm hacking on this: http://github.com/rnewman/clj-git/tree/master I haven't got to commit messages etc. yet -- I'm primarily using git as a backing store, not accessing existing repositories, so there are much more pressing things -- but there might be something useful there for you. The usual caveats of hacky, bad, probably-buggy code apply :) -R --~--~-~--~~~---~--~~ You 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: Bug? Definline arguments multiply evaluated.
On Thu, Jul 30, 2009 at 2:52 PM, Laurent PETIT wrote: > BTW, > > is definline still considered experimental (I know it is still mentioned in > the doc, just asking whether it's up to date or not) ? > Yes, still experimental. Rich > 2009/7/30 Stuart Halloway >> >> The documentation is explicit that definline observes defmacro-like >> semantics. >> >> A.K.A. "What Rich said" :-) >> >> Stu >> >> > Hello, >> > >> > I am not sure to agree. >> > >> > If I get it right, definline is used to replace defn for function that >> > we want to be inlined. >> > >> > So replacing defn by definline should have no impact on the semantic >> > of >> > the program. >> > >> > >> > Best regards, >> > >> > >> > Nicolas. >> > >> > On Thu, 2009-07-30 at 05:34 -0700, Rich Hickey wrote: >> >> >> >> >> >> On Jul 30, 1:29 am, John Harrop wrote: >> >>> user=> (definline addsq [a b] `(+ (* ~a ~a) (* ~b ~b))) >> >>> #'hxr.clj.util/addsq >> >>> user=> (addsq (do (println "a evaluated") 1) 1) >> >>> a evaluated >> >>> a evaluated >> >>> 2 >> >> >> >> You write the expansion, so you are in control of multiple >> >> evaluation. >> >> >> >> Rich >> >>> >> > >> > >> > > >> >> >> > > > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: struct-map niggle
On Jul 30, 5:03 pm, Chouser wrote: > Are you aware of *print-dup* ? It causes the printer to > preserve more of the specific type information than normal > printing: > > user=> (binding [*print-dup* true] (prn (hash-map :a 1, :b 2))) > {:a 1, :b 2} > nil > user=> (binding [*print-dup* true] (prn (sorted-map :a 1, :b 2))) > #=(clojure.lang.PersistentTreeMap/create {:a 1, :b 2}) > nil This doesn't actually work for structs, which may be a bug. That is, you can prn a struct, but you can't read it back in. -SS --~--~-~--~~~---~--~~ You 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: Idiomatic parsing of objects from several lines of a text file
What is this convention you are using with the -> ? Are you coming from a C or C++ background or is this something lispy I haven't seen before? -- Aaron On Thu, Jul 30, 2009 at 7:56 PM, Richard Newman wrote: > > On 30 Jul 2009, at 2:26 PM, David Plumpton wrote: > > > I'm trying to find an idiomatic way to read through a text file (e.g. > > a Git history log) > > Sidenote: I'm hacking on this: > > http://github.com/rnewman/clj-git/tree/master > > I haven't got to commit messages etc. yet -- I'm primarily using git > as a backing store, not accessing existing repositories, so there are > much more pressing things -- but there might be something useful there > for you. > > The usual caveats of hacky, bad, probably-buggy code apply :) > > -R > > > > > --~--~-~--~~~---~--~~ You 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: Idiomatic parsing of objects from several lines of a text file
> What is this convention you are using with the -> ? > > Are you coming from a C or C++ background or is this something lispy > I haven't seen before? A fair proportion of Common Lispers do that (though I've witnessed debates about its merit, usually in the context of low-level code where the symbols are already cluttered with [-_+>] etc), exploiting the much richer options for symbol names than most languages. It's certainly not a dereferencing operation, which is the only context in which it would arise for a C/C++ user. Usually it means "to", either as a conversion or lookup. (defn ref->commit [ref] ...) thus means "take this ref and give me the corresponding commit (in the context of this repo)". Similarly, (defn tree-entry->map [e] ...) takes a Git tree entry string and returns a Clojure map that represents it. This is slightly less confusing than `tree-entry-map`, which could very well mean some mapping construct over a tree entry, or a map of multiple tree entries, or something else. I haven't been entirely consistent, though -- witness `tree-entry- seq`, which should really be `tree-entry->seq`. I said it was a work in progress :) I suppose in Clojure we could use a real arrow character, with UTF-8 available in symbol names... -R --~--~-~--~~~---~--~~ You 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: Keyword not serializable
It turns out that a framework we've been using is able to serialize *any* Java class, whether it implements Serializable or not -- so, we've been happily serializing keywords without them explicitly supporting it for some time. However, making Keyword formally Serializable has other benefits, specifically that a proper patch would ensure that deserialized Keywords are interned as one would expect out. So, I may make a run at this sooner rather than later... - Chas On Jul 24, 7:06 pm, Chris Kent wrote: > Hi > > Are there any fundamental reasons why the Keyword class shouldn't be > serializable? I've been playing around with Clojure and Wicket and > it's not possible to use maps containingKeywordsin Wicket page > classes. Wicket pages are serialized and stored in the session > between requests and this fails if the page refers to anyKeywords. > UsingKeywordsin maps is common in Clojure (and in clj-record in > particular) and it would be a really useful change. > > I'd be happy to supply a (very small) patch if people think it's a > good idea. > > Thanks > Chris --~--~-~--~~~---~--~~ You 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: Idiomatic parsing of objects from several lines of a text file
On Jul 30, 2009, at 7:24 PM, Aaron Cohen wrote: > Are you coming from a C or C++ background or is this something lispy > I haven't seen before? I first ran into this in Scheme, where I think its use is somewhat more idiomatic than in CL. As the author observes, it's generally used instead of "to" in the CL libraries on my system, though it wouldn't surprise me much to see it used in code wrapping C structures. CL usually takes the most verbose option available, confirmed anecdotally by 241 occurrences of "-to-" in a function name in the selection of libraries on my system, versus 129 occurrences of "->." This structure is even employed in SRFI #4, published in 1998, suggesting that its use in the Scheme community has been uncontroversial for at least 11 years. Scheme has always prized a terse kind of elegance where Lisp has sought comprehensiveness. On Jul 30, 2009, at 7:37 PM, Richard Newman wrote: > I suppose in Clojure we could use a real arrow character, with UTF-8 > available in symbol names... Clojure being the 21st century language it is, I would be delighted to see '¬ instead of 'not, 'ƒ instead of 'fn, '∑ instead of a hypothetical 'sum builtin, and → instead of ->. I'm sure I'd enjoy reading code with such conventions, but I think I would find typing it out is somewhat tedious. You might find the Emacs mode "Pretty Lambda" to be useful; the effect on Haskell code is really quite nice: http://alexott.blogspot.com/2009/02/emacs-haskell-pretty-lambda.html It can be customized for other languages, but I can't find any references to anyone doing it with Clojure yet. Details on the mode here: http://www.emacswiki.org/emacs/PrettyLambda — Daniel Lyons --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~---