Observing namespace changes
Hello, Is it possible for my code to "subscribe" to events of type "namespace change" which would inform of deltas on top level namespaces : - added symbol - removed symbol - changed root var binding of a symbol Indeed, I'm currently implementing a little "namespace browser" View for clojuredev (eclipse clojure development tool - aka CLJDT), and I'm concerned with how to efficiently and accurately keep my namespace browser in sync with the clojure environment it is observing. Thanks in advance, -- 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 -~--~~~~--~~--~--~---
*1 *2 isn't working properly
Hey, I'm trying to run my first Clojure example user=> (defn hello [name] (str "Cool! " name)) #'user/hello user=> (hello "Google") "Cool! Google" user=> (hello "Wicket") "Cool! Wicket" user=> (str *1) "Cool! Wicket" user=> (str *2) "Cool! Wicket" Isn't (str *2) supposed to return "Cool! Google" ? Environment: Clojure20081217 Ubuntu 8.04 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: *1 *2 isn't working properly
By the time you evaluated *2, the second most recent result was what it showed you. All top level evaluations count. In short, you were Heisenberged. --Steve On Jan 14, 2009, at 3:59 AM, HB wrote: > > Hey, > I'm trying to run my first Clojure example > > user=> (defn hello [name] (str "Cool! " name)) > #'user/hello > user=> (hello "Google") > "Cool! Google" > user=> (hello "Wicket") > "Cool! Wicket" > user=> (str *1) > "Cool! Wicket" > user=> (str *2) > "Cool! Wicket" > > Isn't (str *2) supposed to return "Cool! Google" ? > Environment: > Clojure20081217 > Ubuntu 8.04 > > 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: *1 *2 isn't working properly
Here's an example of *1 *2 *3 1:1 user=> (str "gavin") "gavin" 1:2 user=> (str "teri") "teri" 1:3 user=> (str "brian") "brian" 1:4 user=> (str-join " " [*1 *2 *3]) "brian teri gavin" On Wed, Jan 14, 2009 at 2:29 AM, Stephen C. Gilardi wrote: > > By the time you evaluated *2, the second most recent result was what > it showed you. All top level evaluations count. > > In short, you were Heisenberged. > > --Steve > > On Jan 14, 2009, at 3:59 AM, HB wrote: > > > > > Hey, > > I'm trying to run my first Clojure example > > > > user=> (defn hello [name] (str "Cool! " name)) > > #'user/hello > > user=> (hello "Google") > > "Cool! Google" > > user=> (hello "Wicket") > > "Cool! Wicket" > > user=> (str *1) > > "Cool! Wicket" > > user=> (str *2) > > "Cool! Wicket" > > > > Isn't (str *2) supposed to return "Cool! Google" ? > > Environment: > > Clojure20081217 > > Ubuntu 8.04 > > > > 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: *1 *2 isn't working properly
I didn't get you, would you please hold my hand and walking me as you explain line by line what is happening in my code? On Jan 14, 11:29 am, "Stephen C. Gilardi" wrote: > By the time you evaluated *2, the second most recent result was what > it showed you. All top level evaluations count. > > In short, you were Heisenberged. > > --Steve > > On Jan 14, 2009, at 3:59 AM, HB wrote: > > > > > Hey, > > I'm trying to run my first Clojure example > > > user=> (defn hello [name] (str "Cool! " name)) > > #'user/hello > > user=> (hello "Google") > > "Cool! Google" > > user=> (hello "Wicket") > > "Cool! Wicket" > > user=> (str *1) > > "Cool! Wicket" > > user=> (str *2) > > "Cool! Wicket" > > > Isn't (str *2) supposed to return "Cool! Google" ? > > Environment: > > Clojure20081217 > > Ubuntu 8.04 > > > 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 -~--~~~~--~~--~--~---
question about understanding/exploring agents
Hi all. I am trying to figure out what the effect of the agent-function is on the efficiency of concurrency. Here is something I do not really understand. I've a fibonacci function and a simple multiplication, both are wrapped in their respective dotimes 100k loop. However, on this 4core machine, the fib behaves as I would expect when I scale up the number of threads, while the multiplication barely seems to benefit from the 4 cores. The only difference I see between the two functions is that the fib is recursive, but I am not quite sure why that would matter. Can anyone shine a light? (defn fib [n] "nonoptimized fib" (if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2) (defn loopfib [n] (dotimes [i 10] (fib n))) (defn loopmult [n] (dotimes [i 10] (* n n n n n 5000 5000 4000 3000 9000))) (dotimes [t 12] (println "threads: " t) (time (let [agents (for [i (range t)] (agent 4))] (do (doseq [a agents] (send-off a loopfib)) (apply await agents (time (let [agents (for [i (range t)] (agent 4))] (do (doseq [a agents] (send-off a loopmult)) (apply await agents) result: threads: 0 "Elapsed time: 0.279713 msecs" "Elapsed time: 0.38143 msecs" threads: 1 "Elapsed time: 205.458949 msecs" "Elapsed time: 209.625273 msecs" threads: 2 "Elapsed time: 205.610849 msecs" "Elapsed time: 357.785344 msecs" threads: 3 "Elapsed time: 205.05658 msecs" "Elapsed time: 401.39515 msecs" threads: 4 "Elapsed time: 221.140317 msecs" "Elapsed time: 469.746969 msecs" threads: 5 "Elapsed time: 309.472848 msecs" "Elapsed time: 597.872393 msecs" threads: 6 "Elapsed time: 336.087848 msecs" "Elapsed time: 714.874749 msecs" threads: 7 "Elapsed time: 382.883045 msecs" "Elapsed time: 846.888746 msecs" threads: 8 "Elapsed time: 442.588196 msecs" "Elapsed time: 960.687669 msecs" threads: 9 "Elapsed time: 478.862175 msecs" "Elapsed time: 1094.892017 msecs" threads: 10 "Elapsed time: 514.380769 msecs" "Elapsed time: 1219.219582 msecs" threads: 11 "Elapsed time: 580.265387 msecs" "Elapsed time: 1361.204858 msecs" --~--~-~--~~~---~--~~ 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: Learning Clojure WikiBook
On Jan 13, 11:35 am, Rock wrote: > I've added some info regarding the backquote expansion mechanism in > the Reader section here: > > http://en.wikibooks.org/wiki/Learning_Clojure#The_Reader > > I tried to answer the author's question regarding the possible > expansion order in nested backquotes and the general algorithm Clojure > apparently employs, which seems to be very similar to the one > "suggested" in the CL HyperSpec, though practically every CL > implementation adopts its own and is free to do so. > > I hope I get his and, of course, Rich's blessing. > > Happy Clojure. > > Rock I've just noticed that my changes attend approval to be viewed by anyone else. Here's the part I edited: Reader Macros A reader macro (not to be confused with a regular macro) is a special character sequence which, when encountered by the reader, modifies the reader behavior. Reader macros exist for syntactical concision and convenience. 'foo ; (quote foo) #'foo ; (var foo) @foo ; (clojure/deref foo) ^foo ; (clojure/meta foo) #^{:ack bar} foo ; (clojure/with-meta foo {:ack bar}) #"regex pattern" ; create a java.util.regex.Pattern from the string (this is done at read time, ; so the evaluator is handed a Pattern, not a form that evaluates into a Pattern) #(foo %2 bar %) ; (fn [a b] (foo b bar a)) The #() syntax is intended for very short functions being passed as arguments. It takes parameters named %, %2, %3, %n ... %&. The most complicated reader macro is syntax-quote, denoted by ` (back- tick). When used on a symbol, syntax-quote is like quote but the symbol is resolved to its fully-qualified name: `meow; (quote cat/meow) ...assuming we are in the namespace cat When used on a list, vector, or map form, syntax-quote quotes the whole form except, a) all symbols are resolved to their fully- qualified names and, b) components preceded by ~ are unquoted: (defn rabbit [] 3) `(moose ~(rabbit)) ; (quote (cat/moose 3)) ...assume namespace cat (def zebra [1 2 3]) `(moose ~zebra); (quote (cat/moose [1 2 3])) Components preceded by ~@ are unquote-spliced: `(moose ~...@zebra) ; (quote (cat/moose 1 2 3)) If a symbol is non-namespace-qualified and ends with '#', it is resolved to a generated symbol with the same name to which '_' and a unique id have been appended. e.g. x# will resolve to x_123. All references to that symbol within a syntax-quoted expression resolve to the same generated symbol. For all forms other than Symbols, Lists, Vectors and Maps, `x is the same as 'x. Syntax-quotes can be nested within other syntax-quotes: `(moose ~(squirrel `(whale ~zebra))) For Lists/Vectors/Maps, syntax-quote establishes a template of the corresponding data structure. Within the template, unqualified forms behave as if recursively syntax-quoted. `(x1 x2 x3 ... xn) may be interpreted to mean (clojure.core/concat [x1] [x2] [x3] ... [xn]) where the brackets are used to indicate a transformation of an xj as follows: * [form] is interpreted as (clojure.core/list `form), which contains a syntax-quoted form that must then be further interpreted. * [~form] is interpreted as (clojure.core/list form). * [...@form] is interpreted as form. If the syntax-quote syntax is nested, the innermost syntax-quoted form should be expanded first. This means that if several ~ occur in a row, the leftmost one belongs to the innermost syntax-quote. Following the rules above, an expression such as ``(~~a) would be expanded as follows: (concat (list `concat) (list (concat (list `list) (list a and then evaluated. Of course the same expression could also be equivalently expanded as (list `list a) which is indeed much easier to read. Clojure employs the first algorithm which is more generally applicable in cases where there is also splicing. The principle is that the result of an expression with syntax-quotes nested to depth k is the same only after k successive evaluations have been performed, regardless of the kind of expansion algorithm (Guy Steele). At this time, Clojure does not allow you to define your own reader macros, but this may change in the future. --~--~-~--~~~---~--~~ 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: *1 *2 isn't working properly
On Wed, 14 Jan 2009 02:47:23 -0800 (PST) HB wrote: > > I didn't get you, would you please hold my hand and walking me as you > explain line by line what is happening in my code? the simple way to work it out is to count up from where you are running the code, so if you use *2, count up to see what was the second last thing that was output, which in this case was the result of (hello "Wicket"), if you had used *3, that would be "Cool! Google" --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Can't get clojure or clojure.contrib via SVN over https
Hi all, I realised today that my "work" machine still has the old Sourceforge version of clojure-contrib but when I try to get the latest version from google-code it falls over - most likely due to a proxy: >svn checkout http://clojure-contrib.googlecode.com/svn/trunk/clojure-contrib svn: REPORT request failed on '/svn/!svn/vcc/default' svn: REPORT of '/svn/!svn/vcc/default': 400 Bad Request ( http://clojure-contrib.googlecode.com) I've had this before and worked around it by using https to get the sourceforge version but for google-code you have to be a member of the project to use https I think. Anyone else have the same problem? Is there a way around this? 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: *1 *2 isn't working properly
Lets say that the result of each method invocation will be saved in a stack. The stack now contains, Google and Wicket When I run (str *1) , I will get the last item in the stack which it is "Wicket" and the result of the method invocation iteself (which it is also "Wicket") will be pushed into the stack. So the stack now contains: Google, Wicket, Wicket Am I right? On Jan 14, 1:33 pm, Martin Wood-Mitrovski wrote: > On Wed, 14 Jan 2009 02:47:23 -0800 (PST) > > HB wrote: > > > I didn't get you, would you please hold my hand and walking me as you > > explain line by line what is happening in my code? > > the simple way to work it out is to count up from where you are running > the code, so if you use *2, count up to see what was the second last > thing that was output, which in this case was the result of (hello > "Wicket"), if you had used *3, that would be "Cool! Google" --~--~-~--~~~---~--~~ 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: *1 *2 isn't working properly
On Wed, 14 Jan 2009 04:15:18 -0800 (PST) HB wrote: > > Lets say that the result of each method invocation will be saved in a > stack. > The stack now contains, Google and Wicket > When I run (str *1) , I will get the last item in the stack which it > is "Wicket" and the result of the method invocation iteself (which it > is also "Wicket") will be pushed into the stack. > So the stack now contains: > Google, Wicket, Wicket > Am I right? sounds right to me. --~--~-~--~~~---~--~~ 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: detecting running as script
Hi all, I managed to make this work by first making a clj script as instructed here: http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started (thanks, great stuff!) But there is still one small thing: Is there an elegant way to "unwrap" the passed command line arguments? And is there any module in Clojure to parse command line arguments like Ruby and Pythons "optparse"? My tiny script: -- #! /usr/bin/env clj (defn somefunc [& args] (println "somefunc!" args)) (defn main [& args] (somefunc args)) (when *command-line-args* (main *command-line-args*)) - When I run it from the command line I get: $ ./test.clj this is the command line args somefunc! (((./test.clj this is the command line args))) $ Best, Grunde On 4 Jan, 14:58, "Mark Volkmann" wrote: > On Sun, Jan 4, 2009 at 3:57 AM, Timothy Pratley > > > > wrote: > > >> I suspect that *command-line-arguments* would have "myapp.clj" as the > >> 0th element in the > >> clj myapp.clj > >> Can't test right now though sorry. > > > I tested this and it does work for me. If it does not work for you is > > most likely in your clj script or bat file. I noticed on the wiki the > > incorrect advice was given: > > java -cp %CLOJURE_JAR%;%CONTRIB_JAR% clojure.lang.Script %1 > > > I've updated the wiki with the correct usage: > > java -cp %CLOJURE_JAR%;%CONTRIB_JAR% clojure.lang.Script %1 -- %* > > > Check your script for the -- between script name and arglist. Note > > that %* includes %1. > > > script-test.clj: > > (if *command-line-args* > > (println "SCRIPT") > > (println "REPL")) > > > C:\java>clj script-test.clj > > SCRIPT > > > C:\java>clj > > Clojure > > user=> (load-file "script-test.clj") > > REPL > > nil > > Thanks! I've got it working this way now. My script defines a "main" > function. At the bottom of the script I do this: > > ; Only run the application automatically if run as a script, > ; not if loaded in a REPL with load-file. > (if *command-line-args* (main)) > > -- > 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 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: *1 *2 isn't working properly
is that just for fun or can it be used in programs? HB, how'd you even learn about that so fast? do I suck at reading? On Wed, Jan 14, 2009 at 7:20 AM, Martin Wood-Mitrovski wrote: > > On Wed, 14 Jan 2009 04:15:18 -0800 (PST) > HB wrote: > > > > > Lets say that the result of each method invocation will be saved in a > > stack. > > The stack now contains, Google and Wicket > > When I run (str *1) , I will get the last item in the stack which it > > is "Wicket" and the result of the method invocation iteself (which it > > is also "Wicket") will be pushed into the stack. > > So the stack now contains: > > Google, Wicket, Wicket > > Am I right? > > sounds right to me. > > > > --~--~-~--~~~---~--~~ 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: *1 *2 isn't working properly
>> is that just for fun or can it be used in programs? Consider it a shenanigan :) >> HB, how'd you even learn about that so fast? do I suck at reading? I'm reading the beta version of "Programming Clojure" ; Am I doing fine Stu? :D On Jan 14, 2:31 pm, e wrote: > is that just for fun or can it be used in programs? HB, how'd you even > learn about that so fast? do I suck at reading? > > On Wed, Jan 14, 2009 at 7:20 AM, Martin Wood-Mitrovski > wrote: > > > > > On Wed, 14 Jan 2009 04:15:18 -0800 (PST) > > HB wrote: > > > > Lets say that the result of each method invocation will be saved in a > > > stack. > > > The stack now contains, Google and Wicket > > > When I run (str *1) , I will get the last item in the stack which it > > > is "Wicket" and the result of the method invocation iteself (which it > > > is also "Wicket") will be pushed into the stack. > > > So the stack now contains: > > > Google, Wicket, Wicket > > > Am I right? > > > sounds right to me. --~--~-~--~~~---~--~~ 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: detecting running as script
Hi folks, I'm almost there. My small script: -- #! /usr/bin/env clj (defn somefunc [& args] (println "somefunc!" args)) (defn main [& args] (somefunc args)) ; Only run the application automatically if run as a script, ; not if loaded in a REPL with load-file. (when *command-line-args* (main *command-line-args*)) --- When I run from the command line I get: $ ./test.clj parameters here somefunc! (((./test.clj parameters here))) $ Now, it these some elegant way to parse and use the passed command line arguments in my program? Is there any lib like Ruby/Pythons optparse to assist parsing of command line arguments? Best, Grunde On 4 Jan, 14:58, "Mark Volkmann" wrote: > On Sun, Jan 4, 2009 at 3:57 AM, Timothy Pratley > > > > wrote: > > >> I suspect that *command-line-arguments* would have "myapp.clj" as the > >> 0th element in the > >> clj myapp.clj > >> Can't test right now though sorry. > > > I tested this and it does work for me. If it does not work for you is > > most likely in your clj script or bat file. I noticed on the wiki the > > incorrect advice was given: > > java -cp %CLOJURE_JAR%;%CONTRIB_JAR% clojure.lang.Script %1 > > > I've updated the wiki with the correct usage: > > java -cp %CLOJURE_JAR%;%CONTRIB_JAR% clojure.lang.Script %1 -- %* > > > Check your script for the -- between script name and arglist. Note > > that %* includes %1. > > > script-test.clj: > > (if *command-line-args* > > (println "SCRIPT") > > (println "REPL")) > > > C:\java>clj script-test.clj > > SCRIPT > > > C:\java>clj > > Clojure > > user=> (load-file "script-test.clj") > > REPL > > nil > > Thanks! I've got it working this way now. My script defines a "main" > function. At the bottom of the script I do this: > > ; Only run the application automatically if run as a script, > ; not if loaded in a REPL with load-file. > (if *command-line-args* (main)) > > -- > 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 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: Patch: Arbitrary Symbols between ||
On Jan 13, 4:56 pm, "Robert Pfeiffer" wrote: > Hello everybody, > > this patch implements a pipe-delimited syntax for symbols. The Reader > parses |this symbol| and one symbol. Symbols containing clojure syntax > are printed in this form, so they can be printed and read in again. > > example: (.toString (symbol "()")) => "|()|" > > What do you think? > I am interested in symbols with arbitrary names, but I don't think this is the right approach. First, it can't have such a detrimental effect on normal symbols - the toString in the patch is quite inefficient. Second, it would be better not to replicate the logic for macro characters etc that already exists in the reader. That's not to say the reader stuff is ready for reuse as is, but making it so is the right thing. I haven't fully thought out how this ought to work (there's likely a speed/space tradeoff somewhere), and it is pretty low priority. 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: Can't get clojure or clojure.contrib via SVN over https
I did the same thing after the switch. Then I read the directions more carefully: http://code.google.com/p/clojure-contrib/source/checkout. --- # Non-members may check out a read-only working copy anonymously over HTTP. svn checkout http://clojure-contrib.googlecode.com/svn/trunk/ clojure- contrib-read-only --- (no /clojure-contrib on the end of the URL now) On Jan 14, 6:57 am, "Paul Drummond" wrote: > Hi all, > > I realised today that my "work" machine still has the old Sourceforge > version of clojure-contrib but when I try to get the latest version from > google-code it falls over - most likely due to a proxy: > > >svn checkouthttp://clojure-contrib.googlecode.com/svn/trunk/clojure-contrib > > svn: REPORT request failed on '/svn/!svn/vcc/default' > svn: REPORT of '/svn/!svn/vcc/default': 400 Bad Request > (http://clojure-contrib.googlecode.com) > > I've had this before and worked around it by using https to get the > sourceforge version but for google-code you have to be a member of the > project to use https I think. > > Anyone else have the same problem? Is there a way around this? > > 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: Can't get clojure or clojure.contrib via SVN over https
2009/1/14 Mark Feeney > > (no /clojure-contrib on the end of the URL now) > Thanks for your reply Mark but I don't get what you mean. Can you elaborate? You say "no /clojure-contrib on the end of the URL" but it's not on there anyway. The url is exactly as it is on the google-code checkout page: http://clojure-contrib.googlecode.com/svn/trunk/ I am pretty sure it's a proxy thing and that I need to use https but I might be wrong. Thanks, 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: Can't get clojure or clojure.contrib via SVN over https
I was just referring to the svn command you posted in your original message: > svn checkout http://clojure-contrib.googlecode.com/svn/trunk/clojure-contrib What it should be is: svn checkout http://clojure-contrib.googlecode.com/svn/trunk/ clojure- contrib (note the space at the end before clojure-contrib) I just tried the above command and it's good for me, so if it doesn't work for you, then this is more than a typo thing (maybe network as you suggest) and my "expertise" is probably at its end :) On Jan 14, 8:15 am, "Paul Drummond" wrote: > 2009/1/14 Mark Feeney > > > > > (no /clojure-contrib on the end of the URL now) > > Thanks for your reply Mark but I don't get what you mean. Can you elaborate? > > You say "no /clojure-contrib on the end of the URL" but it's not on there > anyway. The url is exactly as it is on the google-code checkout page: > > http://clojure-contrib.googlecode.com/svn/trunk/ > > I am pretty sure it's a proxy thing and that I need to use https but I might > be wrong. > > Thanks, > 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: Patch: Arbitrary Symbols between ||
On Wed, Jan 14, 2009 at 1:59 PM, Rich Hickey wrote: > > I am interested in symbols with arbitrary names, > Why is this interesting? -- Venlig hilsen / Kind regards, Christian Vest Hansen. --~--~-~--~~~---~--~~ 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: IntelliJ Plugin
Hi Aria, Actually, I am just in the process of writing up the install instructions. Watch this space! aria42 wrote: > Did you ever get around to posting the notes on getting the IntelliJ > plugin to work? I sorely would love IDE support for Clojure in either > Eclipse or IntelliJ. Is the IntelliJ one in a usable state, or is it > not ready for some alpha-level testers? > > Cheers, Aria > > On Dec 29 2008, 10:36 am, "Justin Johnson" > wrote: > >> On Sat, Dec 27, 2008 at 8:55 AM, Peter Wolf wrote: >> >>> Hi Justin, >>> This is the right place. Thanks for trying the plugin. >>> >>> It would absolutely be helpful to document use of the plugin. However, I >>> am sure you can tell that it is nowhere near ready. >>> >> Yes, I noticed there wasn't much there yet. I still think it would be great >> if you documented how you build and test. In particular I found it to be a >> pain to setup my own update site and updatePlugins.xml file just to install >> my own plugin. It wasn't difficult, but certainly not efficient. My hope >> was that sharing setup info like this would help me discover more efficient >> ways of working. >> >> >> >> >>> I would like to get a basic set of features going and then recruit you and >>> Randall to test and document it. Once it is banged on, we can post the >>> plugin to IntelliJ so it can be installed with a mouse click. >>> >>> I am currently working on the Parser, which will give us parens matching >>> and folding, and Compile/Run/Debug/Profile. >>> >>> The one big piece I am missing is the REPL. Any help would be appreciated. >>> >>> Peter >>> >>> On Wed, Dec 24, 2008 at 4:25 PM, Justin Johnson >>> wrote: >>> Hi, Is this the appropriate mailing list to talk about the Clojure IntelliJ plugin? The Google Code site didn't list any other mailing list. http://code.google.com/p/clojure-intellij-plugin/ I went through the process of building and installing the plugin on Windows XP with IntelliJ IDEA 8.0.1 and thought it might be helpful if I document what I did on the wiki. I also have a small suggestion that the build.xml file use environment variables instead of hard coded paths to java.home and idea.home. Thanks, Justin > > > > --~--~-~--~~~---~--~~ 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: Can't get clojure or clojure.contrib via SVN over https
On Jan 14, 8:44 am, Mark Feeney wrote: > I was just referring to the svn command you posted in your original > message: > > > svn checkouthttp://clojure-contrib.googlecode.com/svn/trunk/clojure-contrib > > What it should be is: > > svn checkouthttp://clojure-contrib.googlecode.com/svn/trunk/clojure- > contrib > > (note the space at the end before clojure-contrib) > > I just tried the above command and it's good for me, so if it doesn't > work for you, then this is more than a typo thing (maybe network as > you suggest) and my "expertise" is probably at its end :) > > On Jan 14, 8:15 am, "Paul Drummond" wrote: > > > 2009/1/14 Mark Feeney > > > > (no /clojure-contrib on the end of the URL now) > > > Thanks for your reply Mark but I don't get what you mean. Can you elaborate? > > > You say "no /clojure-contrib on the end of the URL" but it's not on there > > anyway. The url is exactly as it is on the google-code checkout page: > > >http://clojure-contrib.googlecode.com/svn/trunk/ > > > I am pretty sure it's a proxy thing and that I need to use https but I might > > be wrong. > I think the salient difference is http, not https, for non-members. 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: Can't get clojure or clojure.contrib via SVN over https
2009/1/14 Rich Hickey > I think the salient difference is http, not https, for non-members. Hi Rich, The point is that I could use https on Sourceforge to get around the proxy issue. I've had the same problem before when using SVN for Clojure (sourceforge) and assembla (a personal repos). When I tried checking out using http I got the error (see first post) so I used https and it worked on sourceforge and assembla without me needing to specify a username/password (as far as I remember). But the same trick doesn't work on google-code. Oh well :( I guess I will have to find some other way of keeping clojure and clojure-contrib up-to-date on my work box :( 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: Can't get clojure or clojure.contrib via SVN over https
2009/1/14 Mark Feeney > > I was just referring to the svn command you posted in your original > message: > > > svn checkout > http://clojure-contrib.googlecode.com/svn/trunk/clojure-contrib > > What it should be is: > > svn checkout http://clojure-contrib.googlecode.com/svn/trunk/ clojure- > contrib > > (note the space at the end before clojure-contrib) FYI my original post did have the space in ;) Cheers, 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: when performance matters
For those interested in numeric performance, Clojure lets you use arrays of primitives, has primitive math support, primitive local support, and has higher-level macros for dealing with them (amap, areduce) which can also serve as models for your own. You can also use :inline to wrap arithmetic primitives implemented as Java static methods, as Clojure itself does for +/* etc, which HotSpot inlines quite nicely. If people are not exploring and using these things, and are concerned about performance not being the same as Java's, I can't help them. That's how you get numeric performance the same as Java's in Clojure. Cliff Click has already spoken about the performance of Java vs/ C++, and I concur. Where Clojure currently has an unavoidable overhead vs Java is Clojure- >Clojure calls involving numbers. Since the fn call/return signature is Object based, those numbers need to be boxed, at least until we get something like tagged numbers on the JVM. That means naive fib microbenchmarks suffer (boxing in a tight loop), but most real performance-critical numeric code is not like naive fib. Most of it is inner loops on vectors/matrices, or local iterative calculations involving primitives, which, if implemented using the above constructs, is as fast as Java. So, getting the fastest numerics means working with primitive types, and lower-level constructs. It's not something you'll want to do anywhere other than where it really matters. When you do, you'll find Clojure's macros let you write higher-level code than the for loops of Java. amap and areduce just hint at the possibilities of a high- performance, macro-based math library, and I expect similar macros to come from people actually doing number crunching with Clojure. Rich On Jan 13, 2:53 pm, Peter Wolf wrote: > Why is Clojure slower than Java? And, can it be fixed? Is it just the > dynamic lookups? > > I also want to use Clojure in my work to implement the inner loops, but > I was disappointed by a previous discussion looking at the speed of > Clojure. As I recall Clojure seems to be about 1/4 the speed of Java at > the moment. > > Until we regularly have 10's of processors, it seems hard to justify > that kind of hit for code that has to be fast. So, I use Clojure for > scripting and high level code currently. > > Peter > > P.S. I also find that C++ and Java are now approximately the same > speed. And if exceptions are enabled, Java blows C++ out of the water. > > cliffc wrote: > > Some comments: > > > 1- If you think that HotSpot/Java is slower than C++ by any > > interesting amount, I'd love to see the test case. Being the > > architect of HotSpot "-server" I've a keen interest in where > > performance isn't on par with C. Except for a handful of specialized > > uses (e.g. high-level interpreters using gnu label vars), I've only > > ever seen equivalent code between C/C++ & Java (not so w/asm+C where > > the asm calls out specialized ops or makes specialized optimizations). > > > 2- As already mentioned, there's no auto-parallelization tools Out > > There that are ready for prime-time. (there ARE tools out there that > > can *help* parallelize an algorithm but you need annotations, etc to > > make them work) > > > 3- Making your algorithm parallel is worth an N-times speedup, where N > > is limited by the algorithm & available CPUs. Since you can get huge > > CPU counts these days, if you can parallelize your algorithm you'll > > surely win over almost any other hacking. If you take a 50% slowdown > > in the hacking but get to run well on a 4-way box, then your 2x > > ahead. I'd love to say that the JVM "will just do it", but hand- > > hacking for parallelism is the current state-of-the-art. > > > 4- Java/Clojure makes some of this much easier than in C/C++. Having > > a memory model is a HUGE help in writing parallel code, as is the Java > > concurrency libs, or the above-mentioned Colt libraries. > > > 5- The debian shootout results generally badly mis-represent Java. > > Most of them have runtimes that are too small (<10sec) to show off the > > JIT, and generally don't use any of the features which commonly appear > > in large Java programs (heavy use of virtuals, deep class hierarchies, > > etc) for which the JIT does a lot of optimization. I give a public > > talk on the dangers of microbenchmarks and all the harnesses I've > > looked at in the shootout fail basic sanity checks. Example: the > > fannkuch benchmark runs 5 secs in Java, somewhat faster in C++. Why > > does anybody care about a program which runs 5sec? (there's other > > worse problems: e.g. the C++ code gets explicit constant array sizes > > hand-optimized via templates; the equivalent Java optimization isn't > > done but is trivial (declare 'n' as a *final* static var) and doing so > > greatly speeds up Java, etc). > > > 6- If you need a zillion integer (not FP) parallel Java cycles, look > > at an Azul box. Azul's got more integer cycles in a flat shared- > >
How To Load Source File
Hi all, I'm new to Clojure and new to Lisp but not new to software development. And I feel very dumb for having to ask what seems like a very noob question but I can't seem to figure this out. If I want to load a source file into REPL it seems that I should be able to do this: (load-file "filename") but when I try this with a source file in a folder on my Windows XP box, (load-file "/cljhack/test1.clj") I get "java.lang.Exception: Invalid token: /cljhack/test1.clj" (less the quotes of course). I deliberately made test1.clj as simple as possible because I thought that the load-file might load and parse at the same time. It consists of the following line: ;Simplest possible clojure file So, I'm really stumped. Is this some problem with Windows XP? Using the directory separator the other way doesn't work, of course. Of course my ultimate aim is to be able to load and run a .clj file so if there's another approach I should be using, please feel free to tell me that. -- Onorio Catenacci III --~--~-~--~~~---~--~~ 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 Load Source File
This works for me in every configuration I could think of (at worst I get java.io.FileNotFoundException). Are you running a plain cmd prompt? (not MSys or cygwin) How did you launch clj? Rgds. Tom 2009/1/14 Onorio Catenacci > > Hi all, > > I'm new to Clojure and new to Lisp but not new to software > development. And I feel very dumb for having to ask what seems like a > very noob question but I can't seem to figure this out. > > If I want to load a source file into REPL it seems that I should be > able to do this: > > (load-file "filename") > > but when I try this with a source file in a folder on my Windows XP > box, > > (load-file "/cljhack/test1.clj") > > I get > > "java.lang.Exception: Invalid token: /cljhack/test1.clj" (less the > quotes of course). > > > --~--~-~--~~~---~--~~ 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: when performance matters
Rich, I must apologize-- I worded my question *far* too harshly. I knew it as I pushed the send button. I am a huge fan of Clojure, and plan to use it as often as possible. My question was really looking for hints, so that I can use it in more places. You gave me a great one, thanks! Is there any way to avoid the overhead of dynamic lookups in Clojure? Can I tell the compiler somehow that the types of each argument is constant, and/or that a symbol will always resolve to the same place. I am assuming, and perhaps I am wrong, that dynamic behavior is a significant overhead. P Rich Hickey wrote: > For those interested in numeric performance, Clojure lets you use > arrays of primitives, has primitive math support, primitive local > support, and has higher-level macros for dealing with them (amap, > areduce) which can also serve as models for your own. You can also > use :inline to wrap arithmetic primitives implemented as Java static > methods, as Clojure itself does for +/* etc, which HotSpot inlines > quite nicely. > > If people are not exploring and using these things, and are concerned > about performance not being the same as Java's, I can't help them. > That's how you get numeric performance the same as Java's in Clojure. > Cliff Click has already spoken about the performance of Java vs/ C++, > and I concur. > > Where Clojure currently has an unavoidable overhead vs Java is Clojure- > >> Clojure calls involving numbers. Since the fn call/return signature >> > is Object based, those numbers need to be boxed, at least until we get > something like tagged numbers on the JVM. That means naive fib > microbenchmarks suffer (boxing in a tight loop), but most real > performance-critical numeric code is not like naive fib. Most of it is > inner loops on vectors/matrices, or local iterative calculations > involving primitives, which, if implemented using the above > constructs, is as fast as Java. > > So, getting the fastest numerics means working with primitive types, > and lower-level constructs. It's not something you'll want to do > anywhere other than where it really matters. When you do, you'll find > Clojure's macros let you write higher-level code than the for loops of > Java. amap and areduce just hint at the possibilities of a high- > performance, macro-based math library, and I expect similar macros to > come from people actually doing number crunching with Clojure. > > Rich > > On Jan 13, 2:53 pm, Peter Wolf wrote: > >> Why is Clojure slower than Java? And, can it be fixed? Is it just the >> dynamic lookups? >> >> I also want to use Clojure in my work to implement the inner loops, but >> I was disappointed by a previous discussion looking at the speed of >> Clojure. As I recall Clojure seems to be about 1/4 the speed of Java at >> the moment. >> >> Until we regularly have 10's of processors, it seems hard to justify >> that kind of hit for code that has to be fast. So, I use Clojure for >> scripting and high level code currently. >> >> Peter >> >> P.S. I also find that C++ and Java are now approximately the same >> speed. And if exceptions are enabled, Java blows C++ out of the water. >> >> cliffc wrote: >> >>> Some comments: >>> >>> 1- If you think that HotSpot/Java is slower than C++ by any >>> interesting amount, I'd love to see the test case. Being the >>> architect of HotSpot "-server" I've a keen interest in where >>> performance isn't on par with C. Except for a handful of specialized >>> uses (e.g. high-level interpreters using gnu label vars), I've only >>> ever seen equivalent code between C/C++ & Java (not so w/asm+C where >>> the asm calls out specialized ops or makes specialized optimizations). >>> >>> 2- As already mentioned, there's no auto-parallelization tools Out >>> There that are ready for prime-time. (there ARE tools out there that >>> can *help* parallelize an algorithm but you need annotations, etc to >>> make them work) >>> >>> 3- Making your algorithm parallel is worth an N-times speedup, where N >>> is limited by the algorithm & available CPUs. Since you can get huge >>> CPU counts these days, if you can parallelize your algorithm you'll >>> surely win over almost any other hacking. If you take a 50% slowdown >>> in the hacking but get to run well on a 4-way box, then your 2x >>> ahead. I'd love to say that the JVM "will just do it", but hand- >>> hacking for parallelism is the current state-of-the-art. >>> >>> 4- Java/Clojure makes some of this much easier than in C/C++. Having >>> a memory model is a HUGE help in writing parallel code, as is the Java >>> concurrency libs, or the above-mentioned Colt libraries. >>> >>> 5- The debian shootout results generally badly mis-represent Java. >>> Most of them have runtimes that are too small (<10sec) to show off the >>> JIT, and generally don't use any of the features which commonly appear >>> in large Java programs (heavy use of virtuals, deep class hi
Re: IntelliJ Plugin
I'm an IntelliJ 8 user and I can test the plugin on my own machine if this helps the plugin's development. On Jan 14, 3:52 pm, Peter Wolf wrote: > Hi Aria, > > Actually, I am just in the process of writing up the install > instructions. Watch this space! > > aria42 wrote: > > Did you ever get around to posting the notes on getting the IntelliJ > > plugin to work? I sorely would love IDE support for Clojure in either > > Eclipse or IntelliJ. Is the IntelliJ one in a usable state, or is it > > not ready for some alpha-level testers? > > > Cheers, Aria > > > On Dec 29 2008, 10:36 am, "Justin Johnson" > > wrote: > > >> On Sat, Dec 27, 2008 at 8:55 AM, Peter Wolf wrote: > > >>> Hi Justin, > >>> This is the right place. Thanks for trying the plugin. > > >>> It would absolutely be helpful to document use of the plugin. However, I > >>> am sure you can tell that it is nowhere near ready. > > >> Yes, I noticed there wasn't much there yet. I still think it would be > >> great > >> if you documented how you build and test. In particular I found it to be a > >> pain to setup my own update site and updatePlugins.xml file just to install > >> my own plugin. It wasn't difficult, but certainly not efficient. My hope > >> was that sharing setup info like this would help me discover more efficient > >> ways of working. > > >>> I would like to get a basic set of features going and then recruit you and > >>> Randall to test and document it. Once it is banged on, we can post the > >>> plugin to IntelliJ so it can be installed with a mouse click. > > >>> I am currently working on the Parser, which will give us parens matching > >>> and folding, and Compile/Run/Debug/Profile. > > >>> The one big piece I am missing is the REPL. Any help would be > >>> appreciated. > > >>> Peter > > >>> On Wed, Dec 24, 2008 at 4:25 PM, Justin Johnson > >>> wrote: > > Hi, > > Is this the appropriate mailing list to talk about the Clojure IntelliJ > plugin? The Google Code site didn't list any other mailing list. > > http://code.google.com/p/clojure-intellij-plugin/ > > I went through the process of building and installing the plugin on > Windows XP with IntelliJ IDEA 8.0.1 and thought it might be helpful if I > document what I did on the wiki. I also have a small suggestion that the > build.xml file use environment variables instead of hard coded paths to > java.home and idea.home. > > Thanks, > Justin --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Trying to define next-agent function
Hello, I'm trying to create a list of agents and a function called next-agent that always gives me the next agent and restarts at the beginning when the list is exhausted. For my purposes the agent is serving as a thread that will do some work. I don't much care about its value at this time. I'm new to Clojure and am pretty sure there is an elegant way to do what I want, but my little OO head is spinning. Any help you can provide is appreciated. Thanks, Justin => (def counter (ref 0)) #'user/counter => (defn next-counter [] (dosync (alter counter inc))) #'user/next-counter => (def a1 (agent 0)) #'user/a1 => (def a2 (agent 0)) #'user/a2 => (def a3 (agent 0)) #'user/a3 => (defn agents [] (cycle [a1 a2 a3])) #'user/agents => (defn next-agent [] (nth agents (next-counter))) #'user/next-agent => (next-agent) java.lang.UnsupportedOperationException: nth not supported on this type: user$agents__1177 (repl-1:92) --~--~-~--~~~---~--~~ 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 Load Source File
On Jan 14, 9:56 am, "Tom Ayerst" wrote: > This works for me in every configuration I could think of (at worst I get > java.io.FileNotFoundException). > Are you running a plain cmd prompt? (not MSys or cygwin) > How did you launch clj? > Hi Tom, Thanks for the response. I'm running Repl from a shortcut which does the following: %windir%\system32\java.exe -cp "C:\Documents and Settings \PFHOVC0\Desktop\clojure\clojure.jar" clojure.lang.Repl And I think I've found the problem thanks to your suggestion. The shortcut had the start directory as %windir%\system32. I'm not sure why the system defaulted to that directory. When I changed the start directory to c:\documents and settings\pfhovc0\desktop\clojure the problem went away. Thanks for your help with this. I suspected that I was missing something simple. :-) -- Onorio Catenacci III --~--~-~--~~~---~--~~ 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: Trying to define next-agent function
I found my problem. I wasn't calling agents. I was doing this. => (defn next-agent [] (nth agents (next-counter))) and should have been doing this. => (defn next-agent [] (nth (agents) (next-counter))) Still, I would like feedback. Is there a cleaner way to do this? Thanks. Justin On Wed, Jan 14, 2009 at 9:33 AM, Justin Johnson wrote: > Hello, > > I'm trying to create a list of agents and a function called next-agent that > always gives me the next agent and restarts at the beginning when the list > is exhausted. For my purposes the agent is serving as a thread that will do > some work. I don't much care about its value at this time. > > I'm new to Clojure and am pretty sure there is an elegant way to do what I > want, but my little OO head is spinning. Any help you can provide is > appreciated. > > Thanks, > Justin > > > => (def counter (ref 0)) > #'user/counter > => (defn next-counter [] (dosync (alter counter inc))) > #'user/next-counter > => (def a1 (agent 0)) > #'user/a1 > => (def a2 (agent 0)) > #'user/a2 > => (def a3 (agent 0)) > #'user/a3 > => (defn agents [] (cycle [a1 a2 a3])) > #'user/agents > => (defn next-agent [] (nth agents (next-counter))) > #'user/next-agent > => (next-agent) > java.lang.UnsupportedOperationException: nth not supported on this type: > user$agents__1177 (repl-1:92) > > > --~--~-~--~~~---~--~~ 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: Can't get clojure or clojure.contrib via SVN over https
On Wed, Jan 14, 2009 at 8:16 AM, Paul Drummond wrote: > 2009/1/14 Rich Hickey > >> I think the salient difference is http, not https, for non-members. > > > Hi Rich, > > The point is that I could use https on Sourceforge to get around the proxy > issue. > > I've had the same problem before when using SVN for Clojure (sourceforge) > and assembla (a personal repos). When I tried checking out using http I got > the error (see first post) so I used https and it worked on sourceforge and > assembla without me needing to specify a username/password (as far as I > remember). But the same trick doesn't work on google-code. Oh well :( > > I guess I will have to find some other way of keeping clojure and > clojure-contrib up-to-date on my work box :( > You could try moving to something like git and checking out the source code from one of the unofficial mirrors, like http://*github*.com/kevinoneill/* clojure* -- Cosmin Stejerean http://offbytwo.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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 Load Source File
For more than just experimentation with one file, you might also want to look into lib packaging so that you can 'require' or 'use' rather than have to go down to the level of 'load' or 'load-file'. Quick summary, if your file has namespace "foo.bar" then package it in file / foo/bar.clj (relative to your classpath) and you can then just (require 'foo.bar) or (use 'foo.bar) See this thread for more discussion (I had this question not too long ago): http://groups.google.com/group/clojure/browse_thread/thread/f29913ee38e7930a/910434de5dc460cf?lnk=gst&q=bootstrap#910434de5dc460cf -Greg > 2009/1/14 Onorio Catenacci > > > > > Hi all, > > > I'm new to Clojure and new to Lisp but not new to software > > development. And I feel very dumb for having to ask what seems like a > > very noob question but I can't seem to figure this out. > > > If I want to load a source file into REPL it seems that I should be > > able to do this: > > > (load-file "filename") > > > but when I try this with a source file in a folder on my Windows XP > > box, > > > (load-file "/cljhack/test1.clj") > > > I get > > > "java.lang.Exception: Invalid token: /cljhack/test1.clj" (less the > > quotes of course). --~--~-~--~~~---~--~~ 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: Patch: Arbitrary Symbols between ||
On 14 Jan., 13:59, Rich Hickey wrote: > [...] the toString in the patch is quite > inefficient. Because symbols are immutable, they could cache the printable representation in an extra field, but this would double the space occupied by them. > Second, it would be better not to replicate the logic for > macro characters etc that already exists in the reader. That's not to > say the reader stuff is ready for reuse as is, but making it so is the > right thing. Issue 13 is related to this. Syntactic validation of symbols in clojure.core/symbol depends on the reader syntax of clojure also. Would this patch eliminate the need to validate symbols? Are there other constraints than that the printed representation read again should result in the same symbol? Robert Pfeiffer --~--~-~--~~~---~--~~ 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: typo near http://clojure.org/API#toc248
On Mon, Jan 12, 2009 at 10:26 PM, .Bill Smith wrote: > > The gen-class documentation at http://clojure.org/API#toc248 has a > minor typo: the description of the :state keyword begins at the end of > the :factory paragraph instead of beginning a new paragraph. Not a > big deal but it makes the :state description harder to find. It's probably worth putting this sort of report directly on the issues page. It feels to me like this group's traffic just went up another notch, and this kind of report is even more likely to get lost. Thanks, --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 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: Can't get clojure or clojure.contrib via SVN over https
2009/1/14 Cosmin Stejerean > You could try moving to something like git and checking out the source code > from one of the unofficial mirrors, like http://*github*.com/kevinoneill/* > clojure* > Works perfectly - thanks! I considered trying git but didn't have a clue where to look for mirrors - thanks for the link! Cheers, 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: How To Load Source File
Glad to help. If you haven't found it yet the wiki is very helpful, especialyy: http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started If you want to spend some money Stuart Halloway's book is excellent http://www.pragprog.com/titles/shcloj/programming-clojure Cheers Tom 2009/1/14 Onorio Catenacci ... > > %windir%\system32\java.exe -cp "C:\Documents and Settings > \PFHOVC0\Desktop\clojure\clojure.jar" clojure.lang.Repl > > And I think I've found the problem thanks to your suggestion. The > shortcut had the start directory as %windir%\system32. I'm not sure > why the system defaulted to that directory. When I changed the start > directory to c:\documents and settings\pfhovc0\desktop\clojure the > problem went away. > > Thanks for your help with this. I suspected that I was missing > something simple. :-) > > -- > Onorio Catenacci III > > --~--~-~--~~~---~--~~ 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: Trying to define next-agent function
Also a newbie wrestling with agents.. but perhaps you could do something with lazy-cons or cycle? An endless cycle of your agents: (def running true) (while running (doseq [a (cycle agents)] (send-off a somefunction)) On Jan 14, 4:48 pm, Justin Johnson wrote: > I found my problem. I wasn't calling agents. I was doing this. > > => (defn next-agent [] (nth agents (next-counter))) > > and should have been doing this. > > => (defn next-agent [] (nth (agents) (next-counter))) > > Still, I would like feedback. Is there a cleaner way to do this? > > Thanks. > Justin > > On Wed, Jan 14, 2009 at 9:33 AM, Justin Johnson > wrote: > > > > > Hello, > > > I'm trying to create a list of agents and a function called next-agent that > > always gives me the next agent and restarts at the beginning when the list > > is exhausted. For my purposes the agent is serving as a thread that will do > > some work. I don't much care about its value at this time. > > > I'm new to Clojure and am pretty sure there is an elegant way to do what I > > want, but my little OO head is spinning. Any help you can provide is > > appreciated. > > > Thanks, > > Justin > > > => (def counter (ref 0)) > > #'user/counter > > => (defn next-counter [] (dosync (alter counter inc))) > > #'user/next-counter > > => (def a1 (agent 0)) > > #'user/a1 > > => (def a2 (agent 0)) > > #'user/a2 > > => (def a3 (agent 0)) > > #'user/a3 > > => (defn agents [] (cycle [a1 a2 a3])) > > #'user/agents > > => (defn next-agent [] (nth agents (next-counter))) > > #'user/next-agent > > => (next-agent) > > java.lang.UnsupportedOperationException: nth not supported on this type: > > user$agents__1177 (repl-1:92) --~--~-~--~~~---~--~~ 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: Designing a Performance Vector Math library in Clojure.
On Tue, Jan 13, 2009 at 5:54 PM, Timothy Pratley wrote: > > I'm not sure how to "cpu frequency set > to not change" or how significant that is on my results. I was afraid that was too vague a reference, sorry. My laptop usually slows down the CPU when its idle or nearly so. Specifically, the linux kernel is using an "on demand" CPU frequency scaler. This is nice for nearly every context except trying to run benchmarks, in which case some runs of a test may be partially handled while the CPU is in a slow and cool mode (800 MHz), while the rest is in the fast and hot mode (2500 MHz), resulting in almost unusably divergent timing results. So when I remember to do so, I switch the kernel to using the "performance" CPU frequency scaler before running my tests, and back to "on demand" afterwards. --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 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: when performance matters
On Jan 14, 12:20 pm, "Mark H." wrote: > I humbly propose that folks shouldn't complain about Clojure being > slow for their apps until they have at least one of the following: > > 1. A targeted benchmark for an important bottleneck in their > application, implemented in both Clojure and the current > implementation language, with performance results; or > > 2. A performance model based on an understanding of the Clojure and > HotSpot compilation processes, that highlights which particular > features of the latter would make their application slower than in its > current implementation language. > > This is not out of elitism but out of an earnest desire to be helpful; > it's hard to give good advice on language choice and code optimization > when we don't know what the bottlenecks are. Also it's really hard > for anyone to optimize their own code unless they themselves know > where the bottlenecks are. The latter means that #1 above is > surprisingly easy; it often can be done with a simple function trace > of a typical run. I'm not complaining, but I find the topic interesting as I just tried translating a fluid dynamics algorithm to clojure. (http://www.dgp.toronto.edu/people/stam/reality/Research/pdf/ GDC03.pdf) I got no experience with this kind of stuff, it's just something I tried out for fun. So the performance I get may be as expected. Or there may be obvious ways of speeding it up that I don't see. Anyway, here is a core part of the algorithm. It's a diffusion step, this gets called 3 times and in total this takes up more than one second of cpu time on my machine which makes framerates very slow. If anyone got any improvements I'd be happy to hear about it: (def grid-size 300) (defn make-grid [] (make-array Float/TYPE (* (+ grid-size 2) (+ grid-size 2 (defn diffuse [grid diff-ratio dt] (let [a (float (* dt diff-ratio grid-size grid-size)) a4-1 (float (+ 1 (* 4 a))) grid #^floats (deref grid) diffused-grid #^floats (make-grid) line-length (int (+ grid-size 2))] (dotimes [n 20] (dotimes [y grid-size] (let [line-offset (* (inc y) line-length)] (loop [x (int 1) c (+ x line-offset)] (aset diffused-grid c (float (/ (+ (aget grid c) (* a (+ (+ (aget diffused-grid (dec c)) (aget diffused-grid (inc c))) (+ (aget diffused-grid (- c line-length)) (aget diffused-grid (+ c line-length)) a4-1))) (when (< x grid-size) (recur (inc x) (inc c))) diffused-grid)) (def foo (ref (make-grid))) (time (diffuse foo 0.00025 0.002)) -- -asbjxrn --~--~-~--~~~---~--~~ 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: Observing namespace changes
On Wed, Jan 14, 2009 at 3:07 AM, lpetit wrote: > > Hello, > > Is it possible for my code to "subscribe" to events of type > "namespace change" which would inform of deltas on top level > namespaces : > - added symbol > - removed symbol > - changed root var binding of a symbol > > Indeed, I'm currently implementing a little "namespace browser" View > for clojuredev (eclipse clojure development tool - aka CLJDT), and I'm > concerned with how to efficiently and accurately keep my namespace > browser in sync with the clojure environment it is observing. This was done already for very similar purpose, by Mike Messinides. It's a bit of a hack, and I imagine the code is a bit out of date now, but I'm sure it can be brought up to snuff: http://clojure.googlegroups.com/web/repl+(2).clj A "clean" solution would be to have watchers on namespace objects, as there are now on agents, refs, etc, but I don't think that's planned. --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 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 -~--~~~~--~~--~--~---
newbie question!!
Hi, Earlier Stuart Sierra replied as follows: Hi Patrick, Here's one way to do it: (defn new-person [name] (ref {:name name, :friends #{}})) (defn are-friends [a b] (dosync (commute a assoc :friends (conj (:friends @a) b)) (commute b assoc :friends (conj (:friends @b) a (def bill (new-person "Bill")) (def bob (new-person "Bob")) ... so I tried the followings: user=> (defn person [name] (ref {:name name :friends #{}})) #'user/person user=> (def bill (person "Bill")) #'user/bill user=> (def bob (person "Bob")) #'user/bob user=> (dosync (commute bill assoc :friends (conj (:friends @bill) bob)) ) {:friends #{#}, :name "Bill"} user=> (:friends @bill) #{#} Adding another friend for bill (def beck (person "Becky")) and (dosync (commute bill assoc :friends (conj (:friends @bill) beck)) ) Now I want to print list of names of friends of Bill. (count (:friends @bill)) returns 2, which is working. Tried (:name (first (:friends @bill)) but returned nil. I expected a name gets printed. thanks in advance. -sun --~--~-~--~~~---~--~~ 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: when performance matters
Asbjxrn, One thing that leaps out to me performance-wise is the 3 nested loops (dotimes, dotimes, loop/recur). Whatever's inside the inner loop is getting run a lot of times! General advice about reducing loop depth and computation required inside the innermost loop aside... have you looked at clojure.parallel? Seems like it might be a good fit since your algorithm is doing a lot of array processing... -Greg On Jan 14, 11:27 am, Asbjørn Bjørnstad wrote: > I'm not complaining, but I find the topic interesting as I just tried > translating a fluid dynamics algorithm to clojure. > (http://www.dgp.toronto.edu/people/stam/reality/Research/pdf/ > GDC03.pdf) > I got no experience with this kind of stuff, it's just something I > tried out for fun. So the performance I get may be as expected. Or > there may be obvious ways of speeding it up that I don't see. > > Anyway, here is a core part of the algorithm. It's a diffusion > step, this gets called 3 times and in total this takes up more than > one second of cpu time on my machine which makes framerates very > slow. If anyone got any improvements I'd be happy to hear about it: > > (def grid-size 300) > > (defn make-grid [] > (make-array Float/TYPE (* (+ grid-size 2) > (+ grid-size 2 > > (defn diffuse [grid diff-ratio dt] > (let [a (float (* dt diff-ratio grid-size grid-size)) > a4-1 (float (+ 1 (* 4 a))) > grid #^floats (deref grid) > diffused-grid #^floats (make-grid) > line-length (int (+ grid-size 2))] > (dotimes [n 20] > (dotimes [y grid-size] > (let [line-offset (* (inc y) line-length)] > (loop [x (int 1) > c (+ x line-offset)] > (aset diffused-grid c > (float (/ (+ (aget grid c) > (* a > (+ (+ (aget diffused-grid (dec > c)) > (aget diffused-grid (inc > c))) > (+ (aget diffused-grid (- c > line-length)) > (aget diffused-grid (+ c > line-length)) > a4-1))) > (when (< x grid-size) > (recur (inc x) > (inc c))) > diffused-grid)) > > (def foo (ref (make-grid))) > > (time (diffuse foo 0.00025 0.002)) > > -- > -asbjxrn --~--~-~--~~~---~--~~ 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: Observing namespace changes
There's no event mechanism to monitor namespace changes. I accomplish this by taking a snapshot before and after any possible namespace- changing execution, using ns-map. Not as efficient as an event callback, but I haven't had any performance issues (map lookups are plenty fast for me). You can register a watcher for a Var to get notification of a root binding change using add-watcher - note that the clojure.org doc for add-watcher has not been updated to match the Var watcher revision. --~--~-~--~~~---~--~~ 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: newbie question!!
(:name @(first (:friends @bill))) You need to dereference before trying to access name. 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 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: Learning Clojure WikiBook
Here's an update on syntax-quote in the WikiBook (Reader Macro section): The most complicated reader macro is syntax-quote, denoted by ` (back- tick). When used on a symbol, syntax-quote is like quote but the symbol is resolved to its fully-qualified name: `meow; (quote cat/meow) ...assuming we are in the namespace cat When used on a list, vector, or map form, syntax-quote quotes the whole form except, a) all symbols are resolved to their fully- qualified names and, b) components preceded by ~ are unquoted: (defn rabbit [] 3) `(moose ~(rabbit)) ; (quote (cat/moose 3)) ...assume namespace cat (def zebra [1 2 3]) `(moose ~zebra); (quote (cat/moose [1 2 3])) Components preceded by ~@ are unquote-spliced: `(moose ~...@zebra) ; (quote (cat/moose 1 2 3)) If a symbol is non-namespace-qualified and ends with '#', it is resolved to a generated symbol with the same name to which '_' and a unique id have been appended. e.g. x# will resolve to x_123. All references to that symbol within a syntax-quoted expression resolve to the same generated symbol. For all forms other than Symbols, Lists, Vectors and Maps, `x is the same as 'x. Syntax-quotes can be nested within other syntax-quotes: `(moose ~(squirrel `(whale ~zebra))) For Lists syntax-quote establishes a template of the corresponding data structure. Within the template, unqualified forms behave as if recursively syntax-quoted. `(x1 x2 x3 ... xn) may be interpreted to mean (concat |x1| |x2| |x3| ... |xn|) where the | | are used to indicate a transformation of an xj as follows: * |form| is interpreted as (list `form), which contains a syntax- quoted form that must then be further interpreted. * |~form| is interpreted as (list form). * |~...@form| is interpreted as form. If the syntax-quote syntax is nested, the innermost syntax-quoted form is expanded first. This means that if several ~ occur in a row, the leftmost one belongs to the innermost syntax-quote. Following the rules above, an expression such as ``(~~a) would be expanded as follows: (concat (list `concat) (list (concat (list `list) (list a and then evaluated. Of course the same expression could also be equivalently expanded as (list `list a) which is indeed much easier to read. Clojure employs the first algorithm which is more generally applicable in cases where there is also splicing. The principle is that the result of an expression with syntax-quotes nested to depth k is the same only after k successive evaluations have been performed, regardless of the kind of expansion algorithm (Guy Steele). For Vectors, Maps, and Sets we have the follwing rules: `[x1 x2 x3 ... xn] is equivalent to (apply vector `(x1 x2 x3 ... xn)) `{x1 x2 x3 ... xn} is equivalent to (apply hash-map `(x1 x2 x3 ... xn)) `#{x1 x2 x3 ... xn} is equivalent to (apply hash-set `(x1 x2 x3 ... xn)) At this time, Clojure does not allow you to define your own reader macros, but this may change in the future. --~--~-~--~~~---~--~~ 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: Learning Clojure WikiBook
On Wed, Jan 14, 2009 at 6:07 AM, Rock wrote: > [snip] > > #^{:ack bar} foo ; (clojure/with-meta foo {:ack bar}) This is not correct, and a common misunderstanding. "#^ is not sugar for with-meta. It does not expand into a call to with- meta. They are not equivalent." http://groups.google.com/group/clojure/msg/919455504c57659e > The #() syntax is intended for very short functions being passed as > arguments. It takes parameters named %, %2, %3, %n ... %&. Might be worth mentioning that it cannot be nested. > `meow; (quote cat/meow) ...assuming we are in the namespace cat assming 'meow' is defined in namespace "cat", not that *ns* is currently "cat" > If a symbol is non-namespace-qualified and ends with '#', it is > resolved to a generated symbol with the same name to which '_' and a > unique id have been appended. e.g. x# will resolve to x_123. All > references to that symbol within a syntax-quoted expression resolve to > the same generated symbol. All references to that symbol within THE SAME syntax-quoted expression... > For Lists/Vectors/Maps, syntax-quote establishes a template of the > corresponding data structure. Within the template, unqualified forms > behave as if recursively syntax-quoted. > > `(x1 x2 x3 ... xn) > > may be interpreted to mean > > (clojure.core/concat [x1] [x2] [x3] ... [xn]) > > where the brackets are used to indicate a transformation of an xj as > follows: > >* [form] is interpreted as (clojure.core/list `form), which > contains a syntax-quoted form that must then be further interpreted. > >* [~form] is interpreted as (clojure.core/list form). > >* [...@form] is interpreted as form. I'm not quite sure I follow the above section. Ok, after a bit more pondering, I guess I see what you're saying. That in your own little notation here, if [x1] is actually [~form], by which you mean the original expression is `(~myform), then that's the same as (concat (list myform)) ? I'm not sure that particular mechanism for explanation is simple enough to be worth including. > ``(~~a) Yikes, I've never tried to do that. > At this time, Clojure does not allow you to define your own reader > macros, but this may change in the future. You're more hopeful on this point than I am. :-) Thanks for writing this up. --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 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: detecting running as script
On Wed, Jan 14, 2009 at 5:58 AM, Grunde wrote: > > Now, it these some elegant way to parse and use the passed command > line arguments in my program? Is there any lib like Ruby/Pythons > optparse to assist parsing of command line arguments? There is clojure.contrib.command-line I don't know if it's elegant, and it's certainly not (yet) as powerful as many optparse tools in some other languages, but I've found it to be useful. --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 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 David. -sun On Jan 14, 11:55 am, David Nolen wrote: > (:name @(first (:friends @bill))) > > You need to dereference before trying to access name. > > 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 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: Learning Clojure WikiBook
On 14 Gen, 17:58, Chouser wrote: > On Wed, Jan 14, 2009 at 6:07 AM, Rock wrote: > > [snip] > > > #^{:ack bar} foo ; (clojure/with-meta foo {:ack bar}) > > This is not correct, and a common misunderstanding. > > "#^ is not sugar for with-meta. It does not expand into a call to > with- meta. They are not equivalent." > > http://groups.google.com/group/clojure/msg/919455504c57659e > > > The #() syntax is intended for very short functions being passed as > > arguments. It takes parameters named %, %2, %3, %n ... %&. > > Might be worth mentioning that it cannot be nested. > > > `meow ; (quote cat/meow) ...assuming we are in the namespace cat > > assming 'meow' is defined in namespace "cat", not that *ns* is > currently "cat" > > > If a symbol is non-namespace-qualified and ends with '#', it is > > resolved to a generated symbol with the same name to which '_' and a > > unique id have been appended. e.g. x# will resolve to x_123. All > > references to that symbol within a syntax-quoted expression resolve to > > the same generated symbol. > > All references to that symbol within THE SAME syntax-quoted expression... I didn't write the section above, but I included it for completeness. I'll see what I can do, thanks for the clarifications. I'm still waiting approval for my own modifications :) What follows is my own contribution: > > > > > For Lists/Vectors/Maps, syntax-quote establishes a template of the > > corresponding data structure. Within the template, unqualified forms > > behave as if recursively syntax-quoted. > > > `(x1 x2 x3 ... xn) > > > may be interpreted to mean > > > (clojure.core/concat [x1] [x2] [x3] ... [xn]) > > > where the brackets are used to indicate a transformation of an xj as > > follows: > > > * [form] is interpreted as (clojure.core/list `form), which > > contains a syntax-quoted form that must then be further interpreted. > > > * [~form] is interpreted as (clojure.core/list form). > > > * [...@form] is interpreted as form. > > I'm not quite sure I follow the above section. > > Ok, after a bit more pondering, I guess I see what you're saying. > That in your own little notation here, if [x1] is actually [~form], by > which you mean the original expression is `(~myform), then that's the > same as (concat (list myform)) ? I'm not sure that particular > mechanism for explanation is simple enough to be worth including. > Thanks for pointing that out! Sorry, still feeling the influence of CL. I realize [ ] are for vectors in Clojure. I've already corrected that, replacing the [ ] with | | ... this was adapted from the CL HyperSpec by the way. > > ``(~~a) > > Yikes, I've never tried to do that. > > > At this time, Clojure does not allow you to define your own reader > > macros, but this may change in the future. > > You're more hopeful on this point than I am. :-) > > Thanks for writing this up. You're very welcome. Thank you for your precious tips. > --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 To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Is there any way to dereference %1 %2 etc?
(map #(println %) [1 2 3 4]) prints 1 2 3 and 4 But what if the vector element is a hash with [ {:a 1 :b 11} {:a 2 :b 22} {:a 3 :b 33}]? can we dereference :a using %1, like (:a %1)? If not, any alternative? maybe destructuring or something? thanks -sun --~--~-~--~~~---~--~~ 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 Load Source File
On Jan 14, 10:50 am, Greg Harman wrote: > For more than just experimentation with one file, you might also want > to look into lib packaging so that you can 'require' or 'use' rather > than have to go down to the level of 'load' or 'load-file'. Quick > summary, if your file has namespace "foo.bar" then package it in file / > foo/bar.clj (relative to your classpath) and you can then just > (require 'foo.bar) or (use 'foo.bar) > > See this thread for more discussion (I had this question not too long > ago): > > http://groups.google.com/group/clojure/browse_thread/thread/f29913ee3... > Thanks for the pointer Greg. I'm just getting my big toe into the water, so to speak, so I'm slowly taking this all in. I'm trying to learn Clojure and (sort of) Java at the same time so I'm trying to take it slow. :-) -- Onorio Catenacci III --~--~-~--~~~---~--~~ 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: Delays and their efficiency
On Tue, Jan 13, 2009 at 12:39 PM, samppi wrote: > > Recently, I asked how to make a function evaluate its arguments lazily > (http://groups.google.com/group/clojure/browse_thread/thread/ > cd01ef39c2b62530), and I was given a good solution: use Delay objects > (with the delay and force functions). > > I wanted to do this for the efficiency of a functional parser library > that uses many meta-functions and meta-meta-functions: I thought that > stopping arguments from being evaluated until needed was a good way to > prevent useless creation of objects, especially in huge trees of meta- > meta-functions. But I was very surprised when running my library's > unit tests to see that using Delay objects took much more time to run > the tests than not using Delays. Here's an example in a REPL: > > Clojure > user=> (defn alt [& functions] > (fn [tokens] >(some #(% tokens) functions))) > #'user/alt > user=> (defn sub-function1 [c] (println "1:" c) (fn [c] false)) > #'user/sub-function1 > user=> (defn sub-function2 [c] (println "2:" c) (fn [c] true)) > #'user/sub-function2 > user=> (defn sub-function3 [c] (println "3:" c) (fn [c] false)) > #'user/sub-function3 > user=> (defn a-meta-meta-function [c] > (alt (sub-function1 c) (sub-function2 c) (sub-function3 c))) > #'user/a-meta-meta-function > user=> (time ((a-meta-meta-function "CONTEXT") [:a :b :c])) > 1: CONTEXT > 2: CONTEXT > 3: CONTEXT > "Elapsed time: 1.018 msecs" > true > > ...vs... > > Clojure > user=> (defn alt [& functions] > (fn [tokens] >(some #((force %) tokens) functions))) > #'user/alt > user=> (defn sub-function1 [c] (println "1:" c) (delay (fn [c] > false > #'user/sub-function1 > user=> java.lang.Exception: Unmatched delimiter: ) > user=> (defn sub-function1 [c] (println "1:" c) (delay (fn [c] > false))) > #'user/sub-function1 > user=> (defn sub-function2 [c] (println "2:" c) (delay (fn [c] true))) > #'user/sub-function2 > user=> (defn sub-function3 [c] (println "3:" c) (delay (fn [c] > false))) > #'user/sub-function3 > user=> (defn a-meta-meta-function [c] > (alt (sub-function1 c) (sub-function2 c) (sub-function3 c))) > #'user/a-meta-meta-function > user=> (time ((a-meta-meta-function foo) some-tokens)) > java.lang.Exception: Unable to resolve symbol: foo in this context > (NO_SOURCE_FILE:13) > user=> (time ((a-meta-meta-function "CONTEXT") [:a :b :c])) > 1: CONTEXT > 2: CONTEXT > 3: CONTEXT > "Elapsed time: 2.443 msecs" > true > > Why would it take so much more time? Is it because it might take a > long time to construct a Delay object? Can I do something different to > make it more efficient, or should I just not use Delay objects? I wouldn't really expect that delay/force would be faster unless there are cases where the delay never gets forced. And of course then you'll only get savings in the event that the time it takes to execute the delayed expression would take longer than the creation of the delayed expression in the first place. In your expample it appears to me that all of the delays are being forced, and so I'm not surprised the runtime is longer. So overall, it does not seem unexpected that delay/force takes longer than the same raw expression. The real question is whether or not you'll end up with a lot of delay objects that never get forced--enough to justify the cost of creating the objects in the first place. /mike. --~--~-~--~~~---~--~~ 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: Is there any way to dereference %1 %2 etc?
It doesn't make sense to mix map and println. If you want side effects, use doseq instead of map: (doseq [{a :a} [ {:a 1 :b 11} {:a 2 :b 22} {:a 3 :b 33}]] (println a)) {:a 1, :b 11} {:a 2, :b 22} {:a 3, :b 33} If you don't want side effects, use str instead of println (you could also use identity): (map #(str (:a %1)) [ {:a 1 :b 11} {:a 2 :b 22} {:a 3 :b 33}]) -> ("1" "2" "3") If you want to destructure, use the longer anonymous fn form instead of the % bindings: (map (fn [{a :a}] a) [ {:a 1 :b 11} {:a 2 :b 22} {:a 3 :b 33}]) -> (1 2 3) Cheers, Stu > > > (map #(println %) [1 2 3 4]) prints 1 2 3 and 4 > > But what if the vector element is a hash with > [ {:a 1 :b 11} {:a 2 :b 22} {:a 3 :b 33}]? > can we dereference :a using %1, like (:a %1)? > If not, any alternative? maybe destructuring or something? > > thanks > -sun > > > > > --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Expanding args in (fn [& args]...) to actual args, not ArraySeq
Is there a way to have args expanded to the actual arguments, not an ArraySeq? I need the actual args to pass to a multimethod so it knows how to dispatch appropriately. Code similar to this (send-off (next-agent) (fn [v & args] (somefn args)) arg1 arg2 arg3) Give me an error like this. ... Caused by: java.lang.IllegalArgumentException: No method for dispatch value: (clojure.lang.ArraySeq) ... I could do this (below), but thought there might be a macro or something I'm not aware of to make this cleaner. (send-off (next-agent) (fn [v & args] (somefn (nth args 0) (nth args 1) (nth args 2))) arg1 arg2 arg3) Thanks, Justin --~--~-~--~~~---~--~~ 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: Utilities for clojure.contrib?
I also think it's unhelpful for codebases to stray further from the builtin functions than needed, because it makes that code harder to read as well. So I will consider each of these more carefully. My comments below are of course highly influence by my personal experiences using Clojure. I'm quite willing to admit that even if I've never needed a function, it's certainly possible that everyone else has. On Mon, Jan 12, 2009 at 6:48 PM, Jason Wolfe wrote: > > ;;; Sequences. > > (defn combinations "Take a seq of seqs and return a lazy seq of > ordered combinations (pick 1 from each seq)" > [seqs] > (if (empty? seqs) '(()) >(forcat [item (first seqs)] > (map #(cons item %) (combinations (rest seqs)) I don't think I've ever needed this. When I've needed similar, I've used 'for', but being a macro it can be harder to compose and requires knowing the depth of the nesting ahead of time. I'm not aware of anything other builtin that provides this kind of nesting behavior, so I'd tend to say this pays for itself. Almost identical to clojure.contrib.lazy-seqs/combinations (require '[clojure.contrib.lazy-seqs :as ls]) user=> (combinations [[1 2] [4 5] [7 8]]) ((1 4 7) (1 4 8) (1 5 7) (1 5 8) (2 4 7) (2 4 8) (2 5 7) (2 5 8)) user=> (ls/combinations [1 2] [4 5] [7 8]) ([1 4 7] [1 4 8] [1 5 7] [1 5 8] [2 4 7] [2 4 8] [2 5 7] [2 5 8]) > (defn power-set > "Returns a lazy seq of possible subvectors of seq s." > [s] > (loop [s (seq s), sets [[]]] >(if s >(recur (rest s) (lazy-cat sets (map #(conj % (first s)) > sets))) > sets))) Never needed it, but looks like a good candidate for clojure-contrib I certainly wouldn't want to create it from scratch if I did need it. > (defn random-permutation [s] > "Return a random permutation of this seq." > (let [arr (to-array s) len (alength arr)] >(dotimes [i (dec len)] > (let [r (+ i (rand-int (- len i))), >prev (aget arr i)] >(aset arr i (aget arr r)) >(aset arr r prev))) > (seq arr))) > > (defn random-element [s] > "Return a random element of this seq" > (nth s (rand-int (count s I wouldn't argue against those. > (defn maximal-elements [f s] > "Return a seq of elements of s maximizing (f elt)." > (when (seq s) >(loop [max-elts (first s), > max-val (f (first s)), > rest-elts (rest s)] > (if (empty? rest-elts) > max-elts >(let [next-val (f (first rest-elts))] > (cond (< next-val max-val) (recur max-elts max-val (rest rest- > elts)) >(= next-val max-val) (recur (cons (first rest-elts) max-elts) > max- > val (rest rest-elts)) >(> next-val max-val) (recur [(first rest-elts)] next-val (rest > rest- > elts I'm having a hard time imagining when maximal-elements would be useful. What have you used it for? Looks like a good candidate for application code. :-) > (import '(java.util HashSet)) > (defn distinct-elts? "Are all of the elements of this sequence > distinct? Works on infinite sequences with repititions, making it > useful for, e.g., detecting cycles in graphs." > [s] > (let [hs (HashSet.)] >(loop [s (seq s)] > (cond (empty? s)true >(.contains hs (first s))false >:else (do (.add hs (first s)) (recur (rest s))) Is there any reason the builtin 'distinct?' couldn't handle these cases as well? What does "elts" stand for? > (defn concat-elts "Lazily concatenate elements of a seq of seqs." [s] > (when (seq s) (lazy-cat (first s) (concat-elts (rest s) > > (defn lazy-mapcat "Like mapcat but is lazy like map" [f s] > (concat-elts (map f s))) > > (defn map-when "Like map but discards logically false entries" > [fn & seqs] > (filter identity (apply map fn seqs))) Sufficient laziness is another conversation entirely. :-) > (defn iterate-while [f x] > (take-while identity (iterate f x))) As I said, I've written this out myself. If it was included I would certainly use it. And as you pointed out, the words in its name mean exactly what they mean in the body. I'd vote for this. > (defn chunk "Lazily break s into chunks of length n (or less, for the > final chunk)." > [n s] > (when (seq s) >(lazy-cons (take n s) > (chunk n (drop n s) This is so close to 'partition', that I think I'd prefer there be only one, or at least have related names. > (defn mevery? "Like every but takes multiple seq args like map." > ([f & seqs] > (or (some empty? seqs) > (and (apply f (map first seqs)) > (recur f (map rest seqs)) Is that the same as this? (defn my-mevery? [f & seqs] (every? identity (apply map f seqs))) Someone suggested all the functions that currently take a predicate and one seq ought to take multiple seqs and work like 'map'. I suppose this would include: every? any? some etc. Seems pretty convenient, and I've not heard arguments against it. But without that, I
Re: Utilities for clojure.contrib?
On Wed, Jan 14, 2009 at 12:11 AM, GS wrote: > > On Jan 13, 7:17 pm, "Nick Vogel" wrote: >> seq returns nil when a collection has no items. According to the >> documentation for empty?, empty? is the same as (not (seq coll)) so you >> should use seq for expressing the opposite of empty? > > According to my experiment, the code above works equally well whether > 'seq or 'seq? is used. Intuitively (i.e. without actually knowing :) > seq? is more efficient because it returns a boolean, not a newly- > allocated sequence. > > So, either: > > 1. My experiment was wrong, and seq? is not a valid stand-in > for seq in the above code. Right on the first try! :-) user=> (seq-chunk 2 [1 2 3 4 5]) ((1 2) (3 4) (5)) user=> (seq?-chunk 2 [1 2 3 4 5]) nil This is because a vector is not itself a seq, though it is seq-able. Thus 'seq?' returns false, which 'seq' returns a sequence as long as the vector is not empty. > 2. My intuition is wrong, and 'seq? is not more efficient than 'seq. Both are usually very fast -- fast enough to not worry about them, and certainly fast enough that you should use the correct one rather than the fast one. :-) However, for the record, depending on the type of object being examined, either may be faster. 100,000 times each, fastest to slowest: (seq '(1 2 3 ==> "Elapsed time: 8.086614 msecs" (seq? '(1 2 3 ==> "Elapsed time: 11.290486 msecs" (seq? [1 2 3]))) ==> "Elapsed time: 19.127055 msecs" (seq [1 2 3]))) ==> "Elapsed time: 20.471575 msecs" --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 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: Parameterized query with clojure.contrib.sql
Steve, Thanks much for your work. The new with-query-results seems to work quite well. Your timing is impeccable with this set of changes: I had just finished hacking out a (much uglier) version of update-values as well. (I'll switch over to using the clojure.contrib.sql versions now for a number of reasons). One suggestion/request for your next set of updates: insert-or-update- values, which will determine whether the given row exists in the database already, and then issue the appropriate insert/update statement as the case may be. This is a common paradigm that I find myself doing manually all the time with database coding in any language. I had hacked up a version of insert-or-update-values that worked (with my version of update-values I mentioned above), but it's much too ugly to post here. :-) -Greg On Jan 14, 12:03 am, "Stephen C. Gilardi" wrote: > Hi Greg, > > I checked in changes to clojure.contrib.sql that are intended to > address this. If you get a chance to try the updated lib, I'd > appreciate hearing how it works for you and any suggestions or bug > reports you may have. > > Thanks, > > --Steve > > smime.p7s > 3KViewDownload --~--~-~--~~~---~--~~ 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: Expanding args in (fn [& args]...) to actual args, not ArraySeq
Hi Justin, Use apply: (send-off (next-agent) (fn [v & args] (apply somefn args)) arg1 arg2 arg3) Cheers, Stuart > Is there a way to have args expanded to the actual arguments, not an > ArraySeq? I need the actual args to pass to a multimethod so it > knows how to dispatch appropriately. > > Code similar to this > > (send-off (next-agent) (fn [v & args] (somefn args)) arg1 arg2 arg3) > > Give me an error like this. > > ... > Caused by: java.lang.IllegalArgumentException: No method for > dispatch value: (clojure.lang.ArraySeq) > ... > > I could do this (below), but thought there might be a macro or > something I'm not aware of to make this cleaner. > > (send-off (next-agent) (fn [v & args] (somefn (nth args 0) (nth args > 1) (nth args 2))) arg1 arg2 arg3) > > Thanks, > Justin > > > --~--~-~--~~~---~--~~ 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: Expanding args in (fn [& args]...) to actual args, not ArraySeq
Ah, that's right! Thank you. I'm having a hard time thinking functionally. On Wed, Jan 14, 2009 at 12:31 PM, Stuart Halloway wrote: > > Hi Justin, > > Use apply: > > (send-off (next-agent) (fn [v & args] (apply somefn args)) arg1 arg2 > arg3) > > Cheers, > Stuart > > > Is there a way to have args expanded to the actual arguments, not an > > ArraySeq? I need the actual args to pass to a multimethod so it > > knows how to dispatch appropriately. > > > > Code similar to this > > > > (send-off (next-agent) (fn [v & args] (somefn args)) arg1 arg2 arg3) > > > > Give me an error like this. > > > > ... > > Caused by: java.lang.IllegalArgumentException: No method for > > dispatch value: (clojure.lang.ArraySeq) > > ... > > > > I could do this (below), but thought there might be a macro or > > something I'm not aware of to make this cleaner. > > > > (send-off (next-agent) (fn [v & args] (somefn (nth args 0) (nth args > > 1) (nth args 2))) arg1 arg2 arg3) > > > > Thanks, > > Justin > > > > > > > > > > --~--~-~--~~~---~--~~ 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: detecting running as script
Thanks! I'll have a look at clojure.contrib.command-line. I don't need anything super-powerfull, just something that make it easy to define and parse command line arguments in the "normal manner". Sorry about my previous double post :( Grunde On Wed, Jan 14, 2009 at 6:00 PM, Chouser wrote: > > On Wed, Jan 14, 2009 at 5:58 AM, Grunde wrote: >> >> Now, it these some elegant way to parse and use the passed command >> line arguments in my program? Is there any lib like Ruby/Pythons >> optparse to assist parsing of command line arguments? > > There is clojure.contrib.command-line > > I don't know if it's elegant, and it's certainly not (yet) as powerful > as many optparse tools in some other languages, but I've found it to > be useful. > > --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 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.contrib.command-line patch: multiple option format
On Tue, Jan 13, 2009 at 8:08 PM, Perry Trolard wrote: > > Hi Chouser & list, > > I like clojure.contrib.command-line -- thanks for it! -- but I wanted > to be able to specify multiple forms for an option, e.g. --help, -h, > -?, etc. Here (in the Files section) > > http://bit.ly/fIVH > > is a patch to enable it (the values are bound only to the first form > given -- help, in the previous example). Would you consider it (my CA > is in)? It's a good idea. Any sane way to allow the single-letter variety to be specified with a single leading dash, instead of a double-dash? 'justify' is interesting. I wonder if a CL-style 'format' will end up in clojure-contrib after all. --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 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: when performance matters
On Jan 14, 8:27 am, Asbjørn Bjørnstad wrote: > Anyway, here is a core part of the algorithm. It's a diffusion > step, this gets called 3 times and in total this takes up more than > one second of cpu time on my machine which makes framerates very > slow. If anyone got any improvements I'd be happy to hear about it: Here are a few possibilities: 1. Java 2-D, 3-D, etc. arrays are implemented as arrays of (arrays of ... pointers), which hurts spatial locality. It was enough of a problem that I've seen people reimplement 2-D arrays using 1-D arrays. You might consider using a 1-D array and taking the trouble to do the indexing by hand. Of course only a benchmark can tell whether it really helps. 2. It looks like your inner loop is iterating over the first index of the array (is that right?), which is good for Fortran but bad for Java. Java 2-D arrays are row-oriented. In your inner loop, you should iterate such that successive array values are stored adjacent to each other in memory. 3. I noticed you are doing 20 iterations of Gauss-Seidel. There are some smart ways to speed up multiple stencil applications. I can point you to references if you are interested. Fun to see numeric codes in Clojure! ;-) mfh --~--~-~--~~~---~--~~ 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: Observing namespace changes
OK thank you both Chris & Mike for your answer. What I've done for the moment is similar to what Mike did: at any place where there is a chance for something to change namespaces, I reload a new snapshot (and I throw the old). Registering watchers for Vars seems very interesting, I'll investigate. Registering watchers for ns would be great too. But there still may be a case or two uncovered, even when we will be able to register watchers on ns : when new ns are created. Then we need so kind of watcher on the vector holding all the ns ... ? If this vector is implemented as a Var, it is maybe already possible to do this, even if it is undocumented ? Cheers, -- Laurent On Jan 14, 5:55 pm, MikeM wrote: > There's no event mechanism to monitor namespace changes. I accomplish > this by taking a snapshot before and after any possible namespace- > changing execution, using ns-map. Not as efficient as an event > callback, but I haven't had any performance issues (map lookups are > plenty fast for me). > > You can register a watcher for a Var to get notification of a root > binding change using add-watcher - note that the clojure.org doc for > add-watcher has not been updated to match the Var watcher revision. --~--~-~--~~~---~--~~ 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: Delays and their efficiency
On Jan 13, 12:39 pm, samppi wrote: > Recently, I asked how to make a function evaluate its arguments lazily > (http://groups.google.com/group/clojure/browse_thread/thread/ > cd01ef39c2b62530), and I was given a good solution: use Delay objects > (with the delay and force functions). > > I wanted to do this for the efficiency of a functional parser library > that uses many meta-functions and meta-meta-functions: I thought that > stopping arguments from being evaluated until needed was a good way to > prevent useless creation of objects, especially in huge trees of meta- > meta-functions. But I was very surprised when running my library's > unit tests to see that using Delay objects took much more time to run > the tests than not using Delays. Here's an example in a REPL: > > Clojure > user=> (defn alt [& functions] > (fn [tokens] > (some #(% tokens) functions))) > #'user/alt > user=> (defn sub-function1 [c] (println "1:" c) (fn [c] false)) > #'user/sub-function1 > user=> (defn sub-function2 [c] (println "2:" c) (fn [c] true)) > #'user/sub-function2 > user=> (defn sub-function3 [c] (println "3:" c) (fn [c] false)) > #'user/sub-function3 > user=> (defn a-meta-meta-function [c] > (alt (sub-function1 c) (sub-function2 c) (sub-function3 c))) > #'user/a-meta-meta-function > user=> (time ((a-meta-meta-function "CONTEXT") [:a :b :c])) > 1: CONTEXT > 2: CONTEXT > 3: CONTEXT > "Elapsed time: 1.018 msecs" > true > > ...vs... > > Clojure > user=> (defn alt [& functions] > (fn [tokens] > (some #((force %) tokens) functions))) > #'user/alt > user=> (defn sub-function1 [c] (println "1:" c) (delay (fn [c] > false > #'user/sub-function1 > user=> java.lang.Exception: Unmatched delimiter: ) > user=> (defn sub-function1 [c] (println "1:" c) (delay (fn [c] > false))) > #'user/sub-function1 > user=> (defn sub-function2 [c] (println "2:" c) (delay (fn [c] true))) > #'user/sub-function2 > user=> (defn sub-function3 [c] (println "3:" c) (delay (fn [c] > false))) > #'user/sub-function3 > user=> (defn a-meta-meta-function [c] > (alt (sub-function1 c) (sub-function2 c) (sub-function3 c))) > #'user/a-meta-meta-function > user=> (time ((a-meta-meta-function foo) some-tokens)) > java.lang.Exception: Unable to resolve symbol: foo in this context > (NO_SOURCE_FILE:13) > user=> (time ((a-meta-meta-function "CONTEXT") [:a :b :c])) > 1: CONTEXT > 2: CONTEXT > 3: CONTEXT > "Elapsed time: 2.443 msecs" > true > > Why would it take so much more time? Is it because it might take a > long time to construct a Delay object? Can I do something different to > make it more efficient, or should I just not use Delay objects? It's hard to enumerate everything that is problematic with this approach to determining efficiency. Let's start with the basics: 1) Premature optimization is the root of all evil 2) See #1 3) You can't draw conclusions from a single execution of a short function 4) See #1 5) If you design with Delays etc to put off, avoid or cache a time- consuming computation, then test with trivial computations, you know nothing 6) See #1 7) timings that include I/O tend to be dominated by it 8) see #1 ... 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: when performance matters
On Wed, Jan 14, 2009 at 11:27 AM, Asbjørn Bjørnstad wrote: > > Anyway, here is a core part of the algorithm. It's a diffusion > step, this gets called 3 times and in total this takes up more than > one second of cpu time on my machine which makes framerates very > slow. If anyone got any improvements I'd be happy to hear about it: Not sure if it makes for this algorithm, but there are faster (and less safe) versions of several functions you're using. Check the output of (find-doc "unchecked") While I think your loop-local 'c' will be a primitive int, I'm not entirely sure -- might be worth trying (int (unchecked-add x line-offset)). Same thing on line-offset, not sure it's a primitive. --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 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: question about understanding/exploring agents
On Wed, Jan 14, 2009 at 6:00 AM, bOR_ wrote: > > However, on this 4core machine, the fib behaves as I would expect when > I scale up the number of threads, while the multiplication barely > seems to benefit from the 4 cores. The only difference I see between > the two functions is that the fib is recursive, but I am not quite > sure why that would matter. On my 2-core laptop, I'm seeing loopmult pretty consistently taking between 2 and 2.7 times as long as loopfib, regardless of the number of threads. What exactly are you trying to measure? --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 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: when performance matters
For a completely different way of doing this, you could certainly use GPGPU programming to speed this up. This section: (aset diffused-grid c (float (/ (+ (aget grid c) (* a (+ (+ (aget diffused-grid (dec c)) (aget diffused-grid (inc c))) (+ (aget diffused-grid (- c line-length)) (aget diffused-grid (+ c line-length) looks a lot to me like what any blending or bloom pixel shader does. If you are doing large grids (like 4000x1000) then you can't beat CUDA for something like this. Those four lookups would most likely all be in texture cache as texture cache is spatially managed (i.e. function of both x and y). You mentioned frame rate anyway, just read the framebuffer back after the render call and you can work with the next step of your iteration. You want this for a game engine anyway; do it in opengl or directx using shaders. Chris On Jan 14, 1:04 pm, Chouser wrote: > On Wed, Jan 14, 2009 at 11:27 AM, Asbjørn Bjørnstad > wrote: > > > > > Anyway, here is a core part of the algorithm. It's a diffusion > > step, this gets called 3 times and in total this takes up more than > > one second of cpu time on my machine which makes framerates very > > slow. If anyone got any improvements I'd be happy to hear about it: > > Not sure if it makes for this algorithm, but there are faster (and > less safe) versions of several functions you're using. Check the > output of (find-doc "unchecked") > > While I think your loop-local 'c' will be a primitive int, I'm not > entirely sure -- might be worth trying (int (unchecked-add x > line-offset)). Same thing on line-offset, not sure it's a primitive. > > --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 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: when performance matters
On Jan 14, 11:27 am, Asbjørn Bjørnstad wrote: > On Jan 14, 12:20 pm, "Mark H." wrote: > > > > > I humbly propose that folks shouldn't complain about Clojure being > > slow for their apps until they have at least one of the following: > > > 1. A targeted benchmark for an important bottleneck in their > > application, implemented in both Clojure and the current > > implementation language, with performance results; or > > > 2. A performance model based on an understanding of the Clojure and > > HotSpot compilation processes, that highlights which particular > > features of the latter would make their application slower than in its > > current implementation language. > > > This is not out of elitism but out of an earnest desire to be helpful; > > it's hard to give good advice on language choice and code optimization > > when we don't know what the bottlenecks are. Also it's really hard > > for anyone to optimize their own code unless they themselves know > > where the bottlenecks are. The latter means that #1 above is > > surprisingly easy; it often can be done with a simple function trace > > of a typical run. > > I'm not complaining, but I find the topic interesting as I just tried > translating a fluid dynamics algorithm to clojure. > (http://www.dgp.toronto.edu/people/stam/reality/Research/pdf/ > GDC03.pdf) > I got no experience with this kind of stuff, it's just something I > tried out for fun. So the performance I get may be as expected. Or > there may be obvious ways of speeding it up that I don't see. > > Anyway, here is a core part of the algorithm. It's a diffusion > step, this gets called 3 times and in total this takes up more than > one second of cpu time on my machine which makes framerates very > slow. If anyone got any improvements I'd be happy to hear about it: > > (def grid-size 300) > > (defn make-grid [] > (make-array Float/TYPE (* (+ grid-size 2) > (+ grid-size 2 > > (defn diffuse [grid diff-ratio dt] > (let [a (float (* dt diff-ratio grid-size grid-size)) > a4-1 (float (+ 1 (* 4 a))) > grid #^floats (deref grid) > diffused-grid #^floats (make-grid) > line-length (int (+ grid-size 2))] > (dotimes [n 20] > (dotimes [y grid-size] > (let [line-offset (* (inc y) line-length)] > (loop [x (int 1) > c (+ x line-offset)] >(aset diffused-grid c >(float (/ (+ (aget grid c) > (* a > (+ (+ (aget diffused-grid (dec > c)) > (aget diffused-grid (inc > c))) >(+ (aget diffused-grid (- c > line-length)) > (aget diffused-grid (+ c > line-length)) > a4-1))) >(when (< x grid-size) > (recur (inc x) > (inc c))) > diffused-grid)) > > (def foo (ref (make-grid))) > > (time (diffuse foo 0.00025 0.002)) > Try this (and make sure you are using -server): (defn diffuse [grid diff-ratio dt] (let [a (float (* dt diff-ratio grid-size grid-size)) a4-1 (float (+ 1 (* 4 a))) grid #^floats (deref grid) diffused-grid #^floats (make-grid) grid-size (int grid-size) line-length (int (+ grid-size 2))] (dotimes [n 20] (dotimes [y grid-size] (let [line-offset (* (inc y) line-length)] (loop [x (int 1) c (int (+ x line-offset))] (aset diffused-grid c (/ (+ (aget grid c) (* a (+ (+ (aget diffused-grid (unchecked-dec c)) (aget diffused-grid (unchecked-inc c))) (+ (aget diffused-grid (unchecked-subtract c line-length)) (aget diffused-grid (unchecked-add c line-length)) a4-1)) (when (< x grid-size) (recur (unchecked-inc x) (unchecked-inc c))) diffused-grid)) (time (diffuse foo 0.00025 0.002)) "Elapsed time: 25.588 msecs" 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: Utilities for clojure.contrib?
I agree with Chouser that an uncluttered library is a great virtue. I too have been turned off by CL in part because of the enormous number of subtly distinct built-in functions. I'm partial to Scheme, though, so maybe I'm best viewed as a fanatic on this point. :-) That said, it does seem pleasantly Clojure-ish to have functions named x-when, like "map-when". This is pretty self-explanatory, so I'd be happy having these sorts of functions, especially when they do replace complex chaining of other functions. But I'm not afraid of using reduce, map, and apply to prepare values to use as arguments to built-ins. And I'm not afraid to encapsulate this into my own functions when I need to. I'm OK with building up a bit of a language for whatever problem I'm tackling. (There's the schemaniac in me again.) There's a golden mean between complexity and clarity. At first glance, Jason's suggestions seem close to that mean to me, and I really like what he's done. Thanks for the good work, Jason! Michael On Jan 13, 5:42 pm, Chouser wrote: > On Tue, Jan 13, 2009 at 4:05 PM, Jason Wolfe wrote: > > >> It raises a question, though -- how much functionality should a > >> function provide to be worth making everyone who reads the code learn > >> the new vocabulary? I've written each of these inline when I've > >> needed them. Are they better as idioms or functions? > > > I would say they're better as functions, for several reasons. > > > First, many of these aren't really "new vocabulary", since you can > > clearly tell what they do from their name and knowledge of the > > existing core functions. If you know map and you know take-when and > > take-while, you already know what map-when and map-while do. > > > Moreover, I think some of these actually fill in mysterious gaps in > > the language. For and map are essentially two different ways of > > saying the same thing; which to use in a given situation seems to be > > largely a matter of aesthetics (except when there are multiple > > iterates...). Yet, for supports :when and :while, whereas there are > > no map-when and map-while forms. Conversely, we get mapcat but no > > forcat. > > Those are good arguments. I guess what I fear is some of the reaction > I've had to reading Common Lisp code. The difference in feeling > between CL and Clojure is important to me because I tried repeatedly > and failed to adopt CL into my toolbox, but Clojure went quite > smoothly. > > One of the things I found difficult with CL was the extremely large > number of builtin functions -- a large vocabulary with subtle > differences between nearly synonymous-sounding words. It meant that > at first glance, a particular block of could would look simple -- 5 > lines, how hard could it be? But in reading it I would discover I > only new 2 of the 15 functions used. So I'd fight through it, feeling > like I was learning something useful, but the next function would use > 15 completely different functions. > > Now perhaps I'm just whining, perhaps I needed better reference tools, > perhaps I'm mis-identifying the problem. But it is a real source of > my hesitancy to ask for more built-in functions. > > > For instance, I > > find myself needing to use map-map or merge-reduce fairly frequently, > > and the (reduce (fn [m [k v]] (assoc m k (f v))) {} m) type idioms > > they replace are much more difficult to read than calls to the > > utilities IMO. > > Yes, that's a mouthful. I'll need to study merge-reduce and map-map a > bit more to see when to use them instead of merge, merge-with, and > into. > > --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 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: update-values for clojure.contrib.sql
Good, anyway it was only a relatively minor modification of insert- values function. I'm sending my contributor agreement today, hoping to contribute further in a near future. Thanks On Jan 14, 12:13 am, "Stephen C. Gilardi" wrote: > On Jan 11, 2009, at 10:42 AM, Stephen C. Gilardi wrote: > > > I'd like to include something like this in clojure.contrib.sql. That > > will go smoothest if I can base it directly on what you've written > > and that's only possible if you send in a contributor agreement. > > Would you please send one in? > > Hi budu, > > While I still encourage you (and everyone who thinks they may want to > contribute) to send in a contributor agreement, I came up with an > original implementation for this function. Please see my recent update > to clojure.contrib.sql. Thanks for bringing the need for it to the fore. > > --Steve > > smime.p7s > 3KViewDownload --~--~-~--~~~---~--~~ 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: Utilities for clojure.contrib?
On Jan 14, 10:10 am, Chouser wrote: > I also think it's unhelpful for codebases to stray further from the > builtin functions than needed, because it makes that code harder to > read as well. So I will consider each of these more carefully. Thanks for your detailed response! To keep this manageable, I'll cut out the parts where I don't think comments are needed. > > (defn combinations "Take a seq of seqs and return a lazy seq of > > ordered combinations (pick 1 from each seq)" > > [seqs] > > (if (empty? seqs) '(()) > > (forcat [item (first seqs)] > > (map #(cons item %) (combinations (rest seqs)) ... > Almost identical to clojure.contrib.lazy-seqs/combinations > (require '[clojure.contrib.lazy-seqs :as ls]) Oops, I forgot to check lazy-seqs before writing this one. Ignore this. > > (defn maximal-elements [f s] > > "Return a seq of elements of s maximizing (f elt)." > > (when (seq s) > > (loop [max-elts (first s), > > max-val (f (first s)), > > rest-elts (rest s)] > > (if (empty? rest-elts) > > max-elts > > (let [next-val (f (first rest-elts))] > > (cond (< next-val max-val) (recur max-elts max-val (rest rest- > > elts)) > > (= next-val max-val) (recur (cons (first rest-elts) > > max-elts) max- > > val (rest rest-elts)) > > (> next-val max-val) (recur [(first rest-elts)] next-val > > (rest rest- > > elts > > I'm having a hard time imagining when maximal-elements would be > useful. What have you used it for? Looks like a good candidate for > application code. :-) I've used it for picking the best successors in a search algorithm, particularly as (first (maximal-elements ...)) or (random-element (maximal-elements ...)). But, I can imagine it would be useful in many situations, i.e. things like. user> (maximal-elements second {:bob 10 :lisa 20 :peter 20}) ([:peter 20] [:lisa 20]) There don't seem to be any other utils that pull out the "best" element (s) of a seq, so there seems to be a role for this. But, I've only needed it once so far, so maybe it's not so important. > > (import '(java.util HashSet)) > > (defn distinct-elts? "Are all of the elements of this sequence > > distinct? Works on infinite sequences with repititions, making it > > useful for, e.g., detecting cycles in graphs." > > [s] > > (let [hs (HashSet.)] > > (loop [s (seq s)] > > (cond (empty? s) true > > (.contains hs (first s)) false > > :else (do (.add hs (first s)) (recur (rest s))) > > Is there any reason the builtin 'distinct?' couldn't handle these > cases as well? What does "elts" stand for? I suppose this is the same as (apply distinct? s). I was under the impression that apply always evaluated the entire arg-seq, but I just realized that this isn't the case -- I guess it evaluates everything but the "& rest" params, which can remain a lazy seq? So, for instance, this works user> (apply distinct? (interleave (iterate inc 0) (iterate inc 10))) false which was the whole point of distinct-elts? for me. So, ignore this one too. > > (defn concat-elts "Lazily concatenate elements of a seq of seqs." [s] > > (when (seq s) (lazy-cat (first s) (concat-elts (rest s) > > > (defn lazy-mapcat "Like mapcat but is lazy like map" [f s] > > (concat-elts (map f s))) > > > (defn map-when "Like map but discards logically false entries" > > [fn & seqs] > > (filter identity (apply map fn seqs))) > > Sufficient laziness is another conversation entirely. :-) Yes. I would be happy to drop concat-elts and lazy-mapcat, if the built-in concat (which seems to be used by mapcat) was changed to be less eager (in the apply sense just mentioned above). user> (take 0 (apply concat (report-seq "" [[1] [2] [3] [4] [5]]))) (first [1] ) (rest after [1] ) (first [2] ) (rest after [2] ) (first [3] ) (rest after [3] ) nil This can end up being a real drag in situations like (apply concat (map #(recurive-call ...) ...)), since it may result in an exponential amount of extra work being done. Any chance of this being changed? (It should be possible to get rid of the last 4 evaluations here, without getting into the territory of our last conversation about laziness :)) > > (defn chunk "Lazily break s into chunks of length n (or less, for the > > final chunk)." > > [n s] > > (when (seq s) > > (lazy-cons (take n s) > > (chunk n (drop n s) > > This is so close to 'partition', that I think I'd prefer there be only > one, or at least have related names. OK, I agree the name should be closer to partition (which I'd forgotten about), but I think this one is at least as useful as partition (You can recover partition from this one by (take-when #(= (count %) n) (chunk n s))) but not vice-versa.) Any suggestions on a name? > > (defn mevery? "Like every but takes multiple seq args like map." > > ([f & seqs] > > (or (some empty? seqs) > >
Re: clojure.contrib.command-line patch: multiple option format
Hi Chouser, Thanks for checking out the patch. > It's a good idea. Any sane way to allow the single-letter variety to > be specified with a single leading dash, instead of a double-dash? Single or double dashes should work for both kinds of options (long- or short-style), based on your code. The regex that looks for option syntax is (re-find #"^--?(.*)" argkey) (optional second dash). Are you seeing it not work this way? Maybe you're referring to the printed help, with the "--(option|o)" listing. I agree that it isn't that cool. Maybe dashes don't need to be printed next to the options at all, perhaps with a short message about single or doubles working (though that's a little clunky, too)? > 'justify' is interesting. I wonder if a CL-style 'format' will end up > in clojure-contrib after all. Yeah, I couldn't bear to do it w/o a bit of justification, even if it's a little out of place in this lib (& if 'justify' isn't really complete -- a centered option would be pretty easy to add). As for the full CL format, it looks like Tom Faulhaber is pretty far along at http://github.com/tomfaulhaber/cl-format/ but I'm not familiar with it myself. Best, Perry --~--~-~--~~~---~--~~ 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: Utilities for clojure.contrib?
> > So, either: > > > 1. My experiment was wrong, and seq? is not a valid stand-in > > for seq in the above code. > > Right on the first try! :-) Well, that's something :) > user=> (seq-chunk 2 [1 2 3 4 5]) > ((1 2) (3 4) (5)) > user=> (seq?-chunk 2 [1 2 3 4 5]) > nil > > This is because a vector is not itself a seq, though it is seq-able. > Thus 'seq?' returns false, which 'seq' returns a sequence as long as > the vector is not empty. Sigh, I wish the API docs were more helpful in this case. clojure.core/seq? ([x]) Return true if x implements ISeq It's asking a lot from me to know whether vectors implement ISeq. > > 2. My intuition is wrong, and 'seq? is not more efficient than 'seq. > > Both are usually very fast -- fast enough to not worry about them, and > certainly fast enough that you should use the correct one rather than > the fast one. :-) Yeah, not a bad idea :) Thanks for your help, as always. Gavin --~--~-~--~~~---~--~~ 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: Clojure now running in production
Congratulation, this is quite amazing to see Clojure mature so fast and already working in production system. Sorry but I need to get back at finding that damn bug in a 10 years old VB legacy application :-( On Jan 13, 10:38 am, Luc Prefontaine wrote: > Hi everyone, > > as of yesterday pm, Clojure is running in a live system in a big > veterinarian hospital. > > We designed an HL7 message bus to link several services within the > hospital. > Presently we link the medical record system with the radiology > department. > The main benefit is to avoid re-keying information about patient and > requests in every system. > > We also provide some key applications on the bus to allow people to > share information in a consistent > way along the system they use on a daily basis. It's like a Babel tower, > radiologists want to work > with their radiology system while the administration wants to work with > the medical record system to > bill, ... each of these systems meet specific needs of a user base. > However there is a need for a common ground to share information. That's > what our product offers. > > This year the bus will expand to encompass prescription requests with > the pharmacy, the lab exams > and a couple of other systems. We have also another prospect so we may > end up with more than one site > by the end of 2009. > > The bus is designed to be a product, not a set of integration tools to > be assembled differently > at each customer site. It is highly configurable, all message based and > runs on distributed hardware. > > Clojure drives the top level logic of the bus (routing decisions, error > handling, archiving, ...). > > After digging for some parallel processing language better than Java, > Clojure emerged as a logical choice. > The design of this system is distributed with fault tolerance in every > software function but we needed to have > some options about the low-level components. Having access to all Java > libraries out there was a major factor > in our decision to use Clojure. > > Presently it runs on six small boxes like this one: > > http://www.fic.com.tw/product/ficimages/minipc.jpg > > with an internal redundant network. Each function is running in > master/slave mode with automatic fail over. > The throughput of the system is at least two thousands transactions an > hour. You can unplug cables, boxes, ... > and it still runs. It can sustain more than one fault before it fails. > > In the following year using Clojure and Terracotta we expect to bring > the degree of parallelism up to a point were we will > be able to run concurrently all the functions on multiple boxes and get > rid of the master/slave mode. > Distributed clusters are also in the pipe to allow to route between > different sites while keeping local site traffic and different local > applications. > > Expect a web site about this product in the next 2/3 months. We will > give Clojure visibility on this site. > Many of the key features of the system rely on Clojure so we would like > to give credit to Clojure and Rich. > Maybe this will be an incentive for people to look at Clojure as a > viable alternative to other functional > languages. > > Rich, thank you and congratulation, your baby has grown up well in the > last year and it will soon be asking for the car keys : > > Luc --~--~-~--~~~---~--~~ 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: Utilities for clojure.contrib?
> Sigh, I wish the API docs were more helpful in this case. > > clojure.core/seq? > ([x]) > Return true if x implements ISeq > > It's asking a lot from me to know whether vectors implement ISeq. If you don't know, you can always just ask the language :) user> (ancestors (class [1 2 3])) #{clojure.lang.IPersistentStack clojure.lang.Streamable java.io.Serializable java.lang.Runnable clojure.lang.IFn clojure.lang.IObj clojure.lang.Associative clojure.lang.Reversible clojure.lang.Obj clojure.lang.Sequential java.util.RandomAccess java.util.List clojure.lang.IPersistentVector clojure.lang.APersistentVector clojure.lang.AFn java.lang.Object clojure.lang.IPersistentCollection java.lang.Iterable java.lang.Comparable java.util.Collection java.util.concurrent.Callable} user> (contains? (ancestors (class [1 2 3])) clojure.lang.ISeq) false But, I agree; the seq/coll distinction can be very confusing at first, especially when faced with seemingly contradictory outputs like user> (= '(1) [1]) true user> (= '() []) false user> {'(1) true} {(1) true} user> (get *1 [1]) true user> (hash-map '(1) true) {(1) true} user> (get *1 [1]) nil -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: Utilities for clojure.contrib?
On Wed, Jan 14, 2009 at 4:26 PM, Jason Wolfe wrote: > > user> (contains? (ancestors (class [1 2 3])) clojure.lang.ISeq) > false Also there's 'isa?': user=> (isa? (class [1 2 3]) clojure.lang.ISeq) false user=> (isa? (class (seq [1 2 3])) clojure.lang.ISeq) true And 'instance?': user=> (instance? clojure.lang.ISeq [1 2 3]) false user=> (instance? clojure.lang.ISeq (seq [1 2 3])) true > But, I agree; the seq/coll distinction can be very confusing at first, > especially when faced with seemingly contradictory outputs like > > user> (= '(1) [1]) > true > > user> (= '() []) > false Hm. That does seem rather odd. I wonder if that paper defining 'egal' address this kind of issue. I haven't read it yet -- perhaps the time has come. > user> {'(1) true} > {(1) true} > > user> (get *1 [1]) > true > > user> (hash-map '(1) true) > {(1) true} > > user> (get *1 [1]) > nil The different map types use different kinds of equality, and not all of these are even defined for all object types: Hash-maps use hash functions, sorted-maps use a comparator, and array-maps use = --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 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: Delays and their efficiency
On Jan 14, 2:57 pm, Rich Hickey wrote: > On Jan 13, 12:39 pm, samppi wrote: > > > > > Recently, I asked how to make a function evaluate its arguments lazily > > (http://groups.google.com/group/clojure/browse_thread/thread/ > > cd01ef39c2b62530), and I was given a good solution: use Delay objects > > (with the delay and force functions). > > > I wanted to do this for the efficiency of a functional parser library > > that uses many meta-functions and meta-meta-functions: I thought that > > stopping arguments from being evaluated until needed was a good way to > > prevent useless creation of objects, especially in huge trees of meta- > > meta-functions. But I was very surprised when running my library's > > unit tests to see that using Delay objects took much more time to run > > the tests than not using Delays. Here's an example in a REPL: > > > Clojure > > user=> (defn alt [& functions] > > (fn [tokens] > > (some #(% tokens) functions))) > > #'user/alt > > user=> (defn sub-function1 [c] (println "1:" c) (fn [c] false)) > > #'user/sub-function1 > > user=> (defn sub-function2 [c] (println "2:" c) (fn [c] true)) > > #'user/sub-function2 > > user=> (defn sub-function3 [c] (println "3:" c) (fn [c] false)) > > #'user/sub-function3 > > user=> (defn a-meta-meta-function [c] > > (alt (sub-function1 c) (sub-function2 c) (sub-function3 c))) > > #'user/a-meta-meta-function > > user=> (time ((a-meta-meta-function "CONTEXT") [:a :b :c])) > > 1: CONTEXT > > 2: CONTEXT > > 3: CONTEXT > > "Elapsed time: 1.018 msecs" > > true > > > ...vs... > > > Clojure > > user=> (defn alt [& functions] > > (fn [tokens] > > (some #((force %) tokens) functions))) > > #'user/alt > > user=> (defn sub-function1 [c] (println "1:" c) (delay (fn [c] > > false > > #'user/sub-function1 > > user=> java.lang.Exception: Unmatched delimiter: ) > > user=> (defn sub-function1 [c] (println "1:" c) (delay (fn [c] > > false))) > > #'user/sub-function1 > > user=> (defn sub-function2 [c] (println "2:" c) (delay (fn [c] true))) > > #'user/sub-function2 > > user=> (defn sub-function3 [c] (println "3:" c) (delay (fn [c] > > false))) > > #'user/sub-function3 > > user=> (defn a-meta-meta-function [c] > > (alt (sub-function1 c) (sub-function2 c) (sub-function3 c))) > > #'user/a-meta-meta-function > > user=> (time ((a-meta-meta-function foo) some-tokens)) > > java.lang.Exception: Unable to resolve symbol: foo in this context > > (NO_SOURCE_FILE:13) > > user=> (time ((a-meta-meta-function "CONTEXT") [:a :b :c])) > > 1: CONTEXT > > 2: CONTEXT > > 3: CONTEXT > > "Elapsed time: 2.443 msecs" > > true > > > Why would it take so much more time? Is it because it might take a > > long time to construct a Delay object? Can I do something different to > > make it more efficient, or should I just not use Delay objects? > > It's hard to enumerate everything that is problematic with this > approach to determining efficiency. > > Let's start with the basics: > > 1) Premature optimization is the root of all evil > 2) See #1 > 3) You can't draw conclusions from a single execution of a short > function > 4) See #1 > 5) If you design with Delays etc to put off, avoid or cache a time- > consuming computation, then test with trivial computations, you know > nothing > 6) See #1 > 7) timings that include I/O tend to be dominated by it > 8) see #1 > ... > On rereading this I see #5 could be taken the wrong way - I mean you learn nothing from that test, as the Delays/parallelization etc dominate the time, when with a long computation they wouldn't. 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: By Example - another Clojure introduction wiki page
On Tue, Jan 13, 2009 at 8:12 PM, GS wrote: > > On Jan 14, 1:12 am, Timothy Pratley wrote: >> I've written small wiki article which dives right into the look and >> meaning of common Clojure constructs with examples. Personally I find >> I learn best by examples and when starting out they were hard to find, >> whereas formal descriptions were there but rather cryptic when you >> don't understand the context. My intention is to provide an initial >> understanding of how programs look, what they mean, and what can be >> accomplished because of their features... from which someone would >> then move to one of the more complete articles and references. >> >> http://en.wikibooks.org/wiki/Clojure_Programming/By_Example >> >> I hope someone finds it useful :) > > That's really good, Tim. I hope you continue with it :) AFAIC, just > about every function in core, set, zip and xml needs to be documented > by example. I'm just not smart enough to read the API docs of a lot > of functions and understand how to use them. Someone already started working on documenting every function with an example. See http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples. -- 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 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: Parameterized query with clojure.contrib.sql
On Jan 14, 2009, at 1:26 PM, Greg Harman wrote: Thanks much for your work. The new with-query-results seems to work quite well. You're quite welcome. I'm glad to hear it! Your timing is impeccable with this set of changes: I had just finished hacking out a (much uglier) version of update-values as well. (I'll switch over to using the clojure.contrib.sql versions now for a number of reasons). Great! One suggestion/request for your next set of updates: insert-or-update- values, which will determine whether the given row exists in the database already, and then issue the appropriate insert/update statement as the case may be. This is a common paradigm that I find myself doing manually all the time with database coding in any language. I've added update-or-insert-values. I'd appreciate hearing how it works for you. I had hacked up a version of insert-or-update-values that worked (with my version of update-values I mentioned above), but it's much too ugly to post here. :-) :-) --Steve smime.p7s Description: S/MIME cryptographic signature
Re: Parameterized query with clojure.contrib.sql
You're my personal Santa Claus today! :-) Confirmed present and working for both insert and update, using a 2 field where clause. On Jan 14, 5:14 pm, "Stephen C. Gilardi" wrote: > I've added update-or-insert-values. I'd appreciate hearing how it > works for you. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Only 9 agent "send-off"s complete?
Will someone please help me understand what I'm doing wrong? The code below is *supposed* to do the following. 1) Checkout the top level directory of a Subversion repository with empty depth. 2) Update the project directories (the ones right under the root of the repository) with depth immediates, thus downloading their sub-directories: "branches" and "tags". 3) Update the specific branch called BRANCHNAME with depth infinity. The result should be that I have a Subversion working copy that looks something like this, with BRANCHNAME also expanding to the specific code stored in that branch. ├───project1 │ ├───branches │ │ └───BRANCHNAME │ └───tags ├───project2 │ ├───branches │ │ └───BRANCHNAME │ └───tags └───project3 ├───branches │ └───BRANCHNAME └───tags ... The problem is that even though I have 38 projects in the repository, only 9 projects get updated. Here's the code. I can't provide the clojure.svn code unfortunately, but hopefully I'm doing something obviously wrong that someone can quickly see. (use 'clojure.svn) (use '[clojure.contrib.str-utils :only (re-split str-join)]) (def repo-url "URL_TO_SVN_REPO") (def dst-dir "PATH_TO_WORKING_COPY") (def projects (ls repo-url)) (def agents (map agent (take 5 (repeat 0 (co repo-url dst-dir EMPTY) (doseq [[p a] (partition 2 (interleave projects (cycle agents)))] (do (send-off a (fn [_ & args] (apply up args)) (str-join "/" [dst-dir p]) IMMEDIATES) (send-off a (fn [_ & args] (apply up args)) (str-join "/" [dst-dir p "branches" "BRANCHNAME"]) INFINITY))) Thanks, Justin --~--~-~--~~~---~--~~ 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: Utilities for clojure.contrib?
On Jan 14, 5:02 pm, Chouser wrote: > On Wed, Jan 14, 2009 at 4:26 PM, Jason Wolfe wrote: > > > user> (contains? (ancestors (class [1 2 3])) clojure.lang.ISeq) > > false > > Also there's 'isa?': > > user=> (isa? (class [1 2 3]) clojure.lang.ISeq) > false > user=> (isa? (class (seq [1 2 3])) clojure.lang.ISeq) > true > > And 'instance?': > > user=> (instance? clojure.lang.ISeq [1 2 3]) > false > user=> (instance? clojure.lang.ISeq (seq [1 2 3])) > true > > > But, I agree; the seq/coll distinction can be very confusing at first, > > especially when faced with seemingly contradictory outputs like > > > user> (= '(1) [1]) > > true > > > user> (= '() []) > > false > > Hm. That does seem rather odd. Fixed - svn 1208. 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 -~--~~~~--~~--~--~---
Pre-Alpha of IntelliJ plugin for Clojure
Hey Randall, Justin, Aria, HB, and all other IntelliJ enthusiasts Pre-Alpha of IntelliJ plugin for the Clojure is open for testing... Plugin currently provides editing with syntax coloring, syntax error high-lighting, folding, and brace matching. Also provides run configuration for Clojure scripts with REPL. Still todo includes goto definition and used by referencing, debugger integration, profiler integration and refactoring. Currently I am particularly interested in bugs with the syntax checking. Please look for cases where either a syntax error was not high-lighted, or valid code was marked as an error. Please report all cases, with an S-Expression to opus...@gmail.com. To install go to Settings/Updates and add the following to Plugin Hosts /http://clojure-intellij-plugin.googlecode.com/svn/trunk/plugin/updatePlugins.xml/ Then hit "Check Now" Enjoy! Peter Wolf --~--~-~--~~~---~--~~ 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: Only 9 agent "send-off"s complete?
Your omission of (apply await agents) is allowing the program to terminate before all your created threads finish I think. If I might further comment, your threading model is not quite right to me... You've created 5 agents and then used them to 'send-off' as many threads as there are projects. I would recommend instead using an agent to represent each task and using send to take advantage of the thread pool so you don't need to worry about how many threads there are. --~--~-~--~~~---~--~~ 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: question about understanding/exploring agents
Hi Chris > What exactly are you trying to measure? I think what Boris is expecting is that for 4 CPUs, running 1,2,3,4 equal work threads will take the same amount of time. This is true when he calls loopfib, but not true when he calls loopmult: threads: 1 "Elapsed time: 205.458949 msecs" "Elapsed time: 209.625273 msecs" threads: 2 "Elapsed time: 205.610849 msecs" "Elapsed time: 357.785344 msecs" threads: 3 "Elapsed time: 205.05658 msecs" "Elapsed time: 401.39515 msecs" threads: 4 "Elapsed time: 221.140317 msecs" "Elapsed time: 469.746969 msecs" ie: loopfib total duration is similar for 1,2,3,4 loopmult total duration increases in visible steps. I can't see why looking at the code, and am not currently in access to a multi-core machine to test. Regards, Tim. --~--~-~--~~~---~--~~ 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: when performance matters
On Jan 14, 12:29 pm, chris wrote: > For a completely different way of doing this, you could certainly use > GPGPU programming to speed this up. > ... > You want this for a game engine anyway; do it in opengl or directx > using shaders. I recommend OpenCL or CUDA instead for less pain ;-) (Well, maybe not for you -- I tried doing stuff with OpenGL and some language called CG in 2006 and it was a world of pain.) What's the target frame rate? mfh --~--~-~--~~~---~--~~ 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: Utilities for clojure.contrib?
>>> user> (= '(1) [1]) >>> true >> >>> user> (= '() []) >>> false >> >> Hm. That does seem rather odd. > > Fixed - svn 1208. Oh, I always assumed this was intentional ... I guess I never tried switching the order of arguments. Well, that makes a bit more sense then :). --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Multiple hashing functions? (+ bug in PersistentHashMap.java?)
I've already posted here [1] and on the issue board [2] about hashing. In particular, .hashCode for seqs/colls break the Java contract that whenever (.equals x y), (= (.hashCode x) (.hashCode y)). (let x = [1] and y = (seq [1])). As I've mentioned earlier, I hope that eventually .hashCode and .equals will be brought into line. Anyway, I won't rehash (ha ha) this issue further here. Anyway, I've also since realized that .equals and = are not the same thing, in particular with respect to numbers. So, it might be nice to have a different hash function (i.e., Clojure's "hash"), that matches the behavior of =, and allow the user to specify which hash function they'd like to use when creating hash-sets and hash-maps. (If you know Common Lisp, this idea should be very familiar to you). I think I've already seen at least one instance on the group of someone being thrown off by the fact that two numbers are Clojure = but treated as distinct keys in hash-maps (since they are not .equals to each- other). Actually, I'd be happy with a single type of hashing compatible with = rather than .equals if the idea of multiple flavors is not popular (as I imagine it probably won't be). And, lest you think that confusing = and .equals is just a noobie mistake, let me point out what seems to be a bug in PersistentHashMap.java I just found based on this same confusion. In particular, Objects are located in the map using Clojure's hash function, which is equivalent to .hashCode (and 0 for nil). But, the equality check done on line 561 is done using Util.equal, which is equivalent to Clojure =. Now, suppose that x is a key in the map and we're doing a lookup for y, where (= x y) but (not (.equals x y)). (i.e., x is (Integer. "12") and y is (Long. "12").). Then, the lookup will succeed iff there is a hash collision between x and y, which is presumably not desired behavior. (In fact, I think this will always happen for = Integers and Longs due to the way their hashCodes are defined, but for, e.g., Doubles and Integers it may only happen at a single number (if at all).) -Jason [1] http://groups.google.com/group/clojure/browse_thread/thread/5d11bc0da25a7ecc/06d6cd888a516119?hl=en&lnk=gst&q=.hashcode#06d6cd888a516119 [2] http://code.google.com/p/clojure/issues/detail?id=37&colspec=ID%20Type%20Status%20Priority%20Reporter%20Owner%20Summary --~--~-~--~~~---~--~~ 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: Suggested functions for core: any? none?
On Jan 14, 12:01 am, GS wrote: > On Jan 14, 2:27 pm, "Mark Engelberg" wrote: > > > I also find the choice of some/not-any? as opposites to be hard to > > remember. I'd rather it be some/not-some? or any/not-any? > > I think some and any? both have their place. > > (let [foo (some prime? numseq)] > (do something with foo)) > > (if (any? composite? numseq) > ; we haven't finished factorising > > That is hastily made-up pseudocode, of course. The point it: 'any? > looks like a predicate, as it should. 'some doesn't, so it's a > nuisance when it is used as a predicate. > > Personally, I'd prefer 'some be called 'find or 'find-first, but I'm > not arguing in favour of that; that's simply a preference. > > Gavin +1 I think some consistency is in order. This would both: a) Help beginners find the duality of a given function more easily, and b) Make the code read better, IMHO. -Ryan --~--~-~--~~~---~--~~ 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: when performance matters
On Jan 15, 3:38 am, "Mark H." wrote: > On Jan 14, 8:27 am, Asbjørn Bjørnstad wrote: > > > Anyway, here is a core part of the algorithm. It's a diffusion > > step, this gets called 3 times and in total this takes up more than > > one second of cpu time on my machine which makes framerates very > > slow. If anyone got any improvements I'd be happy to hear about it: > > Here are a few possibilities: > > 1. Java 2-D, 3-D, etc. arrays are implemented as arrays of (arrays > of ... pointers), which hurts spatial locality. It was enough of a > problem that I've seen people reimplement 2-D arrays using 1-D > arrays. You might consider using a 1-D array and taking the trouble > to do the indexing by hand. Of course only a benchmark can tell > whether it really helps. Look closer, I'm using a 1-D array and indexing by hand :-) > 3. I noticed you are doing 20 iterations of Gauss-Seidel. There are > some smart ways to speed up multiple stencil applications. I can > point you to references if you are interested. That would be cool. Although, I just copied someone elses algorithm, and I think he knew what he were doing so it may be hard to improve on it. (Apart from the unchecked- functions pointed out by Chouser and Rich.) -- -asbjxrn --~--~-~--~~~---~--~~ 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: when performance matters
On Jan 15, 8:42 am, "Mark H." wrote: > On Jan 14, 12:29 pm, chris wrote: > > > For a completely different way of doing this, you could certainly use > > GPGPU programming to speed this up. > > ... > > You want this for a game engine anyway; do it in opengl or directx > > using shaders. > > I recommend OpenCL or CUDA instead for less pain ;-) (Well, maybe not > for you -- I tried doing stuff with OpenGL and some language called CG > in 2006 and it was a world of pain.) > > What's the target frame rate? For me, fast enough that the smoke looks smokey :) I'm just playing around, saw this article about "fluid dynamics for games" and thought it looked fun to try to implement in clojure. There is no planned project that this needs to fit into. OpenCL/CUDA might be a next step to see what the performance improvement would be, but right now I just want to see if it could be done in pure clojure. -- -asbjxrn --~--~-~--~~~---~--~~ 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: when performance matters
On Jan 13, 8:04 am, Mark P wrote: > > A macro cannot depend on runtime information. A macro is a function > > that is called at compile time, its argument is an expression (as > > written by the programmer, or as returned by another macro), and its > > result is a modified expression. There is no way a macro could access > > runtime information. It is a program that works on program code, not > > on runtime data. > > Then what do people mean when they say that lisp blurs > the distinction between compile-time and run-time? I > thought that "macros executing at runtime" was part > of this. But if not, I don't know what they do mean. > > I thought macros could get executed at runtime as > follows. Suppose I have a domain-specific-language > implemented in a lisp, using macros. Suppose at > runtime some of this domain-specific-code gets > generated somehow (code is data at this point). > An "eval" is executed on this domain-specific-code, > which causes the macros (used to implement the > domain-specific-language) to transform the input > code at runtime. > > Is this wrong? > > I also thought that when a "clojure application" is > bundled up as java bytecode, this "executable" > actually includes the clojure compiler. Why would > this be included if compilation (including macros) > is never performed at runtime? > > Is there something fundamental I am not > understanding? > > Thanks, > > Mark P. I realize this thread has long since changed gears, but you may find your answer in Chapter 8 of Practical Common Lisp (http:// www.gigamonkeys.com/book/). Look for the section titled 'Macro Expansion vs. Runtime". Basically, it's like Konrad said, macros are executed at 'macro expansion time' which is during the compilation phase. However, Peter Seibel does mention that when interpreted (vs compiled) the line between macro expansion time and runtime becomes kind of fuzzy because they become intertwined. He mentions that it is not explicitly defined when an interpreter must expand macro's. It could expand all the macros up front, or do it lazily as it comes across them, but that doesn't change the fact that they must be expanded first so that the actual runtime code can be produced and executed. Hope this helps. -Ryan --~--~-~--~~~---~--~~ 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: when performance matters
On Jan 15, 4:33 am, Rich Hickey wrote: > Try this (and make sure you are using -server): > > (defn diffuse [grid diff-ratio dt] > (let [a (float (* dt diff-ratio grid-size grid-size)) > a4-1 (float (+ 1 (* 4 a))) > grid #^floats (deref grid) > diffused-grid #^floats (make-grid) > grid-size (int grid-size) > line-length (int (+ grid-size 2))] > (dotimes [n 20] > (dotimes [y grid-size] > (let [line-offset (* (inc y) line-length)] > (loop [x (int 1) > c (int (+ x line-offset))] > (aset diffused-grid c > (/ (+ (aget grid c) > (* a > (+ (+ (aget diffused-grid > (unchecked-dec c)) > (aget diffused-grid > (unchecked-inc c))) > (+ (aget diffused-grid > (unchecked-subtract c line-length)) > (aget diffused-grid > (unchecked-add c line-length)) > a4-1)) > (when (< x grid-size) > (recur (unchecked-inc x) > (unchecked-inc c))) > diffused-grid)) > > (time (diffuse foo 0.00025 0.002)) > "Elapsed time: 25.588 msecs" Your computer is faster than mine.:) I got to check when I get back home tonight, but I think this might be fast enough once I use this technique in all the array manipulation functions. I got about a 4x speedup in my quick tests. Thanks. -- -asbjxrn --~--~-~--~~~---~--~~ 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: Why aren't lists callable?
Makes sense, but (#{:a :b :c} :b) doesn't return 'true', it returns :b. So it's not really acting like an object to boolean mapping. Doesn't much matter, though. By the way, I'd like to see map-map in the core. -Ethan On Jan 12, 5:30 pm, Stuart Sierra wrote: > A set is, in a sense, a function mapping from arbitrary objects to > Boolean values. If the object is in the set, it returns true. A list, > in the Lisp world at least, only has two elements, first and rest (car > and cdr in older Lisps). A list object isn't really a "complete" > collection the way vectors and maps are. There isn't a good way to > conceptualize that as a function. > > I've probably just made this more confusing, but that's the best I > could come up with. > > -Stuart Sierra > > On Jan 12, 6:51 pm, Ethan Herdrick wrote: > > > Then why are sets callable? Not that I'm complaining - I found it > > handy, then came to wonder why lists aren't. > > > -Ethan > > > > I'd just like to add to this discussion that maps and vectors are > > > functions not just because it's neat or possible, with the > > > implementation one of many possibilities, but because they are > > > associative, and associative collections are inherently functions of > > > their keys/indices. > > > > Lists/seqs are not associative, thus not functions. > > > > 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: Utilities for clojure.contrib?
On Wed, Jan 14, 2009 at 4:03 PM, Jason Wolfe wrote: > > To keep this manageable, I'll cut out the parts where I don't think > comments are needed. Good idea! >> > (defn concat-elts "Lazily concatenate elements of a seq of seqs." [s] >> > (when (seq s) (lazy-cat (first s) (concat-elts (rest s) >> >> > (defn lazy-mapcat "Like mapcat but is lazy like map" [f s] >> > (concat-elts (map f s))) > > Yes. I would be happy to drop concat-elts and lazy-mapcat, if the > built-in concat (which seems to be used by mapcat) was changed to be > less eager (in the apply sense just mentioned above). > > user> (take 0 (apply concat (report-seq "" [[1] [2] [3] [4] [5]]))) > (first [1] ) > (rest after [1] ) > (first [2] ) > (rest after [2] ) > (first [3] ) > (rest after [3] ) > nil > > This can end up being a real drag in situations like (apply concat > (map #(recurive-call ...) ...)), since it may result in an exponential > amount of extra work being done. Any chance of this being changed? > (It should be possible to get rid of the last 4 evaluations here, > without getting into the territory of our last conversation about > laziness :)) I don't see why the built-in concat couldn't be defined like yours. >> > (defn chunk "Lazily break s into chunks of length n (or less, for the >> > final chunk)." >> > [n s] >> > (when (seq s) >> >(lazy-cons (take n s) >> > (chunk n (drop n s) >> >> This is so close to 'partition', that I think I'd prefer there be only >> one, or at least have related names. > > OK, I agree the name should be closer to partition (which I'd > forgotten about), but I think this one is at least as useful as > partition (You can recover partition from this one by (take-when #(= > (count %) n) (chunk n s))) but not vice-versa.) Any suggestions on a > name? Perhaps 'partition-all' ? I'd vote to have this in contrib. >> (defn my-mevery? [f & seqs] >> (every? identity (apply map f seqs))) > > Yes, I believe so ... that's a much nicer way of writing it. > >> Someone suggested all the functions that currently take a predicate >> and one seq ought to take multiple seqs and work like 'map'. I >> suppose this would include: every? any? some etc. Seems pretty >> convenient, and I've not heard arguments against it. But without >> that, I think I'd rather use 'identity' and 'apply map' than have an >> m-version of all the seq functions. > > Yes, I would of course prefer that the built-in versions take multiple > seqs and work like map. > If not, I guess I agree with you that it's better not to create m- > versions of everything. These could be changed to act like 'my-mevery?' above. Is this a complete list? --> every? not-every? some not-any? I believe functions that return the values from the input seq are NOT candidates for this? That includes: filter remove take-while drop-while split-with Instead the first three might suggest corollaries: map-when map-when-not map-while >> I think I'd rather this be a feature of the map itself, rather than >> depend on each 'get' to be a 'safe-get'. Perhaps if 'get' finds >> nothing and no default value is given, it could check the map's >> metadata for a :default-value or :throw-unless-found item. > > I think I'd be equally happy with "safe maps" as you suggest as using > safe-get. But, one or the other is definitely useful ... I've been > bitten several times by misspelled keys, which can create difficult-to- > find bugs. I know people have asked previously for maps that know their own default value. I suppose the metadata could be supplied directly: #^{:default "not found"} (hash-map :a 1, :b 2) That's a bit ugly, but you could use it on {} literals. Otherwise I guess you'd need extra constructors. (hash-map-default "not found" :a 1, :b 2) (sorted-map-throw :a 1, :b 2) (safe-array-map :a 1, :b 2) Hm. Is it worth it? Any naming ideas? >> > (defn merge-agree "Like merge but returns nil if there are >> > inconsistent key/value pairs." >> > ([] {}) >> > ([map] map) >> > ([m1 m2 & maps] >> > (when (every? (fn [[k v]] (= v (get m1 k v))) m2) >> > (apply merge-agree (merge m1 m2) maps >> >> Maybe if it accepted the = function as a arg (like merge-with) it >> would be a little more general? > > Well, then which value would you use (if two values are my-equal but > not =)? Oh. Good point. I guess I was thinking it would be like 'merge-with', but if the conflict resolution function returned nil or false, you'd get back a nil instead of a map. > With merge-with, I think I would have to say > (apply merge-with + accounts (map (fn [[k v]] (hash-map k v)) (concat > deposits withdrawls))) > > which is considerably uglier and less clear IMO. Any chance of > changing merge-with in this way? Yes, it would just require replacing a use of 'key' and 'value' with 'first' and 'second' in the definition of 'merge-with'. I can't think of a good reason not to do this. --Chouser --~--~-~--~~---
Re: Why aren't lists callable?
On Wed, Jan 14, 2009 at 10:23 PM, Ethan Herdrick wrote: > > By the way, I'd like to see map-map in the core. If you're referring to Jason Wolfe's suggested function, I think you may be pretty satisfied with (into {} (map ...)) instead. --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 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.contrib.command-line patch: multiple option format
A thought: if you end up using the patch, I gave the 'justify' function an inappropriate name. It should be 'align' or 'align-cols' or some such. (No one in their right mind would justify text on the console!) Perry On Jan 14, 3:16 pm, Perry Trolard wrote: > Hi Chouser, > > Thanks for checking out the patch. > > > It's a good idea. Any sane way to allow the single-letter variety to > > be specified with a single leading dash, instead of a double-dash? > > Single or double dashes should work for both kinds of options (long- > or short-style), based on your code. The regex that looks for option > syntax is > > (re-find #"^--?(.*)" argkey) > > (optional second dash). Are you seeing it not work this way? > > Maybe you're referring to the printed help, with the "--(option|o)" > listing. I agree that it isn't that cool. Maybe dashes don't need to > be printed next to the options at all, perhaps with a short message > about single or doubles working (though that's a little clunky, > too)? > > > 'justify' is interesting. I wonder if a CL-style 'format' will end up > > in clojure-contrib after all. > > Yeah, I couldn't bear to do it w/o a bit of justification, even if > it's a little out of place in this lib (& if 'justify' isn't really > complete -- a centered option would be pretty easy to add). As for the > full CL format, it looks like Tom Faulhaber is pretty far along at > > http://github.com/tomfaulhaber/cl-format/ > > but I'm not familiar with it myself. > > Best, > Perry --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
test-is: set! *e
Here's a trivial patch that I've found useful. After catching an uncaught exception in a test, set! *e so you can examine the stack trace afterward. === --- src/clojure/contrib/test_is.clj (revision 314) +++ src/clojure/contrib/test_is.clj (working copy) @@ -233,7 +289,8 @@ (try (t) (catch Throwable e (report :error "Uncaught exception, not in assertion." - nil e)) + nil e) + (set! *e e)) --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---