Boggle solver
Hey! As a learning exercise I wrote a simple boggle solver in clojure. I'm sure there is lots of room for improvement to make it more idiomatic and perform better so I would be grateful if anyone would care to cast their eye over it. http://wiki.github.com/phraemer/Boggle-Solver thanks, James --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Code formatter
Um, I use butterflies? On Nov 6, 5:35 pm, John Harrop wrote: > On Fri, Nov 6, 2009 at 7:41 PM, Tim Dysinger wrote: > > Use emacs! It formats your code while you type :) > > Nasty side effect though -- it formats your brain while you type, too. > Eventually you wind up a gibbering lunatic. :) I'll keep my Netbeans, > thanks. :) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: clojure.xml/parse of XHTML yields a 503 on the DTD
Perhaps xml/parse shouldn't fetch the DTD, as per the W3C recommendation? On Nov 7, 2:46 am, Christophe Grand wrote: > The w3c filters traffic to DTDs, see here for more > details:http://www.w3.org/blog/systeam/2008/02/08/w3c_s_excessive_dtd_traffic > > Christophe > > > > > > On Sat, Nov 7, 2009 at 7:21 AM, Joubert Nel wrote: > > > Hi, > > > I'm trying to parse the XHTML at > >http://wiki.stat.ucla.edu/socr/index.php/SOCR_Data_Dinov_042108_Antar... > > > But, I get a 503: > > > java.io.IOException: Server returned HTTP response code: 503 for URL: > >http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd > > (NO_SOURCE_FILE:12) > > > The DTD at this URL is available, however (I can get it just fine > > using my browser). > > > Advice? > > > Joubert > > -- > Professional:http://cgrand.net/(fr) > On Clojure:http://clj-me.cgrand.net/(en) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: newbie question
Can I play too? Non-lazy version (basically the same as Chouser's with reduce instead of loop): (defn partition-when [pred coll] (reduce #(if (pred %2) (conj %1 [%2]) (conj (pop %1) (conj (peek %1) %2))) [[]] coll)) user=> (partition-when odd? (range 1 15)) [[] [1 2] [3 4] [5 6] [7 8] [9 10] [11 12] [13 14]] user=> (partition-when even? (range 1 15)) [[1] [2 3] [4 5] [6 7] [8 9] [10 11] [12 13] [14]] And lazy version: (defn partition-when [pred coll] (let [heads (partial take-while (complement pred))] (cons (heads coll) (mapcat #(when (pred %1) [(cons %1 (heads %2))]) coll (iterate rest (rest coll)) user=> (partition-when odd? (range 1 15)) (() (1 2) (3 4) (5 6) (7 8) (9 10) (11 12) (13 14)) user=> (partition-when even? (range 1 15)) ((1) (2 3) (4 5) (6 7) (8 9) (10 11) (12 13) (14)) Christophe On Sat, Nov 7, 2009 at 1:47 AM, Alex Osborne wrote: > > Alex Osborne wrote: >> Like Mark's but using split-with instead of split-at: >> >> (defn partition-when [pred coll] >> (lazy-seq >> (when-let [[x & xs] (seq coll)] >> (let [[xs ys] (split-with (complement pred) xs)] >> (cons (cons x xs) (partition-when pred ys)) > > Just realised this is almost the same as Warren's -- I had missed > reading Warren's before posting. Thought it might be helpful if I > explain the differences: > > * lazy-seq on the outside of the conditional. This means the seq is > fully lazy, so if you never call first/next on it, nothing is ever run. > > * As suggested by others complement instead of NOT. > > * (when (seq coll) ...) instead of (if (empty? coll) () ...). We can > simplify things like this as (lazy-seq nil) => () and (seq ()) => nil. > > * Using destructuring instead of (first coll) (next coll). Makes it a > bit shorter and is quite useful if you're going to use the result of > (first coll) or (next coll) multiple times, but in this case it doesn't > really matter. > > > > -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.cgrand.net/ (en) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Avoiding reflection/hinting with byte-array.
I can't figure out how to avoid reflection, in the 'update' method of MessageDigest. It is overloaded on a single argument with either 'byte', 'byte[]', or 'java.nio.ByteBuffer'. (import '(java.security MessageDigest)) (set! *warn-on-reflection* true) The compiler didn't seem to like a tag that wasn't actually a class name: (def byte-array-class (class (make-array Byte/TYPE 0))) ;; "Unable to resolve classname: byte-array-class" (defn update1 [#^MessageDigest md #^{:tag byte-array-class} item] (.update md item)) And it seems to have no effect if I expand it as the tag: ;; "call to update can't be resolved." (defn update2 [#^MessageDigest md #^{:tag (class (make-array Byte/TYPE 0))} item] (.update md item)) In this particular case, I was able to work around the issue one of two ways, basically by using a different type. (defn workaround [#^MessageDigest md item] (.update md item 0 (count item))) (defn workaround2 [#^MessageDigest md item] (.update md (java.nio.ByteBuffer/wrap item))) Any ideas? BTW, my real use case is in a defmethod, where I handle several other types for the update. Thanks, David --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Avoiding reflection/hinting with byte-array.
On Sat, Nov 7, 2009 at 10:41 AM, David Brown wrote: > > I can't figure out how to avoid reflection, in the 'update' method of > MessageDigest. It is overloaded on a single argument with either > 'byte', 'byte[]', or 'java.nio.ByteBuffer'. > > (import '(java.security MessageDigest)) > (set! *warn-on-reflection* true) > > The compiler didn't seem to like a tag that wasn't actually a class > name: > > (def byte-array-class > (class (make-array Byte/TYPE 0))) > > ;; "Unable to resolve classname: byte-array-class" > (defn update1 > [#^MessageDigest md #^{:tag byte-array-class} item] > (.update md item)) Right, :tag values should be symbols, not classes or instances of those classes. Most of those symbols name actual Java classnames but a few other symbols are supported, mostly for arrays of primitives: objects Object[].class; ints int[].class; longslong[].class; floats float[].class; doubles double[].class; charschar[].class; shorts short[].class; bytesbyte[].class; booleans boolean[].class; This should work: (defn update1 [#^MessageDigest md, #^bytes item] (.update md item)) --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: clojure.xml/parse of XHTML yields a 503 on the DTD
On 07.11.2009, at 15:07, Joubert Nel wrote: > > Perhaps xml/parse shouldn't fetch the DTD, as per the W3C > recommendation? > It's highly likely it's the underlying Java parser that does so (even though it doesn't need to) - the same problem would be there if a Java program running in the same environment parsed the XML. A catalog file would help. Stefan -- Stefan Tilkov, http://www.innoq.com/blog/st/ --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: ICFP Proposals
Thank you Tim, I certainly appreciate information like this! I am busy writing a paper for the IEEE conference later on in 2010. Its for my honours university work. Bluetooth social messaging and proximity related activities in and around the university campus. I have done a lot of work with JAVA, & JAVA byte code this year. I wrote my own small DSL language for Abstract Algebra. A cycle number compiler, where a user could write maths statements as they would on paper and have it compiled into JAVA byte code, that could run on any JVM. (I did not quite get my AST (Abstract Syntax Tree) 100% correct :( ) Either way, I go my hands messy with JAVA byte code & the sable-jasmin JAVA byte code compiler. I read a paper where a lisp was written to run natively on ARM, PPC, x86 cores! Here is the information about the paper I read. Verified LISP Implementations on ARM, x86 and PowerPC Magnus O. Myreen and Michael J.C. Gordon Computer Laboratory, University of Cambridge, UK google around for the paper! Its very interesting. On Sat, Nov 7, 2009 at 7:47 AM, John Harrop wrote: > On Fri, Nov 6, 2009 at 3:36 PM, Tim Dysinger wrote: > >> If anyone's interested there is a call for proposals for ICFP 2010 >> http://www.icfpconference.org/icfp2010/cfwp.html & due by Nov 20 > > > In the future, you might want to tell people that "ICFP" stands for > "International Conference on Functional Programming" instead of assuming > that everyone either already knows or is willing to click through the link > to find out. You might get more people interested if your announcement > messages are a little less cryptic. :) > > > > -- Dimitri Mallis http://www.dimitrimallis.co.za/ --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
web REPL
A couple of months ago I saw a web site that provided a web-based REPL for many programming languages including Clojure. I can't find it now. Does anybody have that URL? -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Avoiding reflection/hinting with byte-array.
On Sat, Nov 07, 2009 at 11:48:32AM -0500, Chouser wrote: >This should work: > >(defn update1 [#^MessageDigest md, #^bytes item] > (.update md item)) This does seem to work, thanks. Any reason that 'doubles' is also defined as an array cast function, but 'bytes' is not? David --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Avoiding reflection/hinting with byte-array.
On Sat, Nov 7, 2009 at 2:57 PM, David Brown wrote: > > On Sat, Nov 07, 2009 at 11:48:32AM -0500, Chouser wrote: > >>This should work: >> >> (defn update1 [#^MessageDigest md, #^bytes item] >> (.update md item)) > > This does seem to work, thanks. > > Any reason that 'doubles' is also defined as an array cast function, > but 'bytes' is not? I don't know of any deep reason. Not only bytes, but also array-cast functions don't exist for chars, shorts or booleans. Also there are factory functions for several primitive array types, but char-array, short-array, byte-array, and boolean-array don't exist. --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: web REPL
On Sat, Nov 7, 2009 at 2:50 PM, Mark Volkmann wrote: > > A couple of months ago I saw a web site that provided a web-based REPL > for many programming languages including Clojure. I can't find it now. > Does anybody have that URL? Perhaps this one on Google AppEngine? http://lotrepls.appspot.com/ --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Adding meta data to a function (from a macro)
I'm trying to do this: (defmacro my-defn [name & body] `(defn- #^{ :foo-tag "blah" } ~name [] ~...@body)) The idea is that foo will be defined and that {:foo-tag "blah"} is added to its meta-data. But that does not seem to work: user> (my-defn foo (println "Hello")) #'user/foo user> (foo) Hello nil user> (meta #'foo) {:ns #, :name foo, :file "NO_SOURCE_FILE", :line 1, :arglists ([]), :private true} What is the proper way to do this? S. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Adding meta data to a function (from a macro)
Stefan Arentz wrote: > > I'm trying to do this: > > (defmacro my-defn [name & body] >`(defn- #^{ :foo-tag "blah" } ~name [] > ~...@body)) > > The idea is that foo will be defined and that {:foo-tag "blah"} is > added to its meta-data. > > But that does not seem to work: Try this: (defmacro my-defn [name & body] `(defn- ~(with-meta name {:foo-tag "blah"}) [] ~...@body)) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Adding meta data to a function (from a macro)
>> The idea is that foo will be defined and that {:foo-tag "blah"} is >> added to its meta-data. ... and to explain *why*: user=> (pprint (read-string "(defmacro my-defn [name & body] `(defn- #^{ :foo-tag \"blah\" } ~name [] ~...@body))")) (defmacro my-defn [name & body] (clojure.core/seq (clojure.core/concat (clojure.core/list 'clojure.core/defn-) (clojure.core/list name) (clojure.core/list (clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat body))) No mention of foo-tag in there. #^ is a reader macro that annotates the next token read with metadata. It's not a form that persists into the macroexpansion, so it doesn't take effect in your generated defn-. (There are good reasons for this, not just "that's the way it is": a macro is just like any other function, and you might want to add metadata such as type annotations just as you would in normal functions.) Using with-meta *does* pass through into the macroexpansion, which is what you want. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Functions and vars and meta-data
Another one related to my previous question about meta-data. user> (defn #^{ :xxx 1} foo [] "foo") #'user/foo user> (defn #^{ :xxx 2} bar [] "bar") #'user/bar I need to do something similar to this: user> (map #(:xxx (meta %)) [foo bar]) (nil nil) Basically accessing the meta data of a function of which I only know the 'name'. (Because that is what my macro takes as one of its parameters) I know it works when I use the #' reader macro. user> (map #(:xxx (meta %)) [#'foo #'bar]) (1 2) But I'm using this in a bigger macro that takes a bunch of functions as a parameter. Is there a way to make this work or should I 'translate' the functions that I take by name with (var foo)? I must admin that I don't fully understand the difference between foo and #'foo. That is probably why I'm making this beginner mistake :-) S. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Functions and vars and meta-data
On Sat, Nov 7, 2009 at 8:04 PM, Stefan Arentz wrote: > But I'm using this in a bigger macro that takes a bunch of functions > as a parameter. Is there a way to make this work or should I > 'translate' the functions that I take by name with (var foo)? You'll need to translate the symbols into vars using resolve, I think. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Functions and vars and meta-data
On 2009-11-07, at 8:28 PM, John Harrop wrote: > On Sat, Nov 7, 2009 at 8:04 PM, Stefan Arentz > wrote: > But I'm using this in a bigger macro that takes a bunch of functions > as a parameter. Is there a way to make this work or should I > 'translate' the functions that I take by name with (var foo)? > > You'll need to translate the symbols into vars using resolve, I think. Hmmm user=> (var foo) #'user/foo user=> (meta (var foo)) {:ns #, :name foo, :file "NO_SOURCE_FILE", :line 1, :arglists ([]), :xxx 1} user=> ((var foo)) "foo" I'll give this a try in my macro later today :-) S. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Functions and vars and meta-data
On Sat, Nov 7, 2009 at 8:34 PM, Stefan Arentz wrote: > On 2009-11-07, at 8:28 PM, John Harrop wrote: > > > On Sat, Nov 7, 2009 at 8:04 PM, Stefan Arentz > > wrote: > > But I'm using this in a bigger macro that takes a bunch of functions > > as a parameter. Is there a way to make this work or should I > > 'translate' the functions that I take by name with (var foo)? > > > > You'll need to translate the symbols into vars using resolve, I think. > > Hmmm > > user=> (var foo) > #'user/foo > > user=> (meta (var foo)) > {:ns #, :name foo, :file "NO_SOURCE_FILE", :line > 1, :arglists ([]), :xxx 1} > > user=> ((var foo)) > "foo" > > I'll give this a try in my macro later today :-) Eh. `(var ~argument) should work. You'll need resolve if you ever want to do this in a function though, or use the var object in the macro body itself (as opposed to only using the var object in the code that results from the macro's expansion). --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Functions and vars and meta-data
Stefan Arentz wrote: > I must admin that I don't fully understand the difference between foo > and #'foo. That is probably why I'm making this beginner mistake :-) The difference takes some explanation. So without further ado... Functions and Metadata: in Vivacious Gory Detail There's three types of objects in play here: symbols, vars and functions: (defn foo []) (type foo) => user$foo_4703 (a class implementing IFn) (type 'foo) => clojure.lang.Symbol (type #'foo) => clojure.lang.Var A symbol is just a name. A Var is an object that is named by a symbol and "bound" to a value. Normally Clojure will "evaluate" symbols, for example when you type this in the REPL: foo => # The way it does this is by first "resolving" the symbol foo in the current namespace. A namespace is essentialy just a map from symbols to vars. So after resolving, it then has a Var object. A Var, is as it's name suggests, a variable. It consist of a name (symbol + namespace), metadata map and a value (called the binding). There can actually be multiple bindings (for thread-local variables and such) but normally there is only one, the "root binding". So Clojure evaluates the var by getting the value bound to it. Now what if you ask Clojure to evaluate a vector of symbols? It evaluates each symbol (first "resolving" to get a var and then taking the binding) and gives you back a vector of function objects: (def some-number 4) [foo inc some-number] => [# # 4] Now macros. When Clojure sees something like this: (bar foo inc some-number) It will first resolve the symbol bar in the current namespace (in this case the namespace is "user"). Remember resolving gives you a Var, so in this case the Var #'user/foo. Clojure then looks at the metadata of the Var to determine whether it is bound to a macro or a function. Normally Clojure evaluates the arguments [foo inc some-number] producing [# # 4] and then calls the binding value (the actual function object) with them. Alternatively if the var's metadata says it is bound to a macro, Clojure doesn't evaluate the arguments. It just calls the binding with the symbols 'foo 'inc and 'some-number. Clojure will then evaluate the return value of the macro (usually another bunch of symbols and literals). So when I write this: (defmacro mymac [sym] (println "symbol is:" sym) sym) (mymac foo) => symbol is: foo # Clojure passes mymac a symbol object. We print out the symbol "foo" and then return it. Clojure then evaluates the return value (the symbol) producing the actual function object that foo is bound to. Now for metadata "on" functoins. When you write this: (defn #^{:xxx 1} greet [] "hello") The #^{...} syntax means that Clojure creates a list of two symbols (defn and greet), and empty vector and a string "hello". The second symbol greet has the metadata {:xxx 1} associated with it. This will be macro-expanded into this: (def #^{:xxx 1} greet (fn ([] "hello"))) The greet symbol still keeps it's metadata. Now the def special form: 1. Creates a var. 2. Copies the metadata {:xxx 1} from the symbol greet to the var. 3. Binds the var to the function (fn ([] "hello")). 4. Creates a mapping in the current namespace ("user") from the symbol greet to the var. Now notice the function object itself never has any metadata associated with it? In fact normal Clojure function objects cannot have any metadata: (with-meta (fn []) {:xxx 1}) => [Thrown class java.lang.UnsupportedOperationException] So now suppose we want something that achieves this: (def #^{:xxx 2} groan (fn ([] "arrrgghhh"))) (get-xxx greet groan) => [1 2] So we need to get at the vars for greet and groan. First thing to note is that get-xxx has to be a macro, if it were a function greet and groan would be evaluated to function objects, which don't have metadata. So what we need is a macro that will take the greet and groan symbols, resolve them to get vars and then lookup :xxx in the metadata of the vars. So something like: (defmacro get-xxx [& syms] (vec (map #(get (meta (resolve %)) :xxx) syms))) Now what if we want get-xxx to take a vector? Well no worries we just change the signature: (defmacro get-xxx [syms] (vec (map #(get (meta (resolve %)) :xxx) syms))) (get-xxx [greet groan]) => [1 2] But hang on, what's going on with this? (let [fns [greet groan]] (get-xxx fns)) => java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol Remember that the arguments to macros aren't evaluated, so get-xxx is being passed the symbol "fns" not a vector! Well what if use macroexpand to explicitly pass it the vector? (let [fns [greet groan]] (macroexpand (list 'get-xxx fns))) => java.lang.ClassCastException: user$greet__5100 cannot be cast to clojure.lang.Symbol Another problem. The let creates a vector function objects not of symbols. So to
Re: newbie question
On Nov 6, 12:10 pm, John Harrop wrote: > On Fri, Nov 6, 2009 at 1:07 PM, John Harrop wrote: > > On Fri, Nov 6, 2009 at 1:01 PM, Warren Wood > > wrote: > > >> In the meantime, I came up with the following, which seems to work. > >> I'm sure it can be improved. > > >> (defn NOT [pred] (fn [x] (not (pred x > > >> ... > > > Which leads me to another question, are there standard functions > >> sitting around somewhere already to do boolean combinations of > >> predicates (conjoin, disjoin, negate perhaps?)? Like my NOT above. > > > How about complement? > > > user=> (def x (complement even?)) > > #'user/x > > user=> (x 4) > > false > > user=> (x 3) > > true > > And WHAT the devil is with complement's messy implementation? (defn > complement [f] (comp not f)) seems much cleaner. :) Ok, I'm embarrassed that I didn't find complement. I know I had known about it at one time. I think I had been wondering about versions of union and intersection that would apply to predicates as well as sets, since mathematically a predicate can be deemed as defining the set of all things for which it is true. I was thinking of a procedure like AND (again probably not a great name... maybe conjunction would be better). I don't think anything like comp can be used in this case since and is a macro. (defn AND [f g] (fn [x] (and (f x) (g x Is there any standard function like THAT? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: newbie question
Thanks, that was indeed helpful! On Nov 6, 6:47 pm, Alex Osborne wrote: > Alex Osborne wrote: > > Like Mark's but using split-with instead of split-at: > > > (defn partition-when [pred coll] > > (lazy-seq > > (when-let [[x & xs] (seq coll)] > > (let [[xs ys] (split-with (complement pred) xs)] > > (cons (cons x xs) (partition-when pred ys)) > > Just realised this is almost the same as Warren's -- I had missed > reading Warren's before posting. Thought it might be helpful if I > explain the differences: > > * lazy-seq on the outside of the conditional. This means the seq is > fully lazy, so if you never call first/next on it, nothing is ever run. > > * As suggested by others complement instead of NOT. > > * (when (seq coll) ...) instead of (if (empty? coll) () ...). We can > simplify things like this as (lazy-seq nil) => () and (seq ()) => nil. > > * Using destructuring instead of (first coll) (next coll). Makes it a > bit shorter and is quite useful if you're going to use the result of > (first coll) or (next coll) multiple times, but in this case it doesn't > really matter. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Gensym collisions can be engineered.
user=> (def q 'G__723) #'user/q user=> (def r (gensym)) #'user/r user=> q G__723 user=> r G__723 user=> (= q r) true It's possible to anticipate the next gensym name that will be generated and then engineer a collision, and therefore possibly variable capture unintended by the author of a macro. It looks like "manually" generating a name does not remove it from the pool of allowable future gensym names. This shouldn't tend to cause accidental problems in practice, since gensym names tend not to collide with the kinds of identifiers programmers ordinarily use. Nonetheless it can be partially fixed comparatively easily by adding to the runtime a WeakHashMap into which a reference to any symbol, however created, is placed and modifying the gensym-generator to, at the point where it currently returns a value, first check if the WeakHashMap contains it already and if so, generate the next one, and the next, as needed until it gets a not-in-use name. This requires gensym creation and normal symbol creation to occur in a global lock but symbol creation rarely occurs at runtime and even more rarely in any kind of hot-spot at runtime. The use of WeakHashMap would prevent the runtime clogging up with ungarbagecollectable symbols, so the memory overhead of adding this would be smallish, one machine pointer per in-use symbol or so, equivalent to if every symbol had a few more characters in its name. This would stop gensym from producing a name already in use. It wouldn't prevent a gensym being generated somewhere and *then* the identical name being put together someplace else and passed to the symbol function, though; a small loophole. Collisions between gensyms in preexisting code and an enclosing lexical scope in new code would become impossible, but collisions between gensyms in preexisting code and an enclosed lexical scope (e.g. a macro-invocation body, such as a loop body) would remain theoretically possible. That last loophole can't really be plugged without giving Clojure "true" gensyms (uninterned anywhere), which would bring with it its own architectural problems. If that change were made, the above REPL interaction would be possible up to the (= q r) evaluation, but that would return false despite the names looking the same, so the symbols wouldn't really collide even though a collision of their printed representations could still be engineered. One bothersome consequence though would be that the textual output of macroexpand-1 could no longer always be substituted for a macro call in source code without altering the run-time semantics of that code, even when the macro's expansion-generation does not have side effects. (To reproduce that REPL interaction for yourself, evaluate (gensym) at the REPL and note the number. Add seven and then evaluate (def q 'G__#) with # replaced with the sum. Then evaluate (def r (gensym)) and, if you like, skip straight to (= q r). If that doesn't work, the number it goes up by must have changed between Clojure 1.0 and whatever version you're using; evaluate (gensym), then (def q 'xyzzy), then (gensym) again and note the increment and use that instead of seven. Oh, and don't have any background threads running in that JVM instance that might do something autonomously that causes a gensym to be generated.) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: newbie question
Thought of this, which I like better. Again, I'm surprised if conjunction is not already a standard function, but I can't find it. I'm still a bit tempted to call it AND for readabilty of code. (I spent some time studying combinatory logic back in the day. (I even had a "Curry Fellowship" at Penn State where Haskell Curry used to work.) Can't remember what combinator letter my "dual" function is.) (defn dual [x] (fn [f] (f x))) (defn conjunction [& preds] (fn [x] (every? (dual x) preds))) (filter (conjunction even? (partial >= 16) (partial <= 9)) (range 1 20)) evaluates to (10 12 14 16) On Nov 7, 9:39 pm, Warren Wood wrote: > On Nov 6, 12:10 pm, John Harrop wrote: > > > > > > > On Fri, Nov 6, 2009 at 1:07 PM, John Harrop wrote: > > > On Fri, Nov 6, 2009 at 1:01 PM, Warren Wood > > > wrote: > > > >> In the meantime, I came up with the following, which seems to work. > > >> I'm sure it can be improved. > > > >> (defn NOT [pred] (fn [x] (not (pred x > > > >> ... > > > > Which leads me to another question, are there standard functions > > >> sitting around somewhere already to do boolean combinations of > > >> predicates (conjoin, disjoin, negate perhaps?)? Like my NOT above. > > > > How about complement? > > > > user=> (def x (complement even?)) > > > #'user/x > > > user=> (x 4) > > > false > > > user=> (x 3) > > > true > > > And WHAT the devil is with complement's messy implementation? (defn > > complement [f] (comp not f)) seems much cleaner. :) > > Ok, I'm embarrassed that I didn't find complement. I know I had known > about it at one time. I think I had been wondering about versions of > union and intersection that would apply to predicates as well as sets, > since mathematically a predicate can be deemed as defining the set of > all things for which it is true. I was thinking of a procedure like > AND (again probably not a great name... maybe conjunction would be > better). I don't think anything like comp can be used in this case > since and is a macro. > > (defn AND [f g] (fn [x] (and (f x) (g x > > Is there any standard function like THAT? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Another "closure" available
Hmm, someone else has made another "closure" available :). http://googlecode.blogspot.com/2009/11/introducing-closure-tools.html -Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Another "closure" available
On Nov 8, 6:08 am, Adrian Cuthbertson wrote: > Hmm, someone else has made another "closure" available :). > > http://googlecode.blogspot.com/2009/11/introducing-closure-tools.html There's also Clozure Common Lisp [1], which is conceptually closer to Clojure. [1] http://www.clozure.com/clozurecl.html --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---