Bug report -- macros within let [Re: Bizarre behavior (bug?) for unchecked-add]
I have more information on this now, and it is definitely a bug in Clojure -- defmacro within a let doesn't work correctly. Consider the following file: --- BEGIN foo1a.coj --- (ns com.ksvanhorn.foo1a) (let [dummy 0] (defmacro add [& args] `(unchecked-add ~...@args)) (defmacro mul [& args] `(unchecked-multiply ~...@args)) (let [magic 1812433253 x 5489 v (add 1 (mul magic x))] (println (str "v: " v --- END --- If I type "(use 'com.ksvanhorn.foo1a)" at the REPL, I get v: (clojure.core/unchecked-add 1 (clojure.core/unchecked-multiply 1812433253 5489)) printed out and nil returned, but if I just type (uncheck-add 1 (unchecked-multiply 1812433253 5489)) I get 1301868182. Although in this case the defmacro doesn't need to be inside the let, I actually have a real need for doing defmacro inside a let -- I have a computed constant that I want to use in several places, and one of those places is in the macro definition. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Bit-level operations
> Or maybe just: > (defn mo [op & args] (reduce op args)) I believe that won't make clojure make a faster code, but I might be wrong. I think the macroexpansion is the right thing if you want speed, as it seems clojure could optimize well this: (+ a b) while it can't optimize this well (+ a b c) if a, b, c are say floating point numbers. Off course this was gathered by experimenting. If in future clojure provides something like CL's compiler-macro it might be used to make such expansions easier. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Bit-level operations
On Fri, Apr 24, 2009 at 6:33 AM, Dimiter "malkia" Stanev wrote: > > Here's even more concise version: > > (defmacro mo [op & args] > (reduce (fn [& ab#] (cons op ab#)) args)) Or maybe just: (defn mo [op & args] (reduce op args)) I don't think that's the point, though. Why not allow bit-and and bit-or to accept multiple arguments? I don't see how doing so would break any existing code or be a bad idea. -- Michael Wood --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Bit-level operations
On Apr 24, 2:57 am, Kevin Van Horn wrote: > 1. bit-and, bit-or, and bit-xor only take two arguments. These are > all associative operations, and as such should take an arbitrary > number of arguments for the same reason that + and * take arbitrary > number of arguments: I totally agree. I have raised the same question back in December last year but nothing conclusive resulted from that apart from a sample implementation: http://groups.google.com/group/clojure/browse_thread/thread/c0737733812838d1 But I would rather like to see something like this in clojure.core too. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Bizarre behavior (bug?) for unchecked-add
When unchecked-add is given an invalid argument, sometimes it throws an exception, and sometimes it does something very weird -- it returns the code for the call! Referring to the files foo1.clj and foo2.clj below, if I type at the REPL (use 'com.ksvanhorn.foo2) I get "java.lang.IllegalArgumentException: No matching method found: unchecked_add (foo2.clj:0)", which is unsurprising, as (* magic x) is much too large to fit into an int. However, if I type (use 'com.ksvanhorn.foo1) I get "v: (clojure.core/unchecked-add 1 9948446125717)" printed out and nil returned, with no exception thrown. The only difference between foo1.clj and foo2.clj is that foo1.clj uses a macro defined within a let. If I replace the macro call with its expansion, or if I define the macro outside of the let, then I get the same behavior as for foo2.clj. --- BEGIN foo1.clj --- (ns com.ksvanhorn.foo1) (let [dummy 0] (defmacro add [& args] `(unchecked-add ~...@args)) (let [magic 1812433253 x 5489 v (add 1 (* magic x))] (println (str "v: " v --- END --- --- BEGIN foo2.clj --- (ns com.ksvanhorn.foo2) (let [magic 1812433253 x 5489 v (unchecked-add 1 (* magic x))] (println (str "v: " v --- END --- --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to have one lib with source in multiple files
billh04, have a look at the compojure project (http://github.com/weavejester/compojure/tree/master). In that James uses an "immigrate" function which may be useful to you. Also the structure used is a good example of a reasonably large, quite complex project. Hth, Adrian. On Fri, Apr 24, 2009 at 7:23 AM, Laurent PETIT wrote: > > Hi, > > Please note that a convention (but it's really just one convention) > could also be to name file for partB : place_partB.clj (or even > place_part_b.clj since in clojure camel case notation is not the > preferred way to write things, hyphens and lower cases are -> but > hyphens must be replaces by underscores in package/namespace names, > and in file names). > > Your solution is acceptable I think (having the load at the end of the > root file). > You could also consider this one: > > place.clj === > (ns whale.achi.model.place > (:load "place/partA") > (:load "place/partB")) > == > > place/partA.clj === > (in-ns 'whale.achi.model.place) > partA > == > > place/partB.clj === > (in-ns 'whale.achi.model.place) > partB > == > > Or, to write it like it is done for clojure.core: > > place.clj === > (ns whale.achi.model.place > (:load "place_part_a") > (:load "place_part_b")) > == > > place_part_a.clj === > (in-ns 'whale.achi.model.place) > partA > == > > place_part_b.clj === > (in-ns 'whale.achi.model.place) > partB > == > > > HTH, > > -- > Laurent > > > 2009/4/24 billh04 : >> >> I don't think I explained my need clearly. >> >> I try to rephrase it. Suppose I have a source file named place.clj in >> a directory named whale/achi/model like the following: >> >> place.clj >> (ns whale.achi.model.place) >> partA >> partB >> == >> >> What I want to do is to keep the same namespace but break it into two >> files named place.clj as above and placeEvaluation.clj in a >> subdirectory place: >> >> place.clj === >> (ns whale.achi.model.place >> (:load "place/placeEvaluation")) >> partA >> == >> >> >> placeEvaluation.clj === >> partB >> == >> >> When, I do this, I get the error message: >> >> java.lang.Exception: Unable to resolve symbol: -boardPlaces- in this >> context (placeEvaluation.clj:19) >> >> since -boardPlaces- is defined in partA, but has not been loaded yet >> (I suspect). >> >> I believe the following will work since partA is loaded before partB: >> >> place.clj === >> (ns whale.achi.model.place) >> partA >> (load "place/placeEvaluation") >> == >> >> >> placeEvaluation.clj === >> partB >> == >> >> What I am seeking is how to split a file for one namespace into >> multiple files with the same namespace. >> >> Also, any source file that wants to use the namespace >> 'whale.achi.model.place would need only 'use 'whale.achi.model.place >> and would not have to worrry about placeEvaluation but get that loaded >> for free. >> >> On Apr 23, 9:29 pm, Drew Raines wrote: >>> billh04 wrote: >>> > Right now I have the two files "whale.achi.model.place.clj" and >>> > "whale.achi.model.placeEvaluation.clj" that make up one name space >>> > "whale.achi.model.place". >>> > The first file is the "root" of the namespace. >>> >>> I think you're confused with how Clojure looks for packages in the >>> filesystem. Perhaps you want: >>> >>> $ find whale >>> whale/achi/model/place.clj >>> whale/achi/model/place/evaluation.clj >>> $ head -2 whale/achi/model/place.clj >>> (ns whale.achi.model.place >>> (:require [whale.achi.model.place.evaluation :as eval])) >>> $ head -1 whale/achi/model/place/evaluation.clj >>> (ns whale.achi.model.place.evaluation) >>> >>> -Drew >> > >> > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to have one lib with source in multiple files
Hi, Please note that a convention (but it's really just one convention) could also be to name file for partB : place_partB.clj (or even place_part_b.clj since in clojure camel case notation is not the preferred way to write things, hyphens and lower cases are -> but hyphens must be replaces by underscores in package/namespace names, and in file names). Your solution is acceptable I think (having the load at the end of the root file). You could also consider this one: place.clj === (ns whale.achi.model.place (:load "place/partA") (:load "place/partB")) == place/partA.clj === (in-ns 'whale.achi.model.place) partA == place/partB.clj === (in-ns 'whale.achi.model.place) partB == Or, to write it like it is done for clojure.core: place.clj === (ns whale.achi.model.place (:load "place_part_a") (:load "place_part_b")) == place_part_a.clj === (in-ns 'whale.achi.model.place) partA == place_part_b.clj === (in-ns 'whale.achi.model.place) partB == HTH, -- Laurent 2009/4/24 billh04 : > > I don't think I explained my need clearly. > > I try to rephrase it. Suppose I have a source file named place.clj in > a directory named whale/achi/model like the following: > > place.clj > (ns whale.achi.model.place) > partA > partB > == > > What I want to do is to keep the same namespace but break it into two > files named place.clj as above and placeEvaluation.clj in a > subdirectory place: > > place.clj === > (ns whale.achi.model.place > (:load "place/placeEvaluation")) > partA > == > > > placeEvaluation.clj === > partB > == > > When, I do this, I get the error message: > > java.lang.Exception: Unable to resolve symbol: -boardPlaces- in this > context (placeEvaluation.clj:19) > > since -boardPlaces- is defined in partA, but has not been loaded yet > (I suspect). > > I believe the following will work since partA is loaded before partB: > > place.clj === > (ns whale.achi.model.place) > partA > (load "place/placeEvaluation") > == > > > placeEvaluation.clj === > partB > == > > What I am seeking is how to split a file for one namespace into > multiple files with the same namespace. > > Also, any source file that wants to use the namespace > 'whale.achi.model.place would need only 'use 'whale.achi.model.place > and would not have to worrry about placeEvaluation but get that loaded > for free. > > On Apr 23, 9:29 pm, Drew Raines wrote: >> billh04 wrote: >> > Right now I have the two files "whale.achi.model.place.clj" and >> > "whale.achi.model.placeEvaluation.clj" that make up one name space >> > "whale.achi.model.place". >> > The first file is the "root" of the namespace. >> >> I think you're confused with how Clojure looks for packages in the >> filesystem. Perhaps you want: >> >> $ find whale >> whale/achi/model/place.clj >> whale/achi/model/place/evaluation.clj >> $ head -2 whale/achi/model/place.clj >> (ns whale.achi.model.place >> (:require [whale.achi.model.place.evaluation :as eval])) >> $ head -1 whale/achi/model/place/evaluation.clj >> (ns whale.achi.model.place.evaluation) >> >> -Drew > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Bit-level operations
Here's even more concise version: (defmacro mo [op & args] (reduce (fn [& ab#] (cons op ab#)) args)) On Apr 23, 9:23 pm, "Dimiter \"malkia\" Stanev" wrote: > You can make your own macro to do that: > > (defmacro mo [op & args] > (reduce (fn [a# b#] (cons op [a# b#])) args)) > > (mo + 1 2 3 4) > > (print "expanded=" (macroexpand '(mo + 1 2 3 4)) "\n") > > ;expanded= (+ (+ (+ 1 2) 3) 4) > > On Apr 23, 5:57 pm, Kevin Van Horn wrote: > > > > > I'm writing an application that needs fast, high-quality random number > > generation, so I've been implementing a Mersenne Twister random number > > generator. I'm finding that bit-twiddling in Clojure can be a "bit" > > awkward. Here are some specifics: > > > 1. bit-and, bit-or, and bit-xor only take two arguments. These are > > all associative operations, and as such should take an arbitrary > > number of arguments for the same reason that + and * take arbitrary > > number of arguments: so you can write, e.g., > > > (op a1 a2 a3 a4) > > > instead of > > > (op (op (op a1 a2) a3) a4) > > > 2. There is no direct support for word-level, unsigned shifts. That > > is, I want to treat an int as the equivalent 32-bit unsigned value > > when I do the shift, shifting in 0 bits and dropping the bits that > > shift past the word boundaries. > > > It took a while to figure out how to do this correctly; the biggest > > problem was avoiding the propagation of the sign bit on a right > > shift. After experimenting around for a while I figured out that > > these will work: > > > * Left-shift x by n bits: (int (bit-shift-left x n)). > > > * Right-shift x by n bits: (int (bit-shift-right (bit-and intmask x) n)) > > where intmask = 2^32 - 1. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Bit-level operations
You can make your own macro to do that: (defmacro mo [op & args] (reduce (fn [a# b#] (cons op [a# b#])) args)) (mo + 1 2 3 4) (print "expanded=" (macroexpand '(mo + 1 2 3 4)) "\n") ;expanded= (+ (+ (+ 1 2) 3) 4) On Apr 23, 5:57 pm, Kevin Van Horn wrote: > I'm writing an application that needs fast, high-quality random number > generation, so I've been implementing a Mersenne Twister random number > generator. I'm finding that bit-twiddling in Clojure can be a "bit" > awkward. Here are some specifics: > > 1. bit-and, bit-or, and bit-xor only take two arguments. These are > all associative operations, and as such should take an arbitrary > number of arguments for the same reason that + and * take arbitrary > number of arguments: so you can write, e.g., > > (op a1 a2 a3 a4) > > instead of > > (op (op (op a1 a2) a3) a4) > > 2. There is no direct support for word-level, unsigned shifts. That > is, I want to treat an int as the equivalent 32-bit unsigned value > when I do the shift, shifting in 0 bits and dropping the bits that > shift past the word boundaries. > > It took a while to figure out how to do this correctly; the biggest > problem was avoiding the propagation of the sign bit on a right > shift. After experimenting around for a while I figured out that > these will work: > > * Left-shift x by n bits: (int (bit-shift-left x n)). > > * Right-shift x by n bits: (int (bit-shift-right (bit-and intmask x) n)) > where intmask = 2^32 - 1. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to have one lib with source in multiple files
I don't think I explained my need clearly. I try to rephrase it. Suppose I have a source file named place.clj in a directory named whale/achi/model like the following: place.clj (ns whale.achi.model.place) partA partB == What I want to do is to keep the same namespace but break it into two files named place.clj as above and placeEvaluation.clj in a subdirectory place: place.clj === (ns whale.achi.model.place (:load "place/placeEvaluation")) partA == placeEvaluation.clj === partB == When, I do this, I get the error message: java.lang.Exception: Unable to resolve symbol: -boardPlaces- in this context (placeEvaluation.clj:19) since -boardPlaces- is defined in partA, but has not been loaded yet (I suspect). I believe the following will work since partA is loaded before partB: place.clj === (ns whale.achi.model.place) partA (load "place/placeEvaluation") == placeEvaluation.clj === partB == What I am seeking is how to split a file for one namespace into multiple files with the same namespace. Also, any source file that wants to use the namespace 'whale.achi.model.place would need only 'use 'whale.achi.model.place and would not have to worrry about placeEvaluation but get that loaded for free. On Apr 23, 9:29 pm, Drew Raines wrote: > billh04 wrote: > > Right now I have the two files "whale.achi.model.place.clj" and > > "whale.achi.model.placeEvaluation.clj" that make up one name space > > "whale.achi.model.place". > > The first file is the "root" of the namespace. > > I think you're confused with how Clojure looks for packages in the > filesystem. Perhaps you want: > > $ find whale > whale/achi/model/place.clj > whale/achi/model/place/evaluation.clj > $ head -2 whale/achi/model/place.clj > (ns whale.achi.model.place > (:require [whale.achi.model.place.evaluation :as eval])) > $ head -1 whale/achi/model/place/evaluation.clj > (ns whale.achi.model.place.evaluation) > > -Drew --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to have one lib with source in multiple files
billh04 wrote: > Right now I have the two files "whale.achi.model.place.clj" and > "whale.achi.model.placeEvaluation.clj" that make up one name space > "whale.achi.model.place". > The first file is the "root" of the namespace. I think you're confused with how Clojure looks for packages in the filesystem. Perhaps you want: $ find whale whale/achi/model/place.clj whale/achi/model/place/evaluation.clj $ head -2 whale/achi/model/place.clj (ns whale.achi.model.place (:require [whale.achi.model.place.evaluation :as eval])) $ head -1 whale/achi/model/place/evaluation.clj (ns whale.achi.model.place.evaluation) -Drew --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Got a Clojure user group?
Thanks all - the list is here: http://clojure.org/community More additions welcome! Rich On Apr 15, 1:48 pm, Amit Rathore wrote: > Hi Rich, > > Bay Area Clojure User > Grouphttp://www.meetup.com/The-Bay-Area-Clojure-User-Group/ > > Thanks! > > Regards, > Amit Rathore. > > On Apr 9, 12:00 pm, Rich Hickey wrote: > > > Got a Clojure user group, meetup etc? > > > Reply to this message and let me know, I'll add them to the Clojure > > site. > > > Please supply a primary URL for getting info for your group. > > > Thanks! > > > Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Bit-level operations
I'm writing an application that needs fast, high-quality random number generation, so I've been implementing a Mersenne Twister random number generator. I'm finding that bit-twiddling in Clojure can be a "bit" awkward. Here are some specifics: 1. bit-and, bit-or, and bit-xor only take two arguments. These are all associative operations, and as such should take an arbitrary number of arguments for the same reason that + and * take arbitrary number of arguments: so you can write, e.g., (op a1 a2 a3 a4) instead of (op (op (op a1 a2) a3) a4) 2. There is no direct support for word-level, unsigned shifts. That is, I want to treat an int as the equivalent 32-bit unsigned value when I do the shift, shifting in 0 bits and dropping the bits that shift past the word boundaries. It took a while to figure out how to do this correctly; the biggest problem was avoiding the propagation of the sign bit on a right shift. After experimenting around for a while I figured out that these will work: * Left-shift x by n bits: (int (bit-shift-left x n)). * Right-shift x by n bits: (int (bit-shift-right (bit-and intmask x) n)) where intmask = 2^32 - 1. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: The Path to 1.0
On Apr 23, 11:24 am, Laurent PETIT wrote: > 2009/4/23 Rich Hickey : > > > > > On Apr 22, 12:41 pm, Laurent PETIT wrote: > >> 2009/4/22 Rich Hickey : > > >> > [...] > >> > {:major 1, :minor 0, :incremental 0, :qualifier :rc1 :interim true} > > >> > for interim versions and > > >> > {:major 1, :minor 0, :incremental 0} > > >> > for releases. :interim tracks the SNAPSHOT segment of the version > >> > string. > >> > [...] > >> > I don't mind the build producing clojure-1.0.0.jar etc, but it doesn't > >> > now. The master build is Ant. Where is the best place to put the > >> > version info so it can be leveraged by Ant, Maven and the clojure core > >> > runtime in order to produce *clojure-version* ? > > >> Here a patch that allows to initialize from ant and from a file > >> version.properties the values in *clojure-version*. > > >> The patch only addresses the problematic of having a single place for > >> version attributes. > >> Having the ant build also use these properties for creating correctly > >> numbered jars is not part of the patch. > > >> Note that I had to create a new file, src/clj/clojure/core_version.clj > >> , which is created by ant as a combination of template file > >> core_version-template.clj and the properties from version.properties. > > >> You'll see that if you don't like the names of the keys in > >> version.properties, build.xml is the single place where to change them > >> (apart from version.properties, of course). > >> Also, if you don't like the name version.properties (e.g. if it should > >> be named project.properties or whatever for easing maven users), then > >> you just have to change its occurence in build.xml too. > > >> If you like it, it can file an issue to google code and attach the patch, > > > Thanks! > > > I can't say I love the idea of generating a file during build. > > Me too, that's why I have made the file as short and independent as possible. > > Well, I tried to keep close to the idea of having the version numbers > "built-in", similarly to what was commited where it was also not read > from a "simpler file" at load time. > > > What about clojure.jar containing a properties file it reads at load time? > > Why not, indeed ? The file would have to placed in the classpath, e.g. > in directory src/jvm/clojure/lang or src/clj/clojure. > > > Could the same file be read by the various builds? > > For ant, yes. > > For maven2, it's more complex. > Indeed, I have read past the entire reference of the pom, searched > through the ml, and it seems that it's not possible at all to have > maven2 read properties file but its own which are not suitable for our > purpose. > > So I that even if we don't generate a clojure source file by reading > version.properties at load time from the classpath, it will be > difficult to avoid having to generate the maven2 pom.xml file from a > pom-template.xml ... > > Not that it would be difficult, it's just a matter of adding a > init-mvn task in the ant build.xml, and make all mvn related ant tasks > depend on it. > I appreciate the feedback. Ant/maven, property files and builds are not my area of expertise, so I'm holding off on 1.0 until I can get some working solution here (from anyone willing/able). Thanks, Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
How to have one lib with source in multiple files
I came across the term "root lib" when I googled on how to have one lib with source in multiple files. But, it appears that this was just discussion. I couldn't find the information I wanted on the main clojure page. Right now I have the two files "whale.achi.model.place.clj" and "whale.achi.model.placeEvaluation.clj" that make up one name space "whale.achi.model.place". The first file is the "root" of the namespace. I can get it to work if I add the statement (load "placeEvaluation") at the end of the first file. But, I was trying to add this information to the "load:" part of "ns" statement as is recommended. The googled pages seem to recommend the directory layout of: 1) whale.achi.model.place a) whale.achi.model.place.place.clj b) whale.achi.model.place.placeEvaluation.clj I really don't like the need to have a directory above the two files. The two files don't really constitute a "lib" in the usual sense, but I want to just be able to split the code in one namespace into two or more files that belong to the same namespace and have other namespaces that need these files to just "use" the root namespace which would then load in the other files needed to complete the namespace. Any help would be appreciated. Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: priority queue: some results
"meld" results look good (unless I made a mistake somewhere). I merged two collections, each with 2 million unique elements. did union of sorted sets, then did meld with my heap implementation: performing union of two sorted sets "Elapsed time: 18881.81 msecs" - making another heap performing meld of two heaps "Elapsed time: 0.146 msecs" checking in latest version of test. On Tue, Apr 21, 2009 at 2:10 AM, e wrote: > I've done a little comparing to sorted-set as recommended. The following > test (in case there is anything bogus about it) is checked in with the java > project: > http://code.google.com/p/jc-pheap/source/browse/trunk/jc-pheap/src/persistent_heap/testing/test.clj?spec=svn8&r=8 > > deduping 2,000,000 nums > shuffling 1999019 nums > = > inserting into sorted set > "Elapsed time: 39375.887 msecs" > > popping from front of sorted set > "Elapsed time: 15189.0 msecs" > = > heap insert > "Elapsed time: 15101.546 msecs" > -- > heap pop > "Elapsed time: 59715.796 msecs" > = > > What I am finding consistently (again, unless the test is bogus) is pretty > much expected. *Overall* the excellently implemented sorted-set outperforms > the heap I'm working on if you add the all the "insert" times to all the the > "pop-front" times. > > That said, if you want fast inserts, and you're not even sure yet if people > want all the elements in sorted order, the heap has advantages ... > especially if you're not even planning on referencing elements in the middle > of the list (something I do hope to support in some fashion eventually, > note). It may also be the case that some smart java/algorithm people could > find opportunities to speed up my deleteMin().* > > a note on deduping:* > > One difference that doesn't seem to matter performance-wise much is that > sorted-set elements are unique. I'm not sure if clojure currently has a > data structure (other than considering the heap) that works like a sorted > multimap or sorted multiset. Would it be the same to sort a vector in > between inserts? That doesn't sound fast, but maybe I should have done that > test, too. > > So, anyway, for this test, I inserted unique elements into both structures > so one wouldn't have way more than the other when comparing things like > popping. I also sampled from a wide range of numbers, so I probably didn't > have to go to such lengths, as it turns out. > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: tangent: X10 language
On Apr 23, 2:43 pm, Stuart Sierra wrote: > Possibly of interest: I saw a presentation about IBM's experimental > X10 language. (Why they named it after the most annoying ad campaign > in the history of the web, I'll never know.) > > X10 is an extension to Java for concurrency and cluster computing. > The basic idea is to make it possible to write a normal, procedural > program, with a few extra keywords that handle concurrency. > > It has some things in common with Clojure. It separates mutable > ("var") & immutable ("val") data, and has special keywords to indicate > that a particular computation is synchronous ("finish") or > asynchronous ("async"). > > A difference from Clojure is that X10 is designed to operate across > multiple processors/machines, even across different architectures, > within a single program (e.g. you could offload math-intensive > operations to a GPU). Data locality is enforced -- a thread can only > manipulate objects within its local address space (called a "place"). > If you want to manipulate data in another "place", you have to send > the code there with an operator called "at". > It's definitely interesting. I saw a presentation on X10 at ECOOP and met some of the devs at IBM Research when I spoke there subsequently. Full of neat ideas, including vectors as multidimensional array indexes/ranges. The notion of 'places' is the most interesting, as we'll need something like this even within process to deal with non-uniform memory access + multicore. Not something Clojure would tackle directly, but when the systems-level support comes around, something to look into (like putting agents in places). Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
tangent: X10 language
Possibly of interest: I saw a presentation about IBM's experimental X10 language. (Why they named it after the most annoying ad campaign in the history of the web, I'll never know.) X10 is an extension to Java for concurrency and cluster computing. The basic idea is to make it possible to write a normal, procedural program, with a few extra keywords that handle concurrency. It has some things in common with Clojure. It separates mutable ("var") & immutable ("val") data, and has special keywords to indicate that a particular computation is synchronous ("finish") or asynchronous ("async"). A difference from Clojure is that X10 is designed to operate across multiple processors/machines, even across different architectures, within a single program (e.g. you could offload math-intensive operations to a GPU). Data locality is enforced -- a thread can only manipulate objects within its local address space (called a "place"). If you want to manipulate data in another "place", you have to send the code there with an operator called "at". -Stuart Sierra --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: ICFP 2009
I'm interested, although I'm not sure if I'll be around that weekend. I've done quite well in past TopCoder-style contests (where I've had to use Java); it would be fun to do a competition in Clojure. -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 To unsubscribe from 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: Abstract data types in functional languages
On Apr 23, 2009, at 18:59, Mark Engelberg wrote: > Konrad has written a library that turns equality into a multimethod. > This provides the hooks for altering equality for maps, but there are > a lot of questions in my mind about how well this will coexist with > other Clojure code and just how severe the performance impact will be. I can't say much about performance yet. As for coexistence, there are two issues: 1) Any code working with your map-based types will have to use the generalized equality rather than the built-in equality test. Whether or not this is a problem depends very much on the nature of your data and the code working on it. The more you want to plug your data into completely unrelated functions, the more problems you can expect. 2) Sets and maps use internal equality tests, which you can't change. That means you can't really use your data types as elements of sets or keys in maps. I found that for many data types this is not a real issue, since I was able to find a representation for which the built-in equality is just fine. In your fraction example, it would be sufficient to ensure normalization after every arithmetic operation and in the constructor function defined as part of the API. Konrad. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from 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: Enlive tutorial
Nice enhancement! On Thu, Apr 23, 2009 at 6:43 PM, Christophe Grand wrote: > > I updated the tutorial to reflect a new behavior: enlive now precomputes > html output for untouched or partly untouched elements. > > ((template (java.io.StringReader. "untouched element class=foo>won't last") [] > [[:div last-child]] (content "new content"))) > > used to return: > ("<" "html" ">" "<" "body" ">" "<" "div" ">" "untouched element" " "div" ">" "<" "div" " " "class" "=\"" "foo" "\"" ">" "new content" " "div" ">" "" "") > > but now returns: > ("" "" "untouched element" "" > "new content" "" "" "") > > > Adrian Cuthbertson a écrit : >> I've uploaded a file >> http://groups.google.co.za/group/clojure/web/enlive-tut1.txt?hl=en >> which is a basic tutorial on getting started with Enlive (the html >> transformation library). >> >> Christophe, this is intended as a contribution to the Enlive project, >> so you're welcome to use it as part of the Enlive documentation, on >> the wiki, etc. Also, please feel free to enhance it and make any >> corrections. >> >> Enlive is an outstanding tool for web development. Thanks Christophe >> for your initiatives. >> >> Regards, Adrian. >> >> > >> >> > > > -- > Professional: http://cgrand.net/ (fr) > On Clojure: http://clj-me.blogspot.com/ (en) > > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Abstract data types in functional languages
In Clojure, the closest thing to an object (short of implementing a class in Java or using gen-class) is the map. But the more I play around with using maps to implement the kinds of things that objects are used for in other languages, the more I'm feeling that maps don't quite cut it. One problem is that Clojure doesn't really have hooks for altering the way equality is performed on things like maps. For example, let's say fractions aren't built in to Clojure, and I'm building my own representation for fractions using maps. Even though the *implementation* is a map, I'm no longer thinking of it as a map, but as its own data type. And I may very well want to define a new notion of equality, for example: (= {:numerator 1 :denominator 2} {:numerator 2 :denominator 4}) should be true. But there's really no convenient way to do this in Clojure. A map, no matter how you choose to think of it, is still just a map, and will always use its own built-in notion of equality. Konrad has written a library that turns equality into a multimethod. This provides the hooks for altering equality for maps, but there are a lot of questions in my mind about how well this will coexist with other Clojure code and just how severe the performance impact will be. David Nolen's example on this thread is another instance of wanting to tweak the equality semantics for a certain kind of map. Another problem that has already been "solved" by many OO languages is that initially it is most convenient to code certain things as properties of the object, and somewhere down the line, you may want to change property access into a method call. Most newish OO languages have some way to do this, so that you don't have to start out making oodles of getters and setters to make your API future proof. Timo pointed out the other day that if you start out modeling data as a map, and eventually want one of those pieces of the map to be dynamically computed from other elements, there's no convenient way to change this. All client code that uses assoc and get to simply retrieve the field from the map must be changed, or the API must use explicit getters and setters from the outset. So this suggests to me that, although maps work fine for a lot of lightweight object-like things, Clojure would benefit from something a bit more sophisticated for more complex use cases where you want to say, "This thing is a map, but I'm no longer thinking of it as map, but as a representation for a " Such a construct would hopefully eliminate the need for explicit tagging to work with multimethods, as well as providing hooks to customize equality, hashing, accessors, setters, visibility of elements, etc. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Enlive tutorial
I updated the tutorial to reflect a new behavior: enlive now precomputes html output for untouched or partly untouched elements. ((template (java.io.StringReader. "untouched elementwon't last") [] [[:div last-child]] (content "new content"))) used to return: ("<" "html" ">" "<" "body" ">" "<" "div" ">" "untouched element" "" "<" "div" " " "class" "=\"" "foo" "\"" ">" "new content" "" "" "") but now returns: ("" "" "untouched element" "" "new content" "" "" "") Adrian Cuthbertson a écrit : > I've uploaded a file > http://groups.google.co.za/group/clojure/web/enlive-tut1.txt?hl=en > which is a basic tutorial on getting started with Enlive (the html > transformation library). > > Christophe, this is intended as a contribution to the Enlive project, > so you're welcome to use it as part of the Enlive documentation, on > the wiki, etc. Also, please feel free to enhance it and make any > corrections. > > Enlive is an outstanding tool for web development. Thanks Christophe > for your initiatives. > > Regards, Adrian. > > > > > -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: best way to compete against meld?
to qualify the "simple" part, I was saying that I wanted to restrict myself to just calling what's in clojure and clojure-contrib, mostly. "simple" from my user perspective, since another part of the study could easily include building a data structure on top of what's already in clojure. On Thu, Apr 23, 2009 at 12:18 PM, e wrote: > I'm continuing to think about this priority queue stuff, now looking at > "meld", and wondering what would be the best way to approximate it with > what's in clojure right now ... core data structures and simple algorithms. > > for example, I could populate two vectors O(n), sort them O(n(log(n))), and > implement the O(n) merge part of merge-sort. Then popping things off the > front would easily be O(1). > > I'd compare that with the practical runtime of the heap, which has a > theoretical runtime of O(n) for all the inserts, no time for any up front > sorting, and O(log(n)) for merging (or possibly O(1) time with more > coding). Again the main work would be the O(log(n)) pops, > > but I want to just compare the meld speeds right now. > > sorted-sets aren't really right because of the uniqueness of elements, but > I could try that, too, doing a join/union of two sorted sets. > > granted I haven't looked through contrib much ... I need to figure out how > to access/include it from my current evironment/IDE (clojure-dev right now) > > Thanks for the help. > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
2009/4/23 Christophe Grand : > > Laurent PETIT a écrit : >> 2009/4/23 Christophe Grand : >> >>> Laurent PETIT a écrit : >>> I guess you're right. But a little warning in the javadoc could help newcomers not shoot themselves in the foot. And the problem is, calling directly (second) without calling (first) would work most of the time. I wanted to make it fail every time => same behaviour whatever the input data are. >>> Such a guarantee implies a side effect on the first seq is realized! >>> >> >> don't understand. >> > > Aren't you proposing that: > (let [[x y] (split-with pred coll)] > (seq y)) > always throws an exception while > (let [[x y] (split-with pred coll)] > (dorun x) > (seq y)) > doesn't? Yes, throwing an IllegalAccessException in the second case, signaling a violation of the contract by the user, instead of letting the code sometimes work (with certain sequences), sometimes not. But really this is not the main point, the main point is having got rid of the OutOfMemory exception, so with the volatile or whatever trick you'll find in your new book, we're almost done for a better split-with 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 To unsubscribe from 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: Abstract data types in functional languages
Point taken, this actually got me thinking about the probability of a hash match between strings of English words. I tried a playful experiment- I used a dictionary of 800,000 English words (containing 2 to 32 characters culled from the Internet) I got 2802 occurrences of strings producing the same hash. Of these 2802 occurrences 2223 are words between 2 and 4 characters. These matches were almost all line noise words. For words of 9 to 12 characters there are only 10 matches. There are no matches for words of 13 characters or more. Taking this into account, the probability of getting a false positive on two data structures of the same type (like a map representing a person) that have matching public fields but a falsely matching private hash becomes very unlikely. As for boinking the hash, c'est la vie since boinking anything in the map would destroy equality anyway. However, for those who might be concerned, this following version removes the hash technique and provides a simple eq? function. (defn set-private [m k x] (let [the-meta(meta m) new-private (assoc (:private the-meta) k x)] (with-meta m (assoc the-meta :private new-private (defn get-private [m k] (get (:private (meta m)) k)) (defn eq? [a b] (and (= a b) (= (:private (meta a)) (:private (meta b) On Wed, Apr 22, 2009 at 7:20 PM, Victor Rodriguez wrote: > > On Wed, Apr 22, 2009 at 1:28 PM, David Nolen > wrote: > > You're missing the clever hack ;) I'm hashing the private data structure > and > > associating it to the map. This is what is used in the equality test. You > > can verify yourself that it works. > > my-object ;; -> {:private -1261861093} > > my-other-object ;; -> {:private -1261861093} > > Make sense? A few quick tests show that the hash of a data structure will > > match on any VM. > > OK, I see the clever hack now. This could work, until murphy's law > kicks in and you get a false positive when two different sets of > private data produce the same hash... (or someone boinks the hash > value in the map). > > Cheers, > > Victor. > > > > On Wed, Apr 22, 2009 at 1:01 PM, Victor Rodriguez > wrote: > >> > >> On Tue, Apr 21, 2009 at 12:01 PM, David Nolen > >> wrote: > >> > Nice post thanks for putting it together. My gut feeling is that the > >> > need > >> > for information hiding is still overinflated, but... until someone > >> > builds a > >> > 200k LOC Clojure program who will know for sure? > >> > Here's my shot at a solution for private data: > >> > (defn set-private [m k x] > >> > (let [the-meta(meta m) > >> > new-private (assoc (:private the-meta) k x)] > >> > (with-meta > >> > (assoc m :private (hash new-private)) > >> > (assoc the-meta :private new-private > >> > (defn get-private [m k] > >> > (get (:private (meta m)) k)) > >> > (def my-object (set-private {} :first "Bob")) > >> > (def my-other-object (set-private {} :first "Bob")) > >> > (get-private my-object :first) ; -> "Bob" > >> > (= my-object my-other-object) ; -> true > >> > No secret keys, no other libraries, and I believe this supports > equality > >> > just fine. Since we're using metadata the data travels around easily > >> > >> This won't work, since metadata is not used for equality tests, isn't > >> that right? > >> > >> Regards, > >> > >> Victor Rodriguez. > >> > >> > between operations. > >> > -- Forwarded message -- > >> > From: Mark Engelberg > >> > Date: Tue, Apr 21, 2009 at 6:41 AM > >> > Subject: Re: Abstract data types in functional languages > >> > To: clojure@googlegroups.com > >> > > >> > > >> > > >> > On Mon, Apr 20, 2009 at 11:00 AM, Timo Mihaljov > >> > wrote: > >> >> Is the concept of Abstract Data Types [1] useful in Clojure? > >> >> > >> >> If yes, how would you implement one? > >> > > >> > I have composed a lengthy response to this question, and added it to > my > >> > blog: > >> > http://programming-puzzler.blogspot.com/2009/04/adts-in-clojure.html > >> > > >> > I look forward to everyone's comments, > >> > > >> > 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 To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
best way to compete against meld?
I'm continuing to think about this priority queue stuff, now looking at "meld", and wondering what would be the best way to approximate it with what's in clojure right now ... core data structures and simple algorithms. for example, I could populate two vectors O(n), sort them O(n(log(n))), and implement the O(n) merge part of merge-sort. Then popping things off the front would easily be O(1). I'd compare that with the practical runtime of the heap, which has a theoretical runtime of O(n) for all the inserts, no time for any up front sorting, and O(log(n)) for merging (or possibly O(1) time with more coding). Again the main work would be the O(log(n)) pops, but I want to just compare the meld speeds right now. sorted-sets aren't really right because of the uniqueness of elements, but I could try that, too, doing a join/union of two sorted sets. granted I haven't looked through contrib much ... I need to figure out how to access/include it from my current evironment/IDE (clojure-dev right now) Thanks for the help. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
Laurent PETIT a écrit : > 2009/4/23 Christophe Grand : > >> Laurent PETIT a écrit : >> >>> I guess you're right. But a little warning in the javadoc could help >>> newcomers not shoot themselves in the foot. >>> And the problem is, calling directly (second) without calling (first) >>> would work most of the time. I wanted to make it fail every time => >>> same behaviour whatever the input data are. >>> >>> >> Such a guarantee implies a side effect on the first seq is realized! >> > > don't understand. > Aren't you proposing that: (let [[x y] (split-with pred coll)] (seq y)) always throws an exception while (let [[x y] (split-with pred coll)] (dorun x) (seq y)) doesn't? -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: The Path to 1.0
2009/4/23 Rich Hickey : > > > > On Apr 22, 12:41 pm, Laurent PETIT wrote: >> 2009/4/22 Rich Hickey : >> >> > [...] >> > {:major 1, :minor 0, :incremental 0, :qualifier :rc1 :interim true} >> >> > for interim versions and >> >> > {:major 1, :minor 0, :incremental 0} >> >> > for releases. :interim tracks the SNAPSHOT segment of the version >> > string. >> > [...] >> > I don't mind the build producing clojure-1.0.0.jar etc, but it doesn't >> > now. The master build is Ant. Where is the best place to put the >> > version info so it can be leveraged by Ant, Maven and the clojure core >> > runtime in order to produce *clojure-version* ? >> >> Here a patch that allows to initialize from ant and from a file >> version.properties the values in *clojure-version*. >> >> The patch only addresses the problematic of having a single place for >> version attributes. >> Having the ant build also use these properties for creating correctly >> numbered jars is not part of the patch. >> >> Note that I had to create a new file, src/clj/clojure/core_version.clj >> , which is created by ant as a combination of template file >> core_version-template.clj and the properties from version.properties. >> >> You'll see that if you don't like the names of the keys in >> version.properties, build.xml is the single place where to change them >> (apart from version.properties, of course). >> Also, if you don't like the name version.properties (e.g. if it should >> be named project.properties or whatever for easing maven users), then >> you just have to change its occurence in build.xml too. >> >> If you like it, it can file an issue to google code and attach the patch, >> > > Thanks! > > I can't say I love the idea of generating a file during build. Me too, that's why I have made the file as short and independent as possible. Well, I tried to keep close to the idea of having the version numbers "built-in", similarly to what was commited where it was also not read from a "simpler file" at load time. > What about clojure.jar containing a properties file it reads at load time? Why not, indeed ? The file would have to placed in the classpath, e.g. in directory src/jvm/clojure/lang or src/clj/clojure. > Could the same file be read by the various builds? For ant, yes. For maven2, it's more complex. Indeed, I have read past the entire reference of the pom, searched through the ml, and it seems that it's not possible at all to have maven2 read properties file but its own which are not suitable for our purpose. So I that even if we don't generate a clojure source file by reading version.properties at load time from the classpath, it will be difficult to avoid having to generate the maven2 pom.xml file from a pom-template.xml ... Not that it would be difficult, it's just a matter of adding a init-mvn task in the ant build.xml, and make all mvn related ant tasks depend on it. Concerning what Howard suggested, having the maven2 pom.xml file be the reference where the version information is placed, I can't say I like this idea very much. That's because maven2 pom.xml is not as structured as you have structured the current version information (maven2 just has a single "version" element where you place whatever you want, it's not decomposed into major, minor, ... so it will be more difficult to do the pattern matching :-). And also, maven2 pom.xml is not the master build file, it's ant, so it sounds weird to have ant go parse maven2.xml file to extract the versioning information. My 0,02€, -- Laurent --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: The Path to 1.0
On Apr 22, 12:41 pm, Laurent PETIT wrote: > 2009/4/22 Rich Hickey : > > > [...] > > {:major 1, :minor 0, :incremental 0, :qualifier :rc1 :interim true} > > > for interim versions and > > > {:major 1, :minor 0, :incremental 0} > > > for releases. :interim tracks the SNAPSHOT segment of the version > > string. > > [...] > > I don't mind the build producing clojure-1.0.0.jar etc, but it doesn't > > now. The master build is Ant. Where is the best place to put the > > version info so it can be leveraged by Ant, Maven and the clojure core > > runtime in order to produce *clojure-version* ? > > Here a patch that allows to initialize from ant and from a file > version.properties the values in *clojure-version*. > > The patch only addresses the problematic of having a single place for > version attributes. > Having the ant build also use these properties for creating correctly > numbered jars is not part of the patch. > > Note that I had to create a new file, src/clj/clojure/core_version.clj > , which is created by ant as a combination of template file > core_version-template.clj and the properties from version.properties. > > You'll see that if you don't like the names of the keys in > version.properties, build.xml is the single place where to change them > (apart from version.properties, of course). > Also, if you don't like the name version.properties (e.g. if it should > be named project.properties or whatever for easing maven users), then > you just have to change its occurence in build.xml too. > > If you like it, it can file an issue to google code and attach the patch, > Thanks! I can't say I love the idea of generating a file during build. What about clojure.jar containing a properties file it reads at load time? Could the same file be read by the various builds? Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: ICFP 2009
On Thu, Apr 23, 2009 at 11:04 AM, Rich Hickey wrote: > On Apr 23, 8:59 am, Andrew Wagner wrote: > > > Sounds like a fun thing to try. Could someone give a brief > > > description of what would be required in terms of time commitment to > > > participate on a team? (Sadly, spare time is hard to come by...) > > > > It's just one weekend. As much or as little time as you can commit to for > > that weekend. > > Although being competitive requires pretty much all waking hours > during that weekend :) > > Rich > And some non-waking hours! :) Paul --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: ICFP 2009
On Apr 23, 8:59 am, Andrew Wagner wrote: > > Sounds like a fun thing to try. Could someone give a brief > > description of what would be required in terms of time commitment to > > participate on a team? (Sadly, spare time is hard to come by...) > > It's just one weekend. As much or as little time as you can commit to for > that weekend. Although being competitive requires pretty much all waking hours during that weekend :) Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
2009/4/23 Christophe Grand : > > Laurent PETIT a écrit : >> I guess you're right. But a little warning in the javadoc could help >> newcomers not shoot themselves in the foot. >> And the problem is, calling directly (second) without calling (first) >> would work most of the time. I wanted to make it fail every time => >> same behaviour whatever the input data are. >> > > Such a guarantee implies a side effect on the first seq is realized! don't understand. > >>> Neither do I. Updates to the atom are serialized by the lazy-seq >>> realization, so we don't even need an atom: a simple volatile field >>> should do the trick. No? >>> >> >> Yes, what would be the prettier way to do this ? I could think of some >> hackish but working array of one element :-) ? >> I don't think (with-local-vars will work, since the produced seqs >> could not be transported among threads anymore). >> > > I think that 1-elt arrays don't work well with threads, that's why I > suggested a volatile field. > But I'm not a concurrency expert (just received my copy of Java > Concurrency In Practice :-D) Have a nice read. I myself just bought "Concepts, Techniques, and Models of Computer Programming". Seems like we're going to not sleep a lot the days following our respective books deliveries :-) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
Laurent PETIT a écrit : > I guess you're right. But a little warning in the javadoc could help > newcomers not shoot themselves in the foot. > And the problem is, calling directly (second) without calling (first) > would work most of the time. I wanted to make it fail every time => > same behaviour whatever the input data are. > Such a guarantee implies a side effect on the first seq is realized! >> Neither do I. Updates to the atom are serialized by the lazy-seq >> realization, so we don't even need an atom: a simple volatile field >> should do the trick. No? >> > > Yes, what would be the prettier way to do this ? I could think of some > hackish but working array of one element :-) ? > I don't think (with-local-vars will work, since the produced seqs > could not be transported among threads anymore). > I think that 1-elt arrays don't work well with threads, that's why I suggested a volatile field. But I'm not a concurrency expert (just received my copy of Java Concurrency In Practice :-D) Christophe -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
2009/4/23 Christophe Grand : > > Laurent PETIT a écrit : >> 2009/4/23 Christophe Grand : >> >>> *Warning this message contains mutable state and may hurt functional >>> sensibilities.* >>> >>> Ugly hack: >>> >>> (defn my-split-with [pred coll] >>> (let [s (atom coll) >>> p #(when-let [r (pred %)] (swap! s rest) r)] >>> [(take-while p coll) (drop-while pred (lazy-seq @s))])) >>> >> >> Cheater ! ;-) >> >> But there's still the problem of having the user being able to check >> the second argument before having exhausted (if possible) the first... >> and then having an infinite loop: e.g. (first (second (my-split-with >> true? (repeat true))). >> > > I don't see the problem, it's like (dropwhile true? (repeat true)) you > can't protect the user from himself. I guess you're right. But a little warning in the javadoc could help newcomers not shoot themselves in the foot. And the problem is, calling directly (second) without calling (first) would work most of the time. I wanted to make it fail every time => same behaviour whatever the input data are. And it could also be counterintuitive : a user could think that if he knows the predicate will always return true, maybe the second seq will be nil, since it is the mathematically expected result :-) With dropwhile there's no option for the user. > > >> And maybe calling swap! for each matched elem may be expensive ? >> (That's a real question, I don't have any real idea, just a guess ...) >> > > Neither do I. Updates to the atom are serialized by the lazy-seq > realization, so we don't even need an atom: a simple volatile field > should do the trick. No? Yes, what would be the prettier way to do this ? I could think of some hackish but working array of one element :-) ? I don't think (with-local-vars will work, since the produced seqs could not be transported among threads anymore). > > >> But wait ... the more I think about it, the more it appears to me >> (though I can not prove it formally) that the problem requires >> side-effect to be solved, either via the use of mutation, either via >> the use of multiple threads for coordinating the feeding of 2 separate >> sequences ? >> > > I share your intuition on this. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
Laurent PETIT a écrit : > 2009/4/23 Christophe Grand : > >> *Warning this message contains mutable state and may hurt functional >> sensibilities.* >> >> Ugly hack: >> >> (defn my-split-with [pred coll] >> (let [s (atom coll) >>p #(when-let [r (pred %)] (swap! s rest) r)] >>[(take-while p coll) (drop-while pred (lazy-seq @s))])) >> > > Cheater ! ;-) > > But there's still the problem of having the user being able to check > the second argument before having exhausted (if possible) the first... > and then having an infinite loop: e.g. (first (second (my-split-with > true? (repeat true))). > I don't see the problem, it's like (dropwhile true? (repeat true)) you can't protect the user from himself. > And maybe calling swap! for each matched elem may be expensive ? > (That's a real question, I don't have any real idea, just a guess ...) > Neither do I. Updates to the atom are serialized by the lazy-seq realization, so we don't even need an atom: a simple volatile field should do the trick. No? > But wait ... the more I think about it, the more it appears to me > (though I can not prove it formally) that the problem requires > side-effect to be solved, either via the use of mutation, either via > the use of multiple threads for coordinating the feeding of 2 separate > sequences ? > I share your intuition on this. Christophe -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
2009/4/23 Christophe Grand : > > *Warning this message contains mutable state and may hurt functional > sensibilities.* > > Ugly hack: > > (defn my-split-with [pred coll] > (let [s (atom coll) > p #(when-let [r (pred %)] (swap! s rest) r)] > [(take-while p coll) (drop-while pred (lazy-seq @s))])) Cheater ! ;-) But there's still the problem of having the user being able to check the second argument before having exhausted (if possible) the first... and then having an infinite loop: e.g. (first (second (my-split-with true? (repeat true))). And maybe calling swap! for each matched elem may be expensive ? (That's a real question, I don't have any real idea, just a guess ...) But wait ... the more I think about it, the more it appears to me (though I can not prove it formally) that the problem requires side-effect to be solved, either via the use of mutation, either via the use of multiple threads for coordinating the feeding of 2 separate sequences ? If I'm correct, then maybe your solution is not that hacky, provided that having to choose between manipulating a state and manipulating multiple threads with BlockingQueues, ... the most efficient, simple and bug free version will certainly be the local mutation of state. With these minor enhancements, your version can also be * very efficient because there will be at most one swap! call (but maybe the overhead I added by adding composition stages is worse than calling swap! each time ?) * much more robust if the user tries to consume from the second seq while not having finished consuming from the first (he will get an exception) Here is the final version, renamed safe-split-with for the occasion: (defn rests [coll] (lazy-seq (if-let [s (seq coll)] (cons s (rests (rest s))) (list () (defn safe-split-with [pred coll] (let [s (atom nil) p #(if-let [r (pred (first %))] true (do (reset! s (second %)) false))] [(map first (take-while p (map vector coll (rests coll (lazy-seq (if-let [s @s] s (throw (IllegalStateException. "Tried to check seq of elems of coll non matching pred before having exhausted seq of elems matching pred."])) ; test: (doseq [c (safe-split-with true? [true true false false])] (println c)) ; test exception: (println (second (safe-split-with true? [true true false false]))) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
contrib mercurial mirror is back up
My bitbucket contrib mirror is public again at http://bitbucket.org/shoover/clojure-contrib-mirror. Thanks to bitbucket for munging unrecognized email addresses per my request. Shawn --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: ICFP 2009
> > Sounds like a fun thing to try. Could someone give a brief > description of what would be required in terms of time commitment to > participate on a team? (Sadly, spare time is hard to come by...) > It's just one weekend. As much or as little time as you can commit to for that weekend. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
On Thu, Apr 23, 2009 at 2:11 PM, Emeka wrote: > Laurent, > > Sampi question was; > > > Let's say I have a sequence of integers: > > (def a (3 9 1 5 102 -322 ...)) > > > > Is there a function for inserting an object—let's say :foo—after > > elements that fulfill a certain predicate? > > Furthermore, I mean inserting :foo after any block of elements that > > fulfill it: > > > > (mystery-function (partial > 6) a) ; -> (3 :foo 9 1 5 :foo 102 > > -322 :foo ...) > > I didn't know that :foo should also be the last element of the list. Did he > actually asked for this? (partial > 6) is the same as #(> 6 %) so Samppi's example puts :foo after a group of elements if (> 6 element) for each of those elements. i.e. (1 2 3 4 5 6 7 8) => (1 2 3 4 5 :foo 6 7 8) because 6 is greater than all of 1, 2, 3, 4, and 5, but none of the other elements. and (3 4 5 8 4 2) => (3 4 5 :foo 8 4 2 :foo) because 6 is greater than 3, 4 and 5 and it is also greater than 4 and 2. -- Michael Wood --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
Laurent, Sampi question was; Let's say I have a sequence of integers: (def a (3 9 1 5 102 -322 ...)) Is there a function for inserting an object—let's say :foo—after elements that fulfill a certain predicate? Furthermore, I mean inserting :foo after any block of elements that fulfill it: (mystery-function (partial > 6) a) ; -> (3 :foo 9 1 5 :foo 102 -322 :foo ...) I didn't know that :foo should also be the last element of the list. Did he actually asked for this? Thanks for pointing out the subtle difference between the two versions of list. Regards, Emeka On Thu, Apr 23, 2009 at 12:37 PM, Laurent PETIT wrote: > > 1:2 user=> (reduce #(concat %1 (if (> %2 6) [ :foo %2] [%2])) [] '(3 4 5 8 > 4 2)) > (3 4 5 :foo 8 4 2) > > Not good, the expected result would have been > (3 4 5 :foo 8 4 2 :foo) > > Regards, > > -- > Laurent > > 2009/4/23 Emeka : > > > > (reduce #(concat %1 (if (> %2 6) [ :foo %2] [%2])) [] '(3 4 5 8 4 2)) > > > > Note that I am not a programmer and do not know much about writing code, > > however the above snippet in my view can achieve the result you desired. > I > > invite comments on the above. > > > > Regards, > > Emeka > > On Thu, Apr 23, 2009 at 10:52 AM, Christophe Grand < > christo...@cgrand.net> > > wrote: > >> > >> *Warning this message contains mutable state and may hurt functional > >> sensibilities.* > >> > >> Ugly hack: > >> > >> (defn my-split-with [pred coll] > >> (let [s (atom coll) > >>p #(when-let [r (pred %)] (swap! s rest) r)] > >>[(take-while p coll) (drop-while pred (lazy-seq @s))])) > >> > >> Now it works ;-) > >> > >> Laurent PETIT a écrit : > >> > This is a general problem with function (split-with) (and derivatives > >> > such as partition-by ...), > >> > > >> > This should certainly deserve a mention in their respective > >> > docstrings, I think. Because the docstring speak about lazyness, but > >> > not the kind of lazyness that can avoid Out of Memory in corner cases. > >> > > >> > Rich, if you agree with that, would you me to issue a patch on google > >> > group ? > >> > > >> > 2009/4/23 Christophe Grand : > >> > > >> >> Laurent PETIT a écrit : > >> >> > >> >>> Hi Meikel, > >> >>> > >> >>> It seems to me that your version is the only safe one so far, that > >> >>> would succesfully indefinitely return values with this test: > >> >>> > >> >>> (dorun (mystery-function true? :foo (repeat true))) > >> >>> > >> >>> Mine, a new version of mine I'll never bother to publish, and > >> >>> Christophe's all retain head. > >> >>> To explain on Christophe's one for example: > >> >>> > >> >>> It uses (split-with) which, in case pred always match coll elements, > >> >>> will retain the head of coll in etc, while eating more and more > >> >>> elements of coll via running on run : > >> >>> 1:21 user=> (defn mystery-function [pred coll] > >> >>> (lazy-seq > >> >>>(when (seq coll) > >> >>> (let [[run etc] (split-with pred coll)] > >> >>>(if (seq run) > >> >>> (concat run (cons :foo (mystery-function pred etc))) > >> >>> (cons (first coll) (mystery-function pred (rest > coll > >> >>> 1:22 user=> (dorun (mystery-function true? (repeat true))) > >> >>> java.lang.OutOfMemoryError: GC overhead limit exceeded (repl-1:22) > >> >>> > >> >>> > >> >> Nice catch! > >> >> > >> >> > >> >> -- > >> >> Professional: http://cgrand.net/ (fr) > >> >> On Clojure: http://clj-me.blogspot.com/ (en) > >> >> > >> >> > >> >> > >> >> > >> > > >> > > > >> > > >> > > >> > >> > >> -- > >> Professional: http://cgrand.net/ (fr) > >> On Clojure: http://clj-me.blogspot.com/ (en) > >> > >> > >> > >> > > > > > > > > > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
Ah, and also it's not lazy, e.g. : (take 10 (reduce #(concat %1 (if (> %2 6) [ :foo %2] [%2])) [] (iterate inc 0 Since you invited comments, please note that the quick way of writing a literal list '(3 4 5 6 8) is not general, because it does not evaluate the elements of the list : Try (let [a 0] '(a 1 2 3)) for example and you may (or may not, I remember I was, since it is a so much spread idiom) be surprised. The version that will always give what you expect is just with function list : (let [a 0] (list a 1 2 3)) HTH, -- Laurent will never return, for example. 2009/4/23 Laurent PETIT : > 1:2 user=> (reduce #(concat %1 (if (> %2 6) [ :foo %2] [%2])) [] '(3 4 5 8 4 > 2)) > (3 4 5 :foo 8 4 2) > > Not good, the expected result would have been > (3 4 5 :foo 8 4 2 :foo) > > Regards, > > -- > Laurent > > 2009/4/23 Emeka : >> >> (reduce #(concat %1 (if (> %2 6) [ :foo %2] [%2])) [] '(3 4 5 8 4 2)) >> >> Note that I am not a programmer and do not know much about writing code, >> however the above snippet in my view can achieve the result you desired. I >> invite comments on the above. >> >> Regards, >> Emeka >> On Thu, Apr 23, 2009 at 10:52 AM, Christophe Grand >> wrote: >>> >>> *Warning this message contains mutable state and may hurt functional >>> sensibilities.* >>> >>> Ugly hack: >>> >>> (defn my-split-with [pred coll] >>> (let [s (atom coll) >>> p #(when-let [r (pred %)] (swap! s rest) r)] >>> [(take-while p coll) (drop-while pred (lazy-seq @s))])) >>> >>> Now it works ;-) >>> >>> Laurent PETIT a écrit : >>> > This is a general problem with function (split-with) (and derivatives >>> > such as partition-by ...), >>> > >>> > This should certainly deserve a mention in their respective >>> > docstrings, I think. Because the docstring speak about lazyness, but >>> > not the kind of lazyness that can avoid Out of Memory in corner cases. >>> > >>> > Rich, if you agree with that, would you me to issue a patch on google >>> > group ? >>> > >>> > 2009/4/23 Christophe Grand : >>> > >>> >> Laurent PETIT a écrit : >>> >> >>> >>> Hi Meikel, >>> >>> >>> >>> It seems to me that your version is the only safe one so far, that >>> >>> would succesfully indefinitely return values with this test: >>> >>> >>> >>> (dorun (mystery-function true? :foo (repeat true))) >>> >>> >>> >>> Mine, a new version of mine I'll never bother to publish, and >>> >>> Christophe's all retain head. >>> >>> To explain on Christophe's one for example: >>> >>> >>> >>> It uses (split-with) which, in case pred always match coll elements, >>> >>> will retain the head of coll in etc, while eating more and more >>> >>> elements of coll via running on run : >>> >>> 1:21 user=> (defn mystery-function [pred coll] >>> >>> (lazy-seq >>> >>> (when (seq coll) >>> >>> (let [[run etc] (split-with pred coll)] >>> >>> (if (seq run) >>> >>> (concat run (cons :foo (mystery-function pred etc))) >>> >>> (cons (first coll) (mystery-function pred (rest coll >>> >>> 1:22 user=> (dorun (mystery-function true? (repeat true))) >>> >>> java.lang.OutOfMemoryError: GC overhead limit exceeded (repl-1:22) >>> >>> >>> >>> >>> >> Nice catch! >>> >> >>> >> >>> >> -- >>> >> Professional: http://cgrand.net/ (fr) >>> >> On Clojure: http://clj-me.blogspot.com/ (en) >>> >> >>> >> >>> >> >>> >> >>> > >>> > > >>> > >>> > >>> >>> >>> -- >>> Professional: http://cgrand.net/ (fr) >>> On Clojure: http://clj-me.blogspot.com/ (en) >>> >>> >>> >>> >> >> >> >> >> > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
1:2 user=> (reduce #(concat %1 (if (> %2 6) [ :foo %2] [%2])) [] '(3 4 5 8 4 2)) (3 4 5 :foo 8 4 2) Not good, the expected result would have been (3 4 5 :foo 8 4 2 :foo) Regards, -- Laurent 2009/4/23 Emeka : > > (reduce #(concat %1 (if (> %2 6) [ :foo %2] [%2])) [] '(3 4 5 8 4 2)) > > Note that I am not a programmer and do not know much about writing code, > however the above snippet in my view can achieve the result you desired. I > invite comments on the above. > > Regards, > Emeka > On Thu, Apr 23, 2009 at 10:52 AM, Christophe Grand > wrote: >> >> *Warning this message contains mutable state and may hurt functional >> sensibilities.* >> >> Ugly hack: >> >> (defn my-split-with [pred coll] >> (let [s (atom coll) >> p #(when-let [r (pred %)] (swap! s rest) r)] >> [(take-while p coll) (drop-while pred (lazy-seq @s))])) >> >> Now it works ;-) >> >> Laurent PETIT a écrit : >> > This is a general problem with function (split-with) (and derivatives >> > such as partition-by ...), >> > >> > This should certainly deserve a mention in their respective >> > docstrings, I think. Because the docstring speak about lazyness, but >> > not the kind of lazyness that can avoid Out of Memory in corner cases. >> > >> > Rich, if you agree with that, would you me to issue a patch on google >> > group ? >> > >> > 2009/4/23 Christophe Grand : >> > >> >> Laurent PETIT a écrit : >> >> >> >>> Hi Meikel, >> >>> >> >>> It seems to me that your version is the only safe one so far, that >> >>> would succesfully indefinitely return values with this test: >> >>> >> >>> (dorun (mystery-function true? :foo (repeat true))) >> >>> >> >>> Mine, a new version of mine I'll never bother to publish, and >> >>> Christophe's all retain head. >> >>> To explain on Christophe's one for example: >> >>> >> >>> It uses (split-with) which, in case pred always match coll elements, >> >>> will retain the head of coll in etc, while eating more and more >> >>> elements of coll via running on run : >> >>> 1:21 user=> (defn mystery-function [pred coll] >> >>> (lazy-seq >> >>> (when (seq coll) >> >>> (let [[run etc] (split-with pred coll)] >> >>> (if (seq run) >> >>> (concat run (cons :foo (mystery-function pred etc))) >> >>> (cons (first coll) (mystery-function pred (rest coll >> >>> 1:22 user=> (dorun (mystery-function true? (repeat true))) >> >>> java.lang.OutOfMemoryError: GC overhead limit exceeded (repl-1:22) >> >>> >> >>> >> >> Nice catch! >> >> >> >> >> >> -- >> >> Professional: http://cgrand.net/ (fr) >> >> On Clojure: http://clj-me.blogspot.com/ (en) >> >> >> >> >> >> >> >> >> > >> > > >> > >> > >> >> >> -- >> Professional: http://cgrand.net/ (fr) >> On Clojure: http://clj-me.blogspot.com/ (en) >> >> >> >> > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
(reduce #(concat %1 (if (> %2 6) [ :foo %2] [%2])) [] '(3 4 5 8 4 2)) Note that I am not a programmer and do not know much about writing code, however the above snippet in my view can achieve the result you desired. I invite comments on the above. Regards, Emeka On Thu, Apr 23, 2009 at 10:52 AM, Christophe Grand wrote: > > *Warning this message contains mutable state and may hurt functional > sensibilities.* > > Ugly hack: > > (defn my-split-with [pred coll] > (let [s (atom coll) >p #(when-let [r (pred %)] (swap! s rest) r)] >[(take-while p coll) (drop-while pred (lazy-seq @s))])) > > Now it works ;-) > > Laurent PETIT a écrit : > > This is a general problem with function (split-with) (and derivatives > > such as partition-by ...), > > > > This should certainly deserve a mention in their respective > > docstrings, I think. Because the docstring speak about lazyness, but > > not the kind of lazyness that can avoid Out of Memory in corner cases. > > > > Rich, if you agree with that, would you me to issue a patch on google > group ? > > > > 2009/4/23 Christophe Grand : > > > >> Laurent PETIT a écrit : > >> > >>> Hi Meikel, > >>> > >>> It seems to me that your version is the only safe one so far, that > >>> would succesfully indefinitely return values with this test: > >>> > >>> (dorun (mystery-function true? :foo (repeat true))) > >>> > >>> Mine, a new version of mine I'll never bother to publish, and > >>> Christophe's all retain head. > >>> To explain on Christophe's one for example: > >>> > >>> It uses (split-with) which, in case pred always match coll elements, > >>> will retain the head of coll in etc, while eating more and more > >>> elements of coll via running on run : > >>> 1:21 user=> (defn mystery-function [pred coll] > >>> (lazy-seq > >>>(when (seq coll) > >>> (let [[run etc] (split-with pred coll)] > >>>(if (seq run) > >>> (concat run (cons :foo (mystery-function pred etc))) > >>> (cons (first coll) (mystery-function pred (rest coll > >>> 1:22 user=> (dorun (mystery-function true? (repeat true))) > >>> java.lang.OutOfMemoryError: GC overhead limit exceeded (repl-1:22) > >>> > >>> > >> Nice catch! > >> > >> > >> -- > >> Professional: http://cgrand.net/ (fr) > >> On Clojure: http://clj-me.blogspot.com/ (en) > >> > >> > >> > >> > > > > > > > > > > > > -- > Professional: http://cgrand.net/ (fr) > On Clojure: http://clj-me.blogspot.com/ (en) > > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
*Warning this message contains mutable state and may hurt functional sensibilities.* Ugly hack: (defn my-split-with [pred coll] (let [s (atom coll) p #(when-let [r (pred %)] (swap! s rest) r)] [(take-while p coll) (drop-while pred (lazy-seq @s))])) Now it works ;-) Laurent PETIT a écrit : > This is a general problem with function (split-with) (and derivatives > such as partition-by ...), > > This should certainly deserve a mention in their respective > docstrings, I think. Because the docstring speak about lazyness, but > not the kind of lazyness that can avoid Out of Memory in corner cases. > > Rich, if you agree with that, would you me to issue a patch on google group ? > > 2009/4/23 Christophe Grand : > >> Laurent PETIT a écrit : >> >>> Hi Meikel, >>> >>> It seems to me that your version is the only safe one so far, that >>> would succesfully indefinitely return values with this test: >>> >>> (dorun (mystery-function true? :foo (repeat true))) >>> >>> Mine, a new version of mine I'll never bother to publish, and >>> Christophe's all retain head. >>> To explain on Christophe's one for example: >>> >>> It uses (split-with) which, in case pred always match coll elements, >>> will retain the head of coll in etc, while eating more and more >>> elements of coll via running on run : >>> 1:21 user=> (defn mystery-function [pred coll] >>> (lazy-seq >>>(when (seq coll) >>> (let [[run etc] (split-with pred coll)] >>>(if (seq run) >>> (concat run (cons :foo (mystery-function pred etc))) >>> (cons (first coll) (mystery-function pred (rest coll >>> 1:22 user=> (dorun (mystery-function true? (repeat true))) >>> java.lang.OutOfMemoryError: GC overhead limit exceeded (repl-1:22) >>> >>> >> Nice catch! >> >> >> -- >> Professional: http://cgrand.net/ (fr) >> On Clojure: http://clj-me.blogspot.com/ (en) >> >> >> >> > > > > > -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Swing Java example to Clojure - Question about better translation
Hello, I've started dabbling into Swing & Clojure, and for fun decided to translate one of the Sun examples (requires Java SE 1.6 though) It's located here: http://java.sun.com/docs/books/tutorial/uiswing/examples/learn/index.html#CelsiusConverter and the java code here: http://java.sun.com/docs/books/tutorial/uiswing/examples/learn/CelsiusConverterProject/src/learn/CelsiusConverterGUI.java I've translated the above java code to clojure here: http://paste.lisp.org/display/79061 But I feel I did not do good job on it. The hard part was this convention of creating object inline, and calling it's method to further add elements/extend the system. It reminds of TurboVision from the glory TurboPascal days: layout.setHorizontalGroup( layout.createParallelGroup (javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup (javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() . // more code omitted .addContainerGap(27, Short.MAX_VALUE)) ); I've did my best: (doto layout (.setHorizontalGroup (.. layout (createParallelGroup GroupLayout$Alignment/LEADING) (addGroup (.. layout (createSequentialGroup) (addContainerGap) (addGroup (.. layout (createParallelGroup GroupLayout$Alignment/LEADING) (addGroup ;; more code omitted (addComponentfahrenheit-label) (addContainerGap 27 Short/MAX_VALUE) But I feel I can do it better (some fancy macro?). Any ideas how I can improve it. I understand from the Java comments that the layout code was autogenerated by a tool, but still it's an interresting question. Granted the ".." sugary macro helped a lot, but my brain melted a bit while I was translating it :) Here is the full code, in case the paste.lisp.org doesn't work: (import '(javax.swing JFrame JLabel JTextField JButton GroupLayout GroupLayout$Alignment SwingConstants LayoutStyle LayoutStyle $ComponentPlacement) '(java.awt.event ActionListener) '(java.awt Component)) (defn celsius-converter-gui "Translation of the simple Celsius Converter GUI Swing Example from Java to Clojure (requires Java SE 1.6) http://java.sun.com/docs/books/tutorial/uiswing/examples/learn/CelsiusConverterProject/src/learn/CelsiusConverterGUI.java"; [] (let [frame(new JFrame "Celsius Converter") pane (. frame getContentPane) layout (new GroupLayout pane) temp-text-field (new JTextField) celsius-label(new JLabel "Celsius") convert-button (new JButton "Convert") fahrenheit-label (new JLabel "Fahrenheit")] (. convert-button addActionListener (proxy [ActionListener] [] (actionPerformed [event] (. fahrenheit-label setText (str (+ 32.0 (* 1.8 (Double/parseDouble (. temp-text-field getText " Fahrenheit") (doto layout (.setHorizontalGroup (.. layout (createParallelGroup GroupLayout$Alignment/LEADING) (addGroup (.. layout (createSequentialGroup) (addContainerGap) (addGroup (.. layout (createParallelGroup GroupLayout$Alignment/LEADING) (addGroup (.. layout (createSequentialGroup) (addComponenttemp-text-field GroupLayout/PREFERRED_SIZE GroupLayout/DEFAULT_SIZE GroupLayout/PREFERRED_SIZE) (addPreferredGap LayoutStyle$ComponentPlacement/RELATED) (addComponentcelsius-label))) (addGroup (.. layout (createSequentialGroup) (addComponentconvert-button) (addPreferredGap LayoutStyle$ComponentPlacement/RELATED) (addComponentfahrenheit-label) (addContainerGap 27 Short/MAX_VALUE) (.linkSize SwingConstants/HORIZONTAL (into-array Component [convert-button temp-text-field])) (.setVerticalGroup (.. layout (createParallelGroup GroupLayout$Alignment/LEADING) (addGroup (.. layout (createSequentialGroup) (addContainerGap) (addGroup (.. layout (createParallelGroup GroupLayout$Alignment/BASELINE)
Re: Enlive tutorial
Christophe Grand a écrit : > Hi Adrian! > > Thanks for this tutorial, I put it on the wiki > http://wiki.github.com/cgrand/enlive/getting-started (I fixed two typos: > a missing paren and an extraneous colon and I simplified to-li). And I removed the part talking about right since I already merged "right" in master. -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
This is a general problem with function (split-with) (and derivatives such as partition-by ...), This should certainly deserve a mention in their respective docstrings, I think. Because the docstring speak about lazyness, but not the kind of lazyness that can avoid Out of Memory in corner cases. Rich, if you agree with that, would you me to issue a patch on google group ? 2009/4/23 Christophe Grand : > > Laurent PETIT a écrit : >> Hi Meikel, >> >> It seems to me that your version is the only safe one so far, that >> would succesfully indefinitely return values with this test: >> >> (dorun (mystery-function true? :foo (repeat true))) >> >> Mine, a new version of mine I'll never bother to publish, and >> Christophe's all retain head. >> To explain on Christophe's one for example: >> >> It uses (split-with) which, in case pred always match coll elements, >> will retain the head of coll in etc, while eating more and more >> elements of coll via running on run : >> 1:21 user=> (defn mystery-function [pred coll] >> (lazy-seq >> (when (seq coll) >> (let [[run etc] (split-with pred coll)] >> (if (seq run) >> (concat run (cons :foo (mystery-function pred etc))) >> (cons (first coll) (mystery-function pred (rest coll >> 1:22 user=> (dorun (mystery-function true? (repeat true))) >> java.lang.OutOfMemoryError: GC overhead limit exceeded (repl-1:22) >> > > Nice catch! > > > -- > Professional: http://cgrand.net/ (fr) > On Clojure: http://clj-me.blogspot.com/ (en) > > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: cannot use swig native shared libraries
Thank you for the suggestion, but doesn't help. Note again that I use it with no problems with plain java: ---file:SwigTest.java--- import swig_test.swig_test; public class SwigTest { public static void main(String[] args) { System.load(System.getProperty("user.dir") + "/libswig_test.so"); System.out.println(swig_test.swig_test_whatever()); } } ---cut--- gives: $ java SwigTest 3 as expected. On Apr 22, 9:18 pm, "Dimiter \"malkia\" Stanev" wrote: > I might be wrong, > > but shouldn't you compile the .c file to .o with "-fpic", and then > link with ld with "-shared"? > > maybe just adding "-fpic" to: > > gcc -fpic -shared ${JNI_CFLAGS} swig_test_wrap.c -o libswig_test.so > > might do it. > > On Apr 22, 6:41 am, "Antonio, Fabio Di Narzo" > > wrote: > > Hi all. > > I'm having problems with using swig-generated wrappers with Clojure. > > I'm running ubuntu-8.04-i386, gcc-4.2.4, swig-1.3.33, openjdk-1.6.0, > > latest clojure release. > > > I've cut down a minimal reproducible example. > > The swig file: > > ---file:swig_test.i--- > > %module swig_test > > %{ > > int swig_test_whatever() { > > return 3;} > > > %} > > int swig_test_whatever(); > > ---cut--- > > > Compile with: > > ---cut--- > > mkdir swig_test > > swig -java -package swig_test -outdir swig_test swig_test.i > > javac swig_test/*.java > > export JAVA_HOME=/usr/lib/jvm/java-6-openjdk > > export JNI_CFLAGS="-I${JAVA_HOME}/include -I${JAVA_HOME}/include/ > > linux" > > gcc -shared ${JNI_CFLAGS} swig_test_wrap.c -o libswig_test.so > > ---cut--- > > > The swig-generated java itfc file is: > > ---file:swig_test/swig_test.java--- > > package swig_test; > > public class swig_test { > > public static int swig_test_whatever() { > > return swig_testJNI.swig_test_whatever(); > > }} > > > ---cut--- > > > The clojure code: > > ---cut--- > > (import '(swig_test swig_test)) > > > (System/load > > (.concat (System/getProperty "user.dir") "/libswig_test.so")) > > (swig_test/swig_test_whatever) > > ---cut--- > > I get: > > java.lang.UnsatisfiedLinkError: > > swig_test.swig_testJNI.swig_test_whatever()I (NO_SOURCE_FILE:0) > > > I can use "manually written" JNI wrappers with clojure and, vice- > > versa, swig-generated wrappers with plain java code. What I'm missing > > here? Anybody can help? > > > Bests, > > Antonio, Fabio Di Narzo. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Enlive tutorial
Hi Adrian! Thanks for this tutorial, I put it on the wiki http://wiki.github.com/cgrand/enlive/getting-started (I fixed two typos: a missing paren and an extraneous colon and I simplified to-li). Speaking of to-li, (to-li ["one" "two"]) can be written (map (wrap :li) ["one" "two"]). While trying to write a tutorial myself, I realized that this kind of simple thing (replicating a simple element) was harder than replicating a complex element: (def simple (-> "Sample text" java.io.StringReader. html-resource first)) (def harder (-> "Author: a quote" java.io.StringReader. html-resource first)) (at simple [:li] #(for [x items] ((content x) %)) (at harder [:li] #(for [{:keys [link author quote]} items] (at % [:blockquote] (content quote) [:a] (do-> (set-attr :href link) (content author) I think I'll add a 'clone (or 'clone-for or a better name?) macro: (at simple [:li] (clone [x items] (content x))) (at harder [:li] (clone [{:keys [link author quote]} items] [:blockquote] (content quote) [:a] (do-> (set-attr :href link) (content author Thanks again Adrian! Christophe Adrian Cuthbertson a écrit : > I've uploaded a file > http://groups.google.co.za/group/clojure/web/enlive-tut1.txt?hl=en > which is a basic tutorial on getting started with Enlive (the html > transformation library). > > Christophe, this is intended as a contribution to the Enlive project, > so you're welcome to use it as part of the Enlive documentation, on > the wiki, etc. Also, please feel free to enhance it and make any > corrections. > > Enlive is an outstanding tool for web development. Thanks Christophe > for your initiatives. > > Regards, Adrian. > > > > > -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
Laurent PETIT a écrit : > Hi Meikel, > > It seems to me that your version is the only safe one so far, that > would succesfully indefinitely return values with this test: > > (dorun (mystery-function true? :foo (repeat true))) > > Mine, a new version of mine I'll never bother to publish, and > Christophe's all retain head. > To explain on Christophe's one for example: > > It uses (split-with) which, in case pred always match coll elements, > will retain the head of coll in etc, while eating more and more > elements of coll via running on run : > 1:21 user=> (defn mystery-function [pred coll] > (lazy-seq >(when (seq coll) > (let [[run etc] (split-with pred coll)] >(if (seq run) > (concat run (cons :foo (mystery-function pred etc))) > (cons (first coll) (mystery-function pred (rest coll > 1:22 user=> (dorun (mystery-function true? (repeat true))) > java.lang.OutOfMemoryError: GC overhead limit exceeded (repl-1:22) > Nice catch! -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
On Thu, Apr 23, 2009 at 9:44 AM, Laurent PETIT wrote: > > Hi Meikel, > > It seems to me that your version is the only safe one so far, that > would succesfully indefinitely return values with this test: > > (dorun (mystery-function true? :foo (repeat true))) > > Mine, a new version of mine I'll never bother to publish, and > Christophe's all retain head. > To explain on Christophe's one for example: > > It uses (split-with) which, in case pred always match coll elements, > will retain the head of coll in etc, while eating more and more > elements of coll via running on run : hmmm... Good point. user=> (nth (mystery-function (partial > 600) (iterate inc 0)) 1000) java.lang.OutOfMemoryError: Java heap space (NO_SOURCE_FILE:0) -- Michael Wood --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
On Thu, Apr 23, 2009 at 1:11 AM, Christophe Grand wrote: > > Hi all! > > (defn mystery-function [pred coll] > (lazy-seq > (when (seq coll) > (let [[run etc] (split-with pred coll)] > (if (seq run) > (concat run (cons :foo (mystery-function pred etc))) > (cons (first coll) (mystery-function pred (rest coll Ah yes, that looks like the one :) -- Michael Wood --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
Hi, Here is my final word (I promise :-): (defn mystery-function [f s o] (let [s (seq s) preds (map f s)] (mapcat #(if (and %2 (not %3)) [%1 o] [%1]) s preds (concat (rest preds) [false] I has only one drawback AFAIK (and depending on your use case, it may or may not be a problem to you): it is a little bit more eager than the pure lazy-seq version of Meikel (the combination of mapcat and (rest preds) makes it consume s 3 to 4 elements (don't remember) ahead of the result of mystery-function (but it's a constant). -- Laurent 2009/4/22 samppi : > > Let's say I have a sequence of integers: > (def a (3 9 1 5 102 -322 ...)) > > Is there a function for inserting an object—let's say :foo—after > elements that fulfill a certain predicate? > Furthermore, I mean inserting :foo after any block of elements that > fulfill it: > > (mystery-function (partial > 6) a) ; -> (3 :foo 9 1 5 :foo 102 > -322 :foo ...) > > Is it possible to do this without a loop? > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
You version does not work for certain kind of data, (as did mine), see my answer to Meikel for more detail, -- Laurent 2009/4/23 Christophe Grand : > > Hi all! > > (defn mystery-function [pred coll] > (lazy-seq > (when (seq coll) > (let [[run etc] (split-with pred coll)] > (if (seq run) > (concat run (cons :foo (mystery-function pred etc))) > (cons (first coll) (mystery-function pred (rest coll > > > Christophe > > > samppi a écrit : >> Let's say I have a sequence of integers: >> (def a (3 9 1 5 102 -322 ...)) >> >> Is there a function for inserting an object—let's say :foo—after >> elements that fulfill a certain predicate? >> Furthermore, I mean inserting :foo after any block of elements that >> fulfill it: >> >> (mystery-function (partial > 6) a) ; -> (3 :foo 9 1 5 :foo 102 >> -322 :foo ...) >> >> Is it possible to do this without a loop? >> > >> >> > > > -- > Professional: http://cgrand.net/ (fr) > On Clojure: http://clj-me.blogspot.com/ (en) > > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple sequence question: inserting something after blocks of fulfilling elements
Hi Meikel, It seems to me that your version is the only safe one so far, that would succesfully indefinitely return values with this test: (dorun (mystery-function true? :foo (repeat true))) Mine, a new version of mine I'll never bother to publish, and Christophe's all retain head. To explain on Christophe's one for example: It uses (split-with) which, in case pred always match coll elements, will retain the head of coll in etc, while eating more and more elements of coll via running on run : 1:21 user=> (defn mystery-function [pred coll] (lazy-seq (when (seq coll) (let [[run etc] (split-with pred coll)] (if (seq run) (concat run (cons :foo (mystery-function pred etc))) (cons (first coll) (mystery-function pred (rest coll 1:22 user=> (dorun (mystery-function true? (repeat true))) java.lang.OutOfMemoryError: GC overhead limit exceeded (repl-1:22) HTH, -- Laurent 2009/4/22 Meikel Brandmeyer : > Hi Micheal, > > Am 22.04.2009 um 21:18 schrieb Michael Wood: > >> Your version gives the same answer as mine, but I believe what he >> wants is something that skips over all the elements that pass the test >> and only inserts one instance of o after them. That's why in his >> example there is not a :foo after 1, but only after 5. >> >> Laurent's version gets this right. > > Oops. Sorry, misread the message. Another try. > > (defn mystery-function > [f o s] > (let [step (fn step [b s] > (lazy-seq > (if-let [s (seq s)] > (let [fst (first s)] > (cond > (and (f fst) b) (cons fst (step b (rest s))) > b (cons o (step false s)) > :else (cons fst (step (f fst) (rest s) > (when b (list o)] > (step false s))) > > 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 To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---