Re: when performance matters
On 13.01.2009, at 19:07, cliffc wrote: > 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 I have to admit that I haven't done many tests, but for those I did I found little to no difference, provided the tests have sufficiently long run times. However, what remains a problem for with the Java/HotSpot approach to performance is the absence of a clear (even though necessarily approximate) performance model. When writing C or C++ code, I have some idea of the approximate cost of everything. Of course there are differences between machines and compilers, but those rarely cause drastic differences in performance, rarely more than a factor of 2. On the JVM, I don't know what HotSpot can optimize and what it can't, and I can't predict the impact of object allocation and garbage collection. I suppose JVM experts can do better than me, but where can I learn about all that? Konrad. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: configurable bash script to launch Clojure available
+1 (and a windows .bat file for the unwashed) I strongly suggest that the script name needs to be retained in *command-line-args*. ie: clj myscript.clj 1 2 *command-line-args* should be ("myscript.clj" 1 2) not (1 2) which is the current behavior of your script with the current clojure.main $0 or argv[0] is really useful and widely expected to exist. I suppose this could be overcome by $1 $@, however that is not quite correct in the case where the user might pass in additional options clj --some-option myscript.clj 1 2 so I believe clojure.main itself needs modification to be correct. Is clojure.main deprecating clojure.lang.Script? I suppose that http://clojure.org/repl_and_main will explain all when revealed :) --~--~-~--~~~---~--~~ 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: Synchronization Benchmarks
Another thing you might want to test is the fairness of the rw-lock in your RWDict, because even a couple of very active readers can easily starve out any number of writers when the rw-lock is non-fair. The reason is simple: readers can interleave but writers cannot, and writers can only get in when noone is reading :) On Fri, Jan 16, 2009 at 4:21 AM, Stu Hood wrote: >> Ah! but a mere hash table is not bi-directional :-) > Right =) I got the idea in a Channel 9 video about MS' efforts with STM: > http://channel9.msdn.com/shows/Going+Deep/Software-Transactional-Memory-The-Current-State-of-the-Art/ > (which reminds me, the spin-lock approach they try is probably fairly close > to using an Atom in Clojure). > > I made the changes that Christophe suggested, and added type hints for the > HashMaps used in CLJDict, and the speed improvement is very impressive. To > see the scalability of the different approaches, I graphed with various > numbers of threads and read percentages: > http://github.com/stuhood/clojure-conc/tree/master/results > > Two conclusions: > 1. The overhead for STM with low contention is very reasonable, > 2. Optimism + MVCC + persistence fall down when faced with a majority of > writes. (see the 100% write case in the writes graph.) > > Thanks, > Stu > > > On Thu, Jan 15, 2009 at 2:52 PM, Christian Vest Hansen > wrote: >> >> On Thu, Jan 15, 2009 at 8:47 PM, Christian Vest Hansen >> wrote: >> > On Thu, Jan 15, 2009 at 8:35 PM, Mark H. wrote: >> >> On Jan 15, 1:38 am, stuhood wrote: >> >>> The benchmark contains 4 bi-directional dictionary implementations: >> ... >> >> >> >> Doesn't Java already have a more optimized thread-safe hash table that >> >> works by locking individual buckets, rather than the whole table? >> >> Maybe I'm just confused ;-P >> >> Ah! but a mere hash table is not bi-directional :-) >> >> >> -- >> Venlig hilsen / Kind regards, >> Christian Vest Hansen. >> >> > > > > > -- 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: Mysterious performance anomalies
Here's my theory. In your when example, "when" is a macro that is expanded to an "if" special form. Your other examples, however, wrap your code in a function call. Now, functions in Clojure can't really take primitive arguments, so in spite of your coercion efforts Clojure introduces boxing in your loop and this is what slows you down. A work-around is to either use a (def variable ...) or something like this: (let [x (time (loop [i (int 0)] (if (< i (int 3000)) (recur (inc i)) i)))] (prn x)) How does that sound? On Fri, Jan 16, 2009 at 5:43 AM, Jason Wolfe wrote: > > I was doing some microbenchmarking earlier, and I noticed some very > very weird anomalies. If anyone could shed some light on what's > going on that would be awesome. (I'm using the latest SVN, and have > verified this on a totally clean repl). > > Simplified as much as possible, the heart of what I observed is: > > user> (prn (time (loop [i (int 0)] (if (< i (int 3000)) (recur > (inc i)) i > "Elapsed time: 4247.477 msecs" > 3000 > nil > > user> (time (loop [i (int 0)] (if (< i (int 3000)) (recur (inc i)) > i))) > "Elapsed time: 128.37 msecs" > 3000 > > Weird, right? The prn is *outside* the loop, and yet it still affects > the timing somehow. Maybe this is something specific to printing? > Nope: > > user> (first (time (loop [i (int 0)] (if (< i (int 3000)) (recur > (inc i)) [i] > "Elapsed time: 4264.847 msecs" > 3000 > > user> (time (loop [i (int 0)] (if (< i (int 3000)) (recur (inc i)) > [i]))) > "Elapsed time: 130.099 msecs" > [3000] > > But, some other expressions around the "time" don't affect it in the > same way: > > user> (when (time (loop [i (int 0)] (if (< i (int 3000)) (recur > (inc i)) [i]))) 12) > "Elapsed time: 130.236 msecs" > 12 > > In case you were wondering, this has nothing to do with the "time" > macro. > > user> (first (loop [i (int 0)] (if (< i (int 3000)) (recur (inc > i)) [i]))) > ; ... 4 seconds pass on my stopwatch ... > 3000 > > And the slowness is by a multiplicative, not additive factor: > > user> (first (time (loop [i (int 0)] (if (< i (int 6000)) (recur > (inc i)) [i] > "Elapsed time: 8576.649 msecs" > 6000 > > user> (time (loop [i (int 0)] (if (< i (int 6000)) (recur (inc i)) > [i]))) > "Elapsed time: 250.407 msecs" > [6000] > > I'm at a total loss for what's going on. Anyway, I'll stop here for > now in case I'm missing something stupid or obvious. > > Thanks for your help! > Jason > > > > -- 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: Newbie question on *agent* here
> My question is how the first agent (agent nil) and *agent* used > later in another nestedsend-offrelated? Agents execute their function with *agent* bound to themselves, so the example given chains itself. This is necessary because the function is only passed in the value of the agent, not the agent itself. So the first send-off is sent to (agent nil), and when the function is called that agent send-offs itself. > Also m after (fn is a function name so that it can be referred to > later inside the same function? yup --~--~-~--~~~---~--~~ 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) running clojure app without repl
Thanks for the answers. I'm very excited about Clojure, it seems to have all the features I was missing from Java and Ruby. --~--~-~--~~~---~--~~ 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: configurable bash script to launch Clojure available
On Jan 16, 9:06 am, Timothy Pratley wrote: > +1 (and a windows .bat file for the unwashed) + 1 too. > I strongly suggest that the script name needs to be retained in > *command-line-args*. > ie: clj myscript.clj 1 2 No, please don't, or it would not be coherent with the way java handles it. Maybe for scripts a global var such as *script-name* could be set automatically ? > *command-line-args* should be ("myscript.clj" 1 2) > not (1 2) which is the current behavior of your script with the > current clojure.main > $0 or argv[0] is really useful and widely expected to exist. > > I suppose this could be overcome by $1 $@, however that is not quite > correct in the case where the user might pass in additional options > clj --some-option myscript.clj 1 2 > so I believe clojure.main itself needs modification to be correct. > > Is clojure.main deprecating clojure.lang.Script? I suppose > thathttp://clojure.org/repl_and_mainwill explain all when revealed :) --~--~-~--~~~---~--~~ 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: test-is reporting problem
S. Sierra, Here is a good test case. It would be nice if the Java interop form worked, without having to be wrapped in an anonymous function. user=> (use 'clojure.contrib.test-is) nil user=> (.startsWith "abc" "a") true user=> (is (.startsWith "abc" "a")) java.lang.Exception: Unable to resolve symbol: .startsWith in this context (NO_SOURCE_FILE:3) user=> (#(.startsWith % "a") "abc") true user=> (is (#(.startsWith % "a") "abc")) true S. Halloway > I was afraid that would happen. I'll fix it, probably tomorrow. > -the other Stuart > > On Jan 15, 6:27 pm, Stuart Halloway wrote: >> The improved error reposting in test-is breaks some tests, e.g. from >> the book: >> >> (deftest test-lazy-index-of-any-with-match >> (is (with-out-str (is (zero? (index-of-any "zzabyycdxx" #{\z >> \a} >> "Iterating overz\n") >> (is (with-out-str (is (= 3 (index-of-any "zzabyycdxx" #{\b \y} >> "Iterating overz\nIterating over z\nIterating over a\n")) >> >> The problem is that it tries to take the value of with-out-str, not >> realizing that it is a macro. >> >> Should I >> >> (1) rewrite the test to not use a macro? >> (2) take a stab at fixing this in test-is? >> (3) get out of the way and let another Stuart handle it? :-) >> >> Stuart > > --~--~-~--~~~---~--~~ 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: Macros in interaction with Functions
I second the vote for _On Lisp_. I have ported the examples to Clojure: http://blog.thinkrelevance.com/2008/12/12/on-lisp-clojure Stuart >> When I found that out, I was surprised. My knowledge of lisp comes >> from reading, in the past few months: >> - ANSI Common Lisp >> - Practical Common Lisp >> and, some years ago, a few more things. > > The best book to read about macros is in my opinion Paul Graham's "On > Lisp", which is now available for free download: > > http://www.paulgraham.com/onlisp.html > > It covers mostly Common Lisp plus a bit of Scheme, but many of the > ideas carry over very well to Clojure. --~--~-~--~~~---~--~~ 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
> There are two pools of threads servicing agent actions. The send pool > is fixed in size and based on the number of available cores. The send- > off pool is variable in size and grows as needed to accommodate the > largest number of simultaneous pending send-off calls that your > program produces. > > If you use send-off when you could have used send, your send-off > thread pool may grow larger than it needed to grow. > > If you use send when you should have used send-off, other actions sent > to other agents may be delayed. Where the expected to run very soon, > they may now have to wait behind a blocking operation which could > easily increase the wait time from tens of microseconds or less to > tens of milliseconds or more--a huge factor. I think that quote verbatim should be added to http://clojure.org/agents Well said :) Back to Boris' problem though... I am now in front of a dual core laptop and able to reproduce his strange result under a number of different circumstances, which really puzzles me. Even more confusing is when I tried a function using loop: (defn fac3 [n] (loop [cnt n acc 1] (if (zero? cnt) acc (recur (dec cnt) (* acc cnt) threads: 1 "Elapsed time: 1880.83262 msecs" "Elapsed time: 2238.489249 msecs" "Elapsed time: 1716.185717 msecs" threads: 2 "Elapsed time: 2261.544134 msecs" "Elapsed time: 2244.013415 msecs" "Elapsed time: 1441.044881 msecs" threads: 3 "Elapsed time: 3469.122751 msecs" "Elapsed time: 2681.029014 msecs" "Elapsed time: 2122.677044 msecs" Now I have 2 CPUs, the 1st line is the loopmult... it goes up by about 15% when going from 1 thread to 2... I would expect it to remain constant. The 2nd test is loopfib... it remains constant from 1 thread to 2, and goes up by only %15 for 3 threads... I would expect it to go up by %50 The 3rd test is loopfac3... (the loop) it actually finishes about 15% earlier with 2 threads?? remember it is doing twice the work - that should be impossible). With 3 threads it is only 15% slower than 1. Can anyone else come up with a theory? I've uploaded my horribly bastardized version of Boris' original code at http://groups.google.com/group/clojure/web/mt2.clj I put lots of stinky stuff in there fiddling with different ways of calling the same scenario to try to explain it to myself and well they all behaved as described. 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: configurable bash script to launch Clojure available
On Jan 16, 2009, at 7:31 AM, lpetit wrote: Maybe for scripts a global var such as *script-name* could be set automatically ? I like this. I've also seen several requests for a way to know when code is running in a script which could be satisfied by this as well. This would be an easy change to clojure.main. I can make a patch. Rich, will you accept this as an issue? --Steve smime.p7s Description: S/MIME cryptographic signature
Re: question about understanding/exploring agents
> goes up by only %15 for 3 threads... I would expect it to go up by %50 Actually I would expect it to go up by %100 t1t2 t1 --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Programming Clojure sample code: fixes for breaking changes
Long, long ago (Tuesday) when Beta 5 of the book shipped, there were some breakages in the sample code due to changes in clojure-contrib. I believe everything is now fixed in the github repository (http://github.com/stuarthalloway/programming-clojure ). Summary of the issues: 1. clojure.contrib.seq-util/includes? changed the argument order for consistency with other operations. This caused problems with the snippet web app; Compojure is now updated to match the change in contrib. 2. clojure.contrib.sql/with-results has been removed and replaced with with-query-results. This broke the snippet model. The code is now fixed and I will update the prose in the next Beta. 3. A change to clojure.lang.Util necessitated a _clean_ rebuild of contrib and compojure. I have rebuild these dependencies in the lib directory. 4. A change to clojure.contrib.test-is.is broke a few unit tests. The book doesn't reference any of these tests directly, but they are now fixed in the code. You can run the whole test suite with ./runtests.sh. Let me know if you find any other issues! Thanks, Stuart --~--~-~--~~~---~--~~ 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: Mysterious performance anomalies
On Jan 16, 5:15 am, Christian Vest Hansen wrote: > Here's my theory. > > In your when example, "when" is a macro that is expanded to an "if" > special form. Your other examples, however, wrap your code in a > function call. > > Now, functions in Clojure can't really take primitive arguments, so in > spite of your coercion efforts Clojure introduces boxing in your loop > and this is what slows you down. > > A work-around is to either use a (def variable ...) or something like this: > > (let [x (time (loop [i (int 0)] (if (< i (int 3000)) (recur (inc > i)) i)))] (prn x)) > > How does that sound? > > > > On Fri, Jan 16, 2009 at 5:43 AM, Jason Wolfe wrote: > > > I was doing some microbenchmarking earlier, and I noticed some very > > very weird anomalies. If anyone could shed some light on what's > > going on that would be awesome. (I'm using the latest SVN, and have > > verified this on a totally clean repl). > > > Simplified as much as possible, the heart of what I observed is: > > > user> (prn (time (loop [i (int 0)] (if (< i (int 3000)) (recur > > (inc i)) i > > "Elapsed time: 4247.477 msecs" > > 3000 > > nil > > > user> (time (loop [i (int 0)] (if (< i (int 3000)) (recur (inc i)) > > i))) > > "Elapsed time: 128.37 msecs" > > 3000 > > > Weird, right? The prn is *outside* the loop, and yet it still affects > > the timing somehow. Maybe this is something specific to printing? > > Nope: > > > user> (first (time (loop [i (int 0)] (if (< i (int 3000)) (recur > > (inc i)) [i] > > "Elapsed time: 4264.847 msecs" > > 3000 > > > user> (time (loop [i (int 0)] (if (< i (int 3000)) (recur (inc i)) > > [i]))) > > "Elapsed time: 130.099 msecs" > > [3000] > > > But, some other expressions around the "time" don't affect it in the > > same way: > > > user> (when (time (loop [i (int 0)] (if (< i (int 3000)) (recur > > (inc i)) [i]))) 12) > > "Elapsed time: 130.236 msecs" > > 12 > > > In case you were wondering, this has nothing to do with the "time" > > macro. > > > user> (first (loop [i (int 0)] (if (< i (int 3000)) (recur (inc > > i)) [i]))) > > ; ... 4 seconds pass on my stopwatch ... > > 3000 > > > And the slowness is by a multiplicative, not additive factor: > > > user> (first (time (loop [i (int 0)] (if (< i (int 6000)) (recur > > (inc i)) [i] > > "Elapsed time: 8576.649 msecs" > > 6000 > > > user> (time (loop [i (int 0)] (if (< i (int 6000)) (recur (inc i)) > > [i]))) > > "Elapsed time: 250.407 msecs" > > [6000] > > > I'm at a total loss for what's going on. Anyway, I'll stop here for > > now in case I'm missing something stupid or obvious. > > > Thanks for your help! > > Jason > The bytecode produced for the loop is exactly the same in both cases. It seems the presence of first (or really anything) on the stack during looping causes HotSpot to bail on optimizing. This is a case where the bytecode is unlike any produced by javac (in Java, loops cannot be expressions). For now, I've made it so that when a loop occurs as an expression it is lifted out into a fn, and the performance is identical. SVN 1216 - thanks for the report. Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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 a hunch I rearranged such that the agents are not recreated for each run, but instead are reused from a pre-established set: http://groups.google.com/group/clojure/web/mt2.2.clj Strangely (from my understanding of agents) this has a significant impact on the result!!! threads: 1 "Elapsed time: 1447.388146 msecs" "Elapsed time: 117.655457 msecs" "Elapsed time: 247.283942 msecs" threads: 2 "Elapsed time: 2064.69705 msecs" "Elapsed time: 630.112486 msecs" "Elapsed time: 396.592304 msecs" threads: 3 "Elapsed time: 3026.769883 msecs" "Elapsed time: 1188.845789 msecs" "Elapsed time: 634.070252 msecs" threads: 4 "Elapsed time: 4240.550405 msecs" "Elapsed time: 2421.342098 msecs" "Elapsed time: 980.957356 msecs" Note all the tests are scaling up and the second two tests are dramatically faster. o_O --~--~-~--~~~---~--~~ 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
Sorry for the quad-post, but I just noticed: http://groups.google.com/group/clojure/browse_thread/thread/6ac273446b4a7183 And actually that is what made the big difference in performance (I'd done a svn update for something unrelated). So I guess two mysteries solved with one patch! Boris I suggest you try to re-run your test on your quad-core with the latest SVN, as I don't think my laptop is really representative. On Jan 17, 1:20 am, Timothy Pratley wrote: > On a hunch I rearranged such that the agents are not recreated for > each run, but instead are reused from a pre-established > set:http://groups.google.com/group/clojure/web/mt2.2.clj > > Strangely (from my understanding of agents) this has a significant > impact on the result!!! > > threads: 1 > "Elapsed time: 1447.388146 msecs" > "Elapsed time: 117.655457 msecs" > "Elapsed time: 247.283942 msecs" > threads: 2 > "Elapsed time: 2064.69705 msecs" > "Elapsed time: 630.112486 msecs" > "Elapsed time: 396.592304 msecs" > threads: 3 > "Elapsed time: 3026.769883 msecs" > "Elapsed time: 1188.845789 msecs" > "Elapsed time: 634.070252 msecs" > threads: 4 > "Elapsed time: 4240.550405 msecs" > "Elapsed time: 2421.342098 msecs" > "Elapsed time: 980.957356 msecs" > > Note all the tests are scaling up and the second two tests are > dramatically faster. > o_O --~--~-~--~~~---~--~~ 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
> So I guess two mysteries solved with one patch! Actually I spoke too soon... the mt2.clj is still giving the 'unexpected' behavior... I am still mystified. But going to bed now :) --~--~-~--~~~---~--~~ 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: Mysterious performance anomalies
This is probably a silly question, well outside the scope of this conversation (but maybe not, and I didn't want to start a whole thread on it). Is it much much easier to make byte code than assembly code? I mean, I understand why running on a VM makes sense as far as instantly inheriting all the massive amounts of things out here for Java but would it be possible to shoot for something down the road that, behind the scenes, uses jvm whenever you say, "import" . . .and writes and compiles assembler whenever you are doing purely algorithmic things? In a way, I guess what I'm saying is that this was a fix that helped the hotspot compiler along. But (and I'm TOTALLY ignorant about all of this so maybe I should do more reading before asking the question) that technology is a moving target and varies from one VM to another. It's sort of analogous to the discussion on why the Jython approach is problematic because it's got to stay in sync with Python. Is this a silly question? Thanks. On Fri, Jan 16, 2009 at 8:59 AM, Rich Hickey wrote: > > > > On Jan 16, 5:15 am, Christian Vest Hansen > wrote: > > Here's my theory. > > > > In your when example, "when" is a macro that is expanded to an "if" > > special form. Your other examples, however, wrap your code in a > > function call. > > > > Now, functions in Clojure can't really take primitive arguments, so in > > spite of your coercion efforts Clojure introduces boxing in your loop > > and this is what slows you down. > > > > A work-around is to either use a (def variable ...) or something like > this: > > > > (let [x (time (loop [i (int 0)] (if (< i (int 3000)) (recur (inc > > i)) i)))] (prn x)) > > > > How does that sound? > > > > > > > > On Fri, Jan 16, 2009 at 5:43 AM, Jason Wolfe > wrote: > > > > > I was doing some microbenchmarking earlier, and I noticed some very > > > very weird anomalies. If anyone could shed some light on what's > > > going on that would be awesome. (I'm using the latest SVN, and have > > > verified this on a totally clean repl). > > > > > Simplified as much as possible, the heart of what I observed is: > > > > > user> (prn (time (loop [i (int 0)] (if (< i (int 3000)) (recur > > > (inc i)) i > > > "Elapsed time: 4247.477 msecs" > > > 3000 > > > nil > > > > > user> (time (loop [i (int 0)] (if (< i (int 3000)) (recur (inc i)) > > > i))) > > > "Elapsed time: 128.37 msecs" > > > 3000 > > > > > Weird, right? The prn is *outside* the loop, and yet it still affects > > > the timing somehow. Maybe this is something specific to printing? > > > Nope: > > > > > user> (first (time (loop [i (int 0)] (if (< i (int 3000)) (recur > > > (inc i)) [i] > > > "Elapsed time: 4264.847 msecs" > > > 3000 > > > > > user> (time (loop [i (int 0)] (if (< i (int 3000)) (recur (inc i)) > > > [i]))) > > > "Elapsed time: 130.099 msecs" > > > [3000] > > > > > But, some other expressions around the "time" don't affect it in the > > > same way: > > > > > user> (when (time (loop [i (int 0)] (if (< i (int 3000)) (recur > > > (inc i)) [i]))) 12) > > > "Elapsed time: 130.236 msecs" > > > 12 > > > > > In case you were wondering, this has nothing to do with the "time" > > > macro. > > > > > user> (first (loop [i (int 0)] (if (< i (int 3000)) (recur (inc > > > i)) [i]))) > > > ; ... 4 seconds pass on my stopwatch ... > > > 3000 > > > > > And the slowness is by a multiplicative, not additive factor: > > > > > user> (first (time (loop [i (int 0)] (if (< i (int 6000)) (recur > > > (inc i)) [i] > > > "Elapsed time: 8576.649 msecs" > > > 6000 > > > > > user> (time (loop [i (int 0)] (if (< i (int 6000)) (recur (inc i)) > > > [i]))) > > > "Elapsed time: 250.407 msecs" > > > [6000] > > > > > I'm at a total loss for what's going on. Anyway, I'll stop here for > > > now in case I'm missing something stupid or obvious. > > > > > Thanks for your help! > > > Jason > > > > The bytecode produced for the loop is exactly the same in both cases. > It seems the presence of first (or really anything) on the stack > during looping causes HotSpot to bail on optimizing. This is a case > where the bytecode is unlike any produced by javac (in Java, loops > cannot be expressions). > > For now, I've made it so that when a loop occurs as an expression it > is lifted out into a fn, and the performance is identical. > > SVN 1216 - thanks for the report. > > Rich > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Programming Clojure sample code: fixes for breaking changes
I keep running into the following problem trying to supply agent validation function. Here is sample code from page 135 (from book version beta 5) (use '[clojure.contrib.except :only (throw-if)]) (def counter (agent 0 #(throw-if (not (number? %)) "not a number"))) triggers the following exception: java.lang.IllegalArgumentException: No value supplied for key: user $fn__1...@89f302 (NO_SOURCE_FILE:2) [Thrown class clojure.lang.Compiler$CompilerException] I’m using the latest versions of clojure (r1216) and clojure-contrib (r374) on Mac OS X 10.5.6, Java version "1.5.0_16" Many thanks, Telman On Jan 16, 8:49 am, Stuart Halloway wrote: > Long, long ago (Tuesday) when Beta 5 of the book shipped, there were > some breakages in the sample code due to changes in clojure-contrib. I > believe everything is now fixed in the github repository > (http://github.com/stuarthalloway/programming-clojure > ). > > Summary of the issues: > > 1. clojure.contrib.seq-util/includes? changed the argument order for > consistency with other operations. This caused problems with the > snippet web app; Compojure is now updated to match the change in > contrib. > > 2. clojure.contrib.sql/with-results has been removed and replaced with > with-query-results. This broke the snippet model. The code is now > fixed and I will update the prose in the next Beta. > > 3. A change to clojure.lang.Util necessitated a _clean_ rebuild of > contrib and compojure. I have rebuild these dependencies in the lib > directory. > > 4. A change to clojure.contrib.test-is.is broke a few unit tests. The > book doesn't reference any of these tests directly, but they are now > fixed in the code. You can run the whole test suite with ./runtests.sh. > > Let me know if you find any other issues! > > Thanks, > Stuart --~--~-~--~~~---~--~~ 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: Programming Clojure sample code: fixes for breaking changes
Hi Telman, The signature for agent has changed. Use: (def counter (agent 0 :validator number?)) I will update the prose in Beta 6. Stuart > I keep running into the following problem trying to supply agent > validation function. Here is sample code from page 135 (from book > version beta 5) > > (use '[clojure.contrib.except :only (throw-if)]) > (def counter (agent 0 #(throw-if (not (number? %)) "not a number"))) > > triggers the following exception: > > java.lang.IllegalArgumentException: No value supplied for key: user > $fn__1...@89f302 (NO_SOURCE_FILE:2) > [Thrown class clojure.lang.Compiler$CompilerException] > > I’m using the latest versions of clojure (r1216) and clojure-contrib > (r374) on Mac OS X 10.5.6, Java version "1.5.0_16" > > Many thanks, > > Telman > > > > On Jan 16, 8:49 am, Stuart Halloway wrote: >> Long, long ago (Tuesday) when Beta 5 of the book shipped, there were >> some breakages in the sample code due to changes in clojure- >> contrib. I >> believe everything is now fixed in the github repository >> (http://github.com/stuarthalloway/programming-clojure >> ). >> >> Summary of the issues: >> >> 1. clojure.contrib.seq-util/includes? changed the argument order for >> consistency with other operations. This caused problems with the >> snippet web app; Compojure is now updated to match the change in >> contrib. >> >> 2. clojure.contrib.sql/with-results has been removed and replaced >> with >> with-query-results. This broke the snippet model. The code is now >> fixed and I will update the prose in the next Beta. >> >> 3. A change to clojure.lang.Util necessitated a _clean_ rebuild of >> contrib and compojure. I have rebuild these dependencies in the lib >> directory. >> >> 4. A change to clojure.contrib.test-is.is broke a few unit tests. The >> book doesn't reference any of these tests directly, but they are now >> fixed in the code. You can run the whole test suite with ./ >> runtests.sh. >> >> Let me know if you find any other issues! >> >> Thanks, >> Stuart > > --~--~-~--~~~---~--~~ 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: Mysterious performance anomalies
On Jan 16, 2009, at 15:47, e wrote: > Is it much much easier to make byte code than assembly code? I > mean, I understand why running on a VM makes sense as far as > instantly inheriting all the massive amounts of things out here for > Java but would it be possible to shoot for something down the > road that, behind the scenes, uses jvm whenever you say, > "import" . . .and writes and compiles assembler whenever you are > doing purely algorithmic things? There are (at least) two reasons not to go that way: 1) The JVM provides a lot of infrastructure for programming languages that otherwise each compiler/interpreter would have to reinvent. Memory handling with garbage collection, for example. And of course a lot of platform-specific OS interfacing. Reinventing them is not only a lot of work, but also creates compatibility barriers in multi- language programming. It is very difficult to combine languages A and B if each of them has its own memory management. 2) Compiling to a mix of native code and JVM bytecode brings up a lot of ugly platform dependencies, the kind that makes the Java native interface so unpleasant to use. There is a reason why virtual machines like the JVM and CLI (.Net/ Mono) are gaining popularity. They provide security (by supervising programs' acces to the machine resources), portability, infrastructure, and the possibility to mix languages easily. There is a performance price to pay for this, but apparently more and more people are willing to do so, and at the same time that price is going down. Konrad. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
How to implement "go to definition" and "find all references"
Hello, and thanks for all the help with the IntelliJ plugin. The next feature I want to implement is "references". That is, one selects a symbol, and then can go to the location where that symbol was defined (e.g. def, defn, let, etc.). One can also get a list of all the locations where that symbol is referenced. This feature is very nice for navigating code, and is also the core of many automatic refactorings (e.g. "rename"). Implementing references are pretty straightforward in a static language like Java, were all the references are resolved at compile time. However, in a language like Clojure some references get resolved at run time. How do other IDEs handle this? Is there a recommended set of rules for what references can and can not be resolved by the editor? How does one detect a possible non-static reference, or how does one ensure that a reference will always refer to the same location? Note that I need a 100% reliable solution, if I am going to implement automatic refactoring on top of it. No one wants refactoring that messes up the code 5% of the time. Thanks Peter --~--~-~--~~~---~--~~ 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: Mysterious performance anomalies
On Jan 16, 9:47 am, e wrote: > Is it much much easier to make byte code than assembly code? To some extent, yes. JVM bytecode is certainly simpler than x86 assembly. The big win is that bytecode is platform-neutral, so you don't have to rewrite your compiler for each architecture. Java's just-in-time compiler generates optimized assembly for every architecture. It's not perfect, but steadily improving. -Stuart Sierra --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Programming Clojure sample code: fixes for breaking changes
Thank you very much, Stuart! I think it's a good idea for me to start reading Clojure source code and keep track of the changes, as the language changes so quickly... On Jan 16, 10:02 am, Stuart Halloway wrote: > Hi Telman, > > The signature for agent has changed. Use: > > (def counter (agent 0 :validator number?)) > > I will update the prose in Beta 6. > > Stuart > > > I keep running into the following problem trying to supply agent > > validation function. Here is sample code from page 135 (from book > > version beta 5) > > > (use '[clojure.contrib.except :only (throw-if)]) > > (def counter (agent 0 #(throw-if (not (number? %)) "not a number"))) > > > triggers the following exception: > > > java.lang.IllegalArgumentException: No value supplied for key: user > > $fn__1...@89f302 (NO_SOURCE_FILE:2) > > [Thrown class clojure.lang.Compiler$CompilerException] > > > I’m using the latest versions of clojure (r1216) and clojure-contrib > > (r374) on Mac OS X 10.5.6, Java version "1.5.0_16" > > > Many thanks, > > > Telman > > > On Jan 16, 8:49 am, Stuart Halloway wrote: > >> Long, long ago (Tuesday) when Beta 5 of the book shipped, there were > >> some breakages in the sample code due to changes in clojure- > >> contrib. I > >> believe everything is now fixed in the github repository > >> (http://github.com/stuarthalloway/programming-clojure > >> ). > > >> Summary of the issues: > > >> 1. clojure.contrib.seq-util/includes? changed the argument order for > >> consistency with other operations. This caused problems with the > >> snippet web app; Compojure is now updated to match the change in > >> contrib. > > >> 2. clojure.contrib.sql/with-results has been removed and replaced > >> with > >> with-query-results. This broke the snippet model. The code is now > >> fixed and I will update the prose in the next Beta. > > >> 3. A change to clojure.lang.Util necessitated a _clean_ rebuild of > >> contrib and compojure. I have rebuild these dependencies in the lib > >> directory. > > >> 4. A change to clojure.contrib.test-is.is broke a few unit tests. The > >> book doesn't reference any of these tests directly, but they are now > >> fixed in the code. You can run the whole test suite with ./ > >> runtests.sh. > > >> Let me know if you find any other issues! > > >> Thanks, > >> Stuart --~--~-~--~~~---~--~~ 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 implement "go to definition" and "find all references"
Peter Wolf a écrit : > Note that I need a 100% reliable solution, if I am going to implement > automatic refactoring on top of it. No one wants refactoring that > messes up the code 5% of the time. > Even Java refactoring tools messes up the code each time something is too dynamic (reflection, identifers hidden in XML or .properties files etc.). Christophe --~--~-~--~~~---~--~~ 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: test-is reporting problem
Hello, fellow Stuarts, and others, Fixed now, SVN rev. 377. I've temporarily abandoned the fancier error reporting I had for functional predicates. I'm going to try to restore that without breaking anything else. :) Peace, love, and happy testing, -Stuart Sierra On Jan 16, 7:54 am, Stuart Halloway wrote: > S. Sierra, > > Here is a good test case. It would be nice if the Java interop form > worked, without having to be wrapped in an anonymous function. > > user=> (use 'clojure.contrib.test-is) > nil > user=> (.startsWith "abc" "a") > true > user=> (is (.startsWith "abc" "a")) > java.lang.Exception: Unable to resolve symbol: .startsWith in this > context (NO_SOURCE_FILE:3) > user=> (#(.startsWith % "a") "abc") > true > user=> (is (#(.startsWith % "a") "abc")) > true > > S. Halloway > > > I was afraid that would happen. I'll fix it, probably tomorrow. > > -the other Stuart > > > On Jan 15, 6:27 pm, Stuart Halloway wrote: > >> The improved error reposting in test-is breaks some tests, e.g. from > >> the book: > > >> (deftest test-lazy-index-of-any-with-match > >> (is (with-out-str (is (zero? (index-of-any "zzabyycdxx" #{\z > >> \a} > >> "Iterating overz\n") > >> (is (with-out-str (is (= 3 (index-of-any "zzabyycdxx" #{\b \y} > >> "Iterating overz\nIterating over z\nIterating over a\n")) > > >> The problem is that it tries to take the value of with-out-str, not > >> realizing that it is a macro. > > >> Should I > > >> (1) rewrite the test to not use a macro? > >> (2) take a stab at fixing this in test-is? > >> (3) get out of the way and let another Stuart handle it? :-) > > >> Stuart --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Clojure style question, mutable global data structures using Java?
I am working on this GUI tool and want to keep 'global' data structures in memory. For example, lets say I have a checkbox and want to be able to keep and access the state of that checkbox at any time. Right now, I am thinking the easiest thing to do is using a Java hashmap and change the state when needed. (def my-map (new HashMap)) (defn init-hash-map [] (. my-map put "checkbox-state" "false")) (defn get-checkbox-state [] (. my-map get "checkbox-state")) ... ... Is this bad clojure or lisp code (probably is), but what are some other approaches? --~--~-~--~~~---~--~~ 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 style question, mutable global data structures using Java?
On Jan 16, 11:10 am, BerlinBrown wrote: > I am working on this GUI tool and want to keep 'global' data > structures in memory. For example, lets say I have a checkbox and > want to be able to keep and access the state of that checkbox at any > time. Right now, I am thinking the easiest thing to do is using a > Java hashmap and change the state when needed. > > (def my-map (new HashMap)) > > (defn init-hash-map [] > (. my-map put "checkbox-state" "false")) > > (defn get-checkbox-state [] >(. my-map get "checkbox-state")) > > ... > ... > > Is this bad clojure or lisp code (probably is), but what are some > other approaches? I hear that in Erlang, you can use processes to work with mutable state. And some say that Clojure has some similar functionality. Should I use 'ref' or 'agent' to do this? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: configurable bash script to launch Clojure available
On Jan 16, 2009, at 8:37 AM, Stephen C. Gilardi wrote: I like this. I've also seen several requests for a way to know when code is running in a script which could be satisfied by this as well. For clarity, here's what I'm proposing based on recent discussion in this thread: [1] When clojure.main runs a script, it will set *command-line-script* to the script name as it appears on the command line. Example: java -cp clojure.jar clojure.main -i dir-utils.clj list- dir.clj :verbose :depth 3 will run with these values set: *command-line-script* "list-dir.clj" *command-line-args* (":verbose" ":depth" "3") Note that dir-utils.clj is an "init file" here (there can be any number of them, each introduced by a "-i"), while list-dir.clj is the main script. [2] When clojure.lang.Script runs a script, the name immediately before either the end of line or the "--" will be the script name. Here's the equivalent to above: java -cp clojure.jar clojure.lang.Script dir-utils.clj list-dir.clj -- :verbose :depth 3 (same values set): *command-line-script* "list-dir.clj" *command-line-args* (":verbose" ":depth" "3") Note that in this case, files are still loaded in order, but "init" files are not "marked". list-dir.clj is considered the main script because it's the last to appear before the "--" which marks the beginning of args. [3] *command-line-script* will be nil in other cases: when clojure.main launches a repl, when using clojure.lang.Repl, or when clojure.main reads a script from *in*. Comments welcome. --Steve smime.p7s Description: S/MIME cryptographic signature
Re: configurable bash script to launch Clojure available
On Fri, Jan 16, 2009 at 11:27 AM, Stephen C. Gilardi wrote: > > [1] When clojure.main runs a script, it will set *command-line-script* to > the script name as it appears on the command line. > > Example: > >java -cp clojure.jar clojure.main -i dir-utils.clj list-dir.clj > :verbose :depth 3 > > will run with these values set: > >*command-line-script* "list-dir.clj" >*command-line-args* (":verbose" ":depth" "3") > > Note that dir-utils.clj is an "init file" here (there can be any number of > them, each introduced by a "-i"), while list-dir.clj is the main script. I think this is a good idea. It would also be useful for a .clj file to be able to determine if itself is the main script or if instead it's being loaded some other way (-i, load-file, require, etc.). The proposed *command-line-script* could be used to make a good guess, but since it's possible that the main script might have the same file name as some lib, it wouldn't be perfect. I'm not exactly sure how this ought to work, since the main script may not be a lib or even be in the classpath. Maybe a dynamically-bound variable *loading-main-script* that is bound to true when the main script is loaded and specifically re-bound to false during lib loading? --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 style question, mutable global data structures using Java?
Hi Berlin, Probably ref, if the state must be coordinate with other state, or atom, if it is totally independent. But you might be able to avoid using mutable state at all. We would need a larger example to tell. Stuart > On Jan 16, 11:10 am, BerlinBrown wrote: >> I am working on this GUI tool and want to keep 'global' data >> structures in memory. For example, lets say I have a checkbox and >> want to be able to keep and access the state of that checkbox at any >> time. Right now, I am thinking the easiest thing to do is using a >> Java hashmap and change the state when needed. >> >> (def my-map (new HashMap)) >> >> (defn init-hash-map [] >> (. my-map put "checkbox-state" "false")) >> >> (defn get-checkbox-state [] >> (. my-map get "checkbox-state")) >> >> ... >> ... >> >> Is this bad clojure or lisp code (probably is), but what are some >> other approaches? > > I hear that in Erlang, you can use processes to work with mutable > state. And some say that Clojure has some similar functionality. > Should I use 'ref' or 'agent' to do this? > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure style question, mutable global data structures using Java?
BerlinBrown a écrit : > > On Jan 16, 11:10 am, BerlinBrown wrote: > >> I am working on this GUI tool and want to keep 'global' data >> structures in memory. For example, lets say I have a checkbox and >> want to be able to keep and access the state of that checkbox at any >> time. Right now, I am thinking the easiest thing to do is using a >> Java hashmap and change the state when needed. >> > Should I use 'ref' or 'agent' to do this? > Yes! http://clojure.googlegroups.com/web/clojure-conc.png summarizes the differences between atoms, refs and agents. (and the fine doc tells you the details.) I think you need an atom or a ref: (def my-map (ref {:checkbox-state false})) (defn get-checkbox-state [] (@my-map :checkbox-state)) (defn set-checkbox-state [state] (dosync (commute my-map assoc :checkbox-state state))) Christophe --~--~-~--~~~---~--~~ 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 style question, mutable global data structures using Java?
On Jan 16, 11:49 am, Christophe Grand wrote: > BerlinBrown a écrit : > > > On Jan 16, 11:10 am, BerlinBrown wrote: > > >> I am working on this GUI tool and want to keep 'global' data > >> structures in memory. For example, lets say I have a checkbox and > >> want to be able to keep and access the state of that checkbox at any > >> time. Right now, I am thinking the easiest thing to do is using a > >> Java hashmap and change the state when needed. > > > Should I use 'ref' or 'agent' to do this? > > Yes!http://clojure.googlegroups.com/web/clojure-conc.pngsummarizes the > differences between atoms, refs and agents. > (and the fine doc tells you the details.) > > I think you need an atom or a ref: > > (def my-map (ref {:checkbox-state false})) > > (defn get-checkbox-state [] >(@my-map :checkbox-state)) > > (defn set-checkbox-state [state] > (dosync (commute my-map assoc :checkbox-state state))) > > Christophe Thanks all, this is what I ended up with: For noobs like myself, I am using this code to monitor files and refresh it when the file gets modified. I used 'ref' and 'agent'. (def file-monitor-agent (agent false)) (def file-state (ref {:open-state false})) (defn get-file-state [] (@file-state :open-state)) (defn set-file-state [state] (dosync (commute file-state assoc :open- state state))) (defn file-monitor-loop [] (let [delay-t (prop-int resources-core-sys "Octane_Sys_filemonitor_delay") enable-file-mon (prop-bool resources-win-opts "file_monitor_enabled")] (send file-monitor-agent (fn [_] (when enable-file-mon (loop [] (when (not (. shell (isDisposed))) (. Thread sleep delay-t) (println "Woot!!!") (recur --~--~-~--~~~---~--~~ 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 style question, mutable global data structures using Java?
BerlinBrown a écrit : > Thanks all, this is what I ended up with: > For noobs like myself, I am using this code to monitor files and > refresh it when the file gets modified. I used 'ref' and 'agent'. > > (def file-monitor-agent (agent false)) > (def file-state (ref {:open-state false})) > (defn get-file-state [] (@file-state :open-state)) > (defn set-file-state [state] (dosync (commute file-state assoc :open- > state state))) > > (defn file-monitor-loop [] > (let [delay-t (prop-int resources-core-sys > "Octane_Sys_filemonitor_delay") > enable-file-mon (prop-bool resources-win-opts > "file_monitor_enabled")] > (send file-monitor-agent > (fn [_] > (when enable-file-mon > (loop [] > (when (not (. shell (isDisposed))) > (. Thread sleep delay-t) > (println "Woot!!!") > (recur > Since the action you send to your agent doesn't end you should send it using send-off ('send-off will give your action its own thread while 'send use a fixed thread pool). But, given that you don't care about the agent value, it would be better to simply use a thread (clojure's fns are Runnables): (defn file-monitor-loop [] (let [delay-t (prop-int resources-core-sys "Octane_Sys_filemonitor_delay") enable-file-mon (prop-bool resources-win-opts "file_monitor_enabled")] (when enable-file-mon (.start (Thread. #(while (not (.isDisposed shell)) (Thread/sleep delay-t) (println "Woot!!!"))) Christophe --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Possible minor bug in gen-class: method name character escaping?
I think I may have found a minor issue with gen-class, but wanted to confirm with the group that I'm not just doing something stupid... (gen-class :name mypkg.foo :prefix "" :methods [[my-method [Object] Object]]) Results in the following method signature in the .class file: public Object my_2D_method(Object obj) { "-" is being written out as "_2D_" -Greg --~--~-~--~~~---~--~~ 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: Possible minor bug in gen-class: method name character escaping?
- is not a "Java letter or digit" so it is not allowed in java method names. http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8 user=> (Character/isJavaIdentifierPart (int \-)) false user=> On Fri, Jan 16, 2009 at 9:56 AM, Greg Harman wrote: > > I think I may have found a minor issue with gen-class, but wanted to > confirm with the group that I'm not just doing something stupid... > > (gen-class :name mypkg.foo > :prefix "" > :methods [[my-method [Object] Object]]) > > Results in the following method signature in the .class file: > > public Object my_2D_method(Object obj) { > > "-" is being written out as "_2D_" > > -Greg > > > -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? --~--~-~--~~~---~--~~ 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 style question, mutable global data structures using Java?
On Jan 16, 12:47 pm, Christophe Grand wrote: > BerlinBrown a écrit : > > > Thanks all, this is what I ended up with: > > For noobs like myself, I am using this code to monitor files and > > refresh it when the file gets modified. I used 'ref' and 'agent'. > > > (def file-monitor-agent (agent false)) > > (def file-state (ref {:open-state false})) > > (defn get-file-state [] (@file-state :open-state)) > > (defn set-file-state [state] (dosync (commute file-state assoc :open- > > state state))) > > > (defn file-monitor-loop [] > > (let [delay-t (prop-int resources-core-sys > > "Octane_Sys_filemonitor_delay") > > enable-file-mon (prop-bool resources-win-opts > > "file_monitor_enabled")] > > (send file-monitor-agent > > (fn [_] > > (when enable-file-mon > > (loop [] > > (when (not (. shell (isDisposed))) > > (. Thread sleep delay-t) > > (println "Woot!!!") > > (recur > > Since the action you send to your agent doesn't end you should send it > using send-off ('send-off will give your action its own thread while > 'send use a fixed thread pool). > But, given that you don't care about the agent value, it would be better > to simply use a thread (clojure's fns are Runnables): > > (defn file-monitor-loop [] > (let [delay-t (prop-int resources-core-sys > "Octane_Sys_filemonitor_delay") > enable-file-mon (prop-bool resources-win-opts > "file_monitor_enabled")] > (when enable-file-mon > (.start (Thread. > #(while (not (.isDisposed shell)) >(Thread/sleep delay-t) >(println "Woot!!!"))) > > Christophe What is the '#' in this example. --~--~-~--~~~---~--~~ 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 style question, mutable global data structures using Java?
On Fri, Jan 16, 2009 at 12:13 PM, BerlinBrown wrote: > > On Jan 16, 12:47 pm, Christophe Grand wrote: >> BerlinBrown a écrit : >> >> > Thanks all, this is what I ended up with: >> > For noobs like myself, I am using this code to monitor files and >> > refresh it when the file gets modified. I used 'ref' and 'agent'. >> >> > (def file-monitor-agent (agent false)) >> > (def file-state (ref {:open-state false})) >> > (defn get-file-state [] (@file-state :open-state)) >> > (defn set-file-state [state] (dosync (commute file-state assoc :open- >> > state state))) >> >> > (defn file-monitor-loop [] >> > (let [delay-t (prop-int resources-core-sys >> > "Octane_Sys_filemonitor_delay") >> > enable-file-mon (prop-bool resources-win-opts >> > "file_monitor_enabled")] >> > (send file-monitor-agent >> > (fn [_] >> > (when enable-file-mon >> > (loop [] >> > (when (not (. shell (isDisposed))) >> > (. Thread sleep delay-t) >> > (println "Woot!!!") >> > (recur >> >> Since the action you send to your agent doesn't end you should send it >> using send-off ('send-off will give your action its own thread while >> 'send use a fixed thread pool). >> But, given that you don't care about the agent value, it would be better >> to simply use a thread (clojure's fns are Runnables): >> >> (defn file-monitor-loop [] >> (let [delay-t (prop-int resources-core-sys >> "Octane_Sys_filemonitor_delay") >> enable-file-mon (prop-bool resources-win-opts >> "file_monitor_enabled")] >> (when enable-file-mon >> (.start (Thread. >> #(while (not (.isDisposed shell)) >>(Thread/sleep delay-t) >>(println "Woot!!!"))) >> >> Christophe > > What is the '#' in this example. It's the beginning of the definition of an anonymous function. That's what is passed to the Thread constructor. -- 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: Clojure style question, mutable global data structures using Java?
BerlinBrown a écrit : > > On Jan 16, 12:47 pm, Christophe Grand wrote: > >> BerlinBrown a écrit : >> >> >>> Thanks all, this is what I ended up with: >>> For noobs like myself, I am using this code to monitor files and >>> refresh it when the file gets modified. I used 'ref' and 'agent'. >>> >>> (def file-monitor-agent (agent false)) >>> (def file-state (ref {:open-state false})) >>> (defn get-file-state [] (@file-state :open-state)) >>> (defn set-file-state [state] (dosync (commute file-state assoc :open- >>> state state))) >>> >>> (defn file-monitor-loop [] >>> (let [delay-t (prop-int resources-core-sys >>> "Octane_Sys_filemonitor_delay") >>> enable-file-mon (prop-bool resources-win-opts >>> "file_monitor_enabled")] >>> (send file-monitor-agent >>> (fn [_] >>> (when enable-file-mon >>> (loop [] >>> (when (not (. shell (isDisposed))) >>> (. Thread sleep delay-t) >>> (println "Woot!!!") >>> (recur >>> >> Since the action you send to your agent doesn't end you should send it >> using send-off ('send-off will give your action its own thread while >> 'send use a fixed thread pool). >> But, given that you don't care about the agent value, it would be better >> to simply use a thread (clojure's fns are Runnables): >> >> (defn file-monitor-loop [] >> (let [delay-t (prop-int resources-core-sys >> "Octane_Sys_filemonitor_delay") >> enable-file-mon (prop-bool resources-win-opts >> "file_monitor_enabled")] >> (when enable-file-mon >> (.start (Thread. >> #(while (not (.isDisposed shell)) >>(Thread/sleep delay-t) >>(println "Woot!!!"))) >> >> Christophe >> > > What is the '#' in this example. > It denotes an anonymous function literal. Anonymous function literal (#()) #(...) => (fn [args] (...)) where args are determined by the presence of argument literals taking the form %, %n or %&. % is a synonym for %1, %n designates the nth arg (1-based), and %& designates a rest arg. This is not a replacement for /*fn*/ - idiomatic used would be for very short one-off mapping/filter fns and the like. #() forms cannot be nested. see http://clojure.org/reader Christophe --~--~-~--~~~---~--~~ 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 implement "go to definition" and "find all references"
On Jan 16, 9:32 am, Peter Wolf wrote: > Hello, and thanks for all the help with the IntelliJ plugin. > > The next feature I want to implement is "references". That is, one > selects a symbol, and then can go to the location where that symbol was > defined (e.g. def, defn, let, etc.). One can also get a list of all the > locations where that symbol is referenced. This feature is very nice > for navigating code, and is also the core of many automatic refactorings > (e.g. "rename"). > > Implementing references are pretty straightforward in a static language > like Java, were all the references are resolved at compile time. > However, in a language like Clojure some references get resolved at run > time. > > How do other IDEs handle this? Is there a recommended set of rules for > what references can and can not be resolved by the editor? How does one > detect a possible non-static reference, or how does one ensure that a > reference will always refer to the same location? > > Note that I need a 100% reliable solution, if I am going to implement > automatic refactoring on top of it. No one wants refactoring that > messes up the code 5% of the time. > > Thanks > Peter I haven't been following the IntelliJ plugin. Does it use slime? SLIME + Lisp has had a solution for this for years by directly asking the running lisp process. The high level description is that the process keeps track of all of the functions it has loaded/compiled, and the list of functions each of those functions calls. Then to find out who calls foo, you just ask the process. The answer is pretty reliable and doesn't require writing your own parser. Of course, it too can't deal with eval'ing and identifiers in XML, but I'm not sure that anything can. I've been toying with the idea of implementing this in clojure. Allen It would be fairly straightforward to modify the running clojure --~--~-~--~~~---~--~~ 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: test-is reporting problem
On Jan 16, 11:02 am, Stuart Sierra wrote: > Fixed now, SVN rev. 377. I've temporarily abandoned the fancier error > reporting I had for functional predicates. I'm going to try to > restore that without breaking anything else. :) Ok, I figured out how to do it. Now (rev. 380) you get nice error reports again: user> (is (= "Word" (.toUpperCase "word"))) FAIL in (:1) expected: (= "Word" (.toUpperCase "word")) actual: (not (= "Word" "WORD")) -Stuart Sierra --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Possible minor bug in gen-class: method name character escaping?
Ah, that'll do it. Thanks. On Jan 16, 1:02 pm, Kevin Downey wrote: > - is not a "Java letter or digit" so it is not allowed in java method names. > > http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8 > > user=> (Character/isJavaIdentifierPart (int \-)) > false > user=> > > > > On Fri, Jan 16, 2009 at 9:56 AM, Greg Harman wrote: > > > I think I may have found a minor issue with gen-class, but wanted to > > confirm with the group that I'm not just doing something stupid... > > > (gen-class :name mypkg.foo > > :prefix "" > > :methods [[my-method [Object] Object]]) > > > Results in the following method signature in the .class file: > > > public Object my_2D_method(Object obj) { > > > "-" is being written out as "_2D_" > > > -Greg > > -- > And what is good, Phaedrus, > And what is not good— > Need we ask anyone to tell us these things? --~--~-~--~~~---~--~~ 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 implement "go to definition" and "find all references"
On Jan 16, 10:32 am, Peter Wolf wrote: > The next feature I want to implement is "references". That is, one > selects a symbol, and then can go to the location where that symbol was > defined (e.g. def, defn, let, etc.). Try looking at clojure.contrib.repl-utils and its "source" macro. -Stuart Sierra --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Mysterious performance anomalies
> SVN 1216 - thanks for the report. Thanks for the quick fix! -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: Macros in interaction with Functions
I'm also very interested in this topic. The only reason to write "and" as a macro is for performance reasons. It's much more convenient, programming-wise, if and is a function. Is there anyway to write a macro/function that acts as a function when necessary (so it can be passed as an argument), but expands into a macro (for speed) when deemed possible? --~--~-~--~~~---~--~~ 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: Macros in interaction with Functions
and is also written as a macro to short circuit evaluation: clojure.core/and ([] [x] [x & rest]) Macro Evaluates exprs one at a time, from left to right. If a form returns logical false (nil or false), and returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expr. (and) returns true. On Fri, Jan 16, 2009 at 10:49 AM, CuppoJava wrote: > > I'm also very interested in this topic. > > The only reason to write "and" as a macro is for performance reasons. > It's much more convenient, programming-wise, if and is a function. > > Is there anyway to write a macro/function that acts as a function when > necessary (so it can be passed as an argument), but expands into a > macro (for speed) when deemed possible? > > > -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? --~--~-~--~~~---~--~~ 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: Macros in interaction with Functions
On Fri, Jan 16, 2009 at 12:49 PM, CuppoJava wrote: > > I'm also very interested in this topic. > > The only reason to write "and" as a macro is for performance reasons. That's not the only reason. Another reason is to have the option to avoid evaluating all of the arguments. Functions always evaluate all of their arguments. Macros don't always do that. -- 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: Possible minor bug in gen-class: method name character escaping?
As I chew on this, a couple of things don't sit right with me regarding use cases: 1. IMHO gen-class should fail with an appropriate message/exception rather than trying to "fix" the signature. This is what the Java compiler would do if I made the same mistake in Java. More to the point, an external Java class that tries to call my-method is going to break since that method doesn't exist by that name. That breakage is traceable no doubt, but it would be more effective to nip it in the bud at compilation time. 2. If I want the Clojure functions that underlie the methods in the generated class used directly by my Clojure code as well (which I do), then I'm stuck having to either violate standard Clojure/Lisp function naming conventions in favor of Java-friendly naming or I have to write wrapper functions like: (defn myMethod [obj] (my-method obj)) Other than using the prefix and keeping the method names to one "word", is there a better way? -Greg On Jan 16, 1:02 pm, Kevin Downey wrote: > - is not a "Java letter or digit" so it is not allowed in java method names. > > http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8 > > user=> (Character/isJavaIdentifierPart (int \-)) > false > user=> > > > > On Fri, Jan 16, 2009 at 9:56 AM, Greg Harman wrote: > > > I think I may have found a minor issue with gen-class, but wanted to > > confirm with the group that I'm not just doing something stupid... > > > (gen-class :name mypkg.foo > > :prefix "" > > :methods [[my-method [Object] Object]]) > > > Results in the following method signature in the .class file: > > > public Object my_2D_method(Object obj) { > > > "-" is being written out as "_2D_" > > > -Greg > > -- > And what is good, Phaedrus, > And what is not good— > Need we ask anyone to tell us these things? --~--~-~--~~~---~--~~ 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: Two errors building closure
Looks like you are attempting to compile with a 1.4.x JDK. You need to compile with JDK 1.5 or higher. -Ryan On Jan 15, 5:42 pm, Ron Parker wrote: > I am trying to build Clojure on Fedora 10. When I first run ant, I get > a message about the compliance level 1.4 not supporting target version > 1.5. So I add source="1.5" to the javac task. Then I get a lot of > warnings and the following 3 errors. > > [javac] 354. ERROR in /home/rdp/lisp/clj/clojure/src/jvm/clojure/ > lang/Numbers.java (at line 900) > [javac] : toBigDecimal(x).divide(toBigDecimal(y), mc); > [javac] ^^ > [javac] The method divide(BigDecimal, int) in the type BigDecimal > is not applicable for the arguments (BigDecimal, MathCont > ext) > [javac] -- > [javac] 355. ERROR in /home/rdp/lisp/clj/clojure/src/jvm/clojure/ > lang/Numbers.java > [javac] (at line 907) > [javac] : toBigDecimal(x).divideToIntegralValue(toBigDecimal > (y), mc); > [javac] ^ > [javac] The method divideToIntegralValue(BigDecimal) in the type > BigDecimal is not applicable for the arguments (BigDecimal > , MathContext) > [javac] -- > [javac] 356. ERROR in /home/rdp/lisp/clj/clojure/src/jvm/clojure/ > lang/Numbers.java (at line 914) > [javac] : toBigDecimal(x).remainder(toBigDecimal(y), mc); > [javac] ^ > [javac] The method remainder(BigDecimal) in the type BigDecimal is > not applicable for the arguments (BigDecimal, MathContex > t) --~--~-~--~~~---~--~~ 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: Possible minor bug in gen-class: method name character escaping?
On Jan 16, 2009, at 2:46 PM, Greg Harman wrote: > > As I chew on this, a couple of things don't sit right with me > regarding use cases: > > 1. IMHO gen-class should fail with an appropriate message/exception > rather than trying to "fix" the signature. This is what the Java > compiler would do if I made the same mistake in Java. More to the > point, an external Java class that tries to call my-method is going to > break since that method doesn't exist by that name. That breakage is > traceable no doubt, but it would be more effective to nip it in the > bud at compilation time. Agreed, this should be done before the 1.0 release. > > > 2. If I want the Clojure functions that underlie the methods in the > generated class used directly by my Clojure code as well (which I do), > then I'm stuck having to either violate standard Clojure/Lisp function > naming conventions in favor of Java-friendly naming or I have to write > wrapper functions like: > > (defn myMethod [obj] (my-method obj)) > > Other than using the prefix and keeping the method names to one > "word", is there a better way? Since gen-class is used to create Java classes, it's sensible that the naming convention within the generated class be Java's. > > > -Greg > > On Jan 16, 1:02 pm, Kevin Downey wrote: >> - is not a "Java letter or digit" so it is not allowed in java >> method names. >> >> http://java.sun.com/docs/books/jls/third_edition/html/ >> lexical.html#3.8 >> >> user=> (Character/isJavaIdentifierPart (int \-)) >> false >> user=> >> >> >> >> On Fri, Jan 16, 2009 at 9:56 AM, Greg Harman >> wrote: >> >>> I think I may have found a minor issue with gen-class, but wanted to >>> confirm with the group that I'm not just doing something stupid... >> >>> (gen-class :name mypkg.foo >>> :prefix "" >>> :methods [[my-method [Object] Object]]) >> >>> Results in the following method signature in the .class file: >> >>> public Object my_2D_method(Object obj) { >> >>> "-" is being written out as "_2D_" >> >>> -Greg >> >> -- >> And what is good, Phaedrus, >> And what is not good— >> Need we ask anyone to tell us these things? > > --~--~-~--~~~---~--~~ 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?
> > > (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]) Oops, just found occasion to use this again and realized there's a bug if the first element ends up being maximal. Here's a fixed version. (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 --~--~-~--~~~---~--~~ 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: Possible minor bug in gen-class: method name character escaping?
> > 2. If I want the Clojure functions that underlie the methods in the > > generated class used directly by my Clojure code as well (which I do), > > then I'm stuck having to either violate standard Clojure/Lisp function > > naming conventions in favor of Java-friendly naming or I have to write > > wrapper functions like: > > > (defn myMethod [obj] (my-method obj)) > > > Other than using the prefix and keeping the method names to one > > "word", is there a better way? > > Since gen-class is used to create Java classes, it's sensible that the > naming convention within the generated class be Java's. I agree that the convention inside the generated class should be a Java convention (my original post was more of an experiment than an attempt to create a working class with that signature). However, I find myself wanting to write a clojure function that can be exposed to both Clojure and Java code, and I'd like to keep them in their respective paradigms. That is, in Clojure, I don't want to have to call (.myMethod foo) when I already have (my-method) defined. And in Java, I want to just use foo.myMethod(), not have to wrap up a call to RT.var().invoke(). I know I'm being picky, but it just seems cleaner this way... --~--~-~--~~~---~--~~ 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 implement "go to definition" and "find all references"
Hello, While I understand this solution has been long in place for Lips, I don't think it looks like the ideal solution, e.g. in a world where the "source code" is still in files, and not managed by the "lisp image". I'm aware of just smalltalk that does this cleanly (it is even managing versions of modifications as they are made !). This to say, that, as an IDE provider, I feel uneasy to offer text source code in an editor, while not being able to say to the user : "what you are currently seeing is/is not in sync with what is in the running lisp you see in the REPL below". How does Slime handle that ? Thanks in advance for your answers, (I'm not an experience emacs/slime user, so feedback welcome !) -- Laurent On 16 jan, 19:31, Allen Rohner wrote: > On Jan 16, 9:32 am, Peter Wolf wrote: > > > > > Hello, and thanks for all the help with the IntelliJ plugin. > > > The next feature I want to implement is "references". That is, one > > selects a symbol, and then can go to the location where that symbol was > > defined (e.g. def, defn, let, etc.). One can also get a list of all the > > locations where that symbol is referenced. This feature is very nice > > for navigating code, and is also the core of many automatic refactorings > > (e.g. "rename"). > > > Implementing references are pretty straightforward in a static language > > like Java, were all the references are resolved at compile time. > > However, in a language like Clojure some references get resolved at run > > time. > > > How do other IDEs handle this? Is there a recommended set of rules for > > what references can and can not be resolved by the editor? How does one > > detect a possible non-static reference, or how does one ensure that a > > reference will always refer to the same location? > > > Note that I need a 100% reliable solution, if I am going to implement > > automatic refactoring on top of it. No one wants refactoring that > > messes up the code 5% of the time. > > > Thanks > > Peter > > I haven't been following the IntelliJ plugin. Does it use slime? SLIME > + Lisp has had a solution for this for years by directly asking the > running lisp process. The high level description is that the process > keeps track of all of the functions it has loaded/compiled, and the > list of functions each of those functions calls. Then to find out who > calls foo, you just ask the process. The answer is pretty reliable and > doesn't require writing your own parser. Of course, it too can't deal > with eval'ing and identifiers in XML, but I'm not sure that anything > can. > > I've been toying with the idea of implementing this in clojure. > > Allen > > It would be fairly straightforward to modify the running clojure --~--~-~--~~~---~--~~ 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: Possible minor bug in gen-class: method name character escaping?
On Fri, Jan 16, 2009 at 12:22 PM, Greg Harman wrote: > >> > 2. If I want the Clojure functions that underlie the methods in the >> > generated class used directly by my Clojure code as well (which I do), >> > then I'm stuck having to either violate standard Clojure/Lisp function >> > naming conventions in favor of Java-friendly naming or I have to write >> > wrapper functions like: >> >> > (defn myMethod [obj] (my-method obj)) >> >> > Other than using the prefix and keeping the method names to one >> > "word", is there a better way? >> >> Since gen-class is used to create Java classes, it's sensible that the >> naming convention within the generated class be Java's. > > I agree that the convention inside the generated class should be a > Java convention (my original post was more of an experiment than an > attempt to create a working class with that signature). However, I > find myself wanting to write a clojure function that can be exposed to > both Clojure and Java code, and I'd like to keep them in their > respective paradigms. That is, in Clojure, I don't want to have to > call (.myMethod foo) when I already have (my-method) defined. And in > Java, I want to just use foo.myMethod(), not have to wrap up a call to > RT.var().invoke(). > > I know I'm being picky, but it just seems cleaner this way... write a macro that takes all fns in the current namespace and generates wrappers with the correct naming style. problem solved. -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? --~--~-~--~~~---~--~~ 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: Macros in interaction with Functions
> Is there anyway to write a macro/function that acts as a function when > necessary (so it can be passed as an argument), but expands into a > macro (for speed) when deemed possible? I don't think this is possible without some sort of support for a macro/function duality in core Clojure. In the current implementation (read: you should not rely on this fact) macros' are simply functions with the #^{:macro true} metadata attached. Since you can't have a symbol refer to two different values, I don't see any way to do this except if you re-bind 'and' in a local context: (let [and (fn and [x & xs] (if x (if (nil? xs) true (and xs)) false))] (apply and [true true false])) Probably the closest you can come to this without redefining and is Konrad's suggestion: #(and %1 %2) /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: Macros in interaction with Functions
On Fri, Jan 16, 2009 at 3:41 PM, Michael Reid wrote: > >> Is there anyway to write a macro/function that acts as a function when >> necessary (so it can be passed as an argument), but expands into a >> macro (for speed) when deemed possible? > > I don't think this is possible without some sort of support for a > macro/function duality in core Clojure. Which is one way to describe what's provided by definline. It's marked experimental, has an unusual format and proviso's, but it's there get a blend of macro performance and function first-classness. --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: configurable bash script to launch Clojure available
On Jan 16, 2009, at 11:37 AM, Chouser wrote: It would also be useful for a .clj file to be able to determine if itself is the main script or if instead it's being loaded some other way (-i, load-file, require, etc.). How about this which is not quite the same, but has nice properties of its own: It appears that all flavors of loading ultimately bottleneck at Compiler.load(Reader,String,String). We could add a "*load-level*" var with a root binding of 0 that gets incremented on each entry to that Compiler.load method. A *load-level* of 1 would indicate that this file is being loaded from the "top level" with no other load pending. A script could behave differently on (= *load-level* 1) (or a suitably named function that returns the same boolean value). I like this because it's simple to implement and explain and it also covers the case of loading a script explicitly from the repl. Arguably a script loaded by the user from the top level at the repl ought to behave as a "main" script as well. --Steve smime.p7s Description: S/MIME cryptographic signature
Re: How to implement "go to definition" and "find all references"
Hi and thanks for all the feedback How does SLIME handle this case? user=> (def foo 1) #'user/foo user=> (defn bah [] (let [foo 2] foo)) #'user/bah user=> (bah) 2 If I select the "foo" inside the let, I want the local one How does the running image figure that out? What does the API to the LISP process look like? Also what happens if you have the following in a file? How does the image figure out which (def...) maps to which reference? (def foo 1) foo (def foo 2) foo Thanks Peter lpetit wrote: > Hello, > > While I understand this solution has been long in place for Lips, I > don't think it looks like the ideal solution, e.g. in a world where > the "source code" is still in files, and not managed by the "lisp > image". I'm aware of just smalltalk that does this cleanly (it is even > managing versions of modifications as they are made !). > > This to say, that, as an IDE provider, I feel uneasy to offer text > source code in an editor, while not being able to say to the user : > "what you are currently seeing is/is not in sync with what is in the > running lisp you see in the REPL below". > > How does Slime handle that ? > > Thanks in advance for your answers, (I'm not an experience emacs/slime > user, so feedback welcome !) > > -- > Laurent > > On 16 jan, 19:31, Allen Rohner wrote: > >> On Jan 16, 9:32 am, Peter Wolf wrote: >> >> >> >> >>> Hello, and thanks for all the help with the IntelliJ plugin. >>> >>> The next feature I want to implement is "references". That is, one >>> selects a symbol, and then can go to the location where that symbol was >>> defined (e.g. def, defn, let, etc.). One can also get a list of all the >>> locations where that symbol is referenced. This feature is very nice >>> for navigating code, and is also the core of many automatic refactorings >>> (e.g. "rename"). >>> >>> Implementing references are pretty straightforward in a static language >>> like Java, were all the references are resolved at compile time. >>> However, in a language like Clojure some references get resolved at run >>> time. >>> >>> How do other IDEs handle this? Is there a recommended set of rules for >>> what references can and can not be resolved by the editor? How does one >>> detect a possible non-static reference, or how does one ensure that a >>> reference will always refer to the same location? >>> >>> Note that I need a 100% reliable solution, if I am going to implement >>> automatic refactoring on top of it. No one wants refactoring that >>> messes up the code 5% of the time. >>> >>> Thanks >>> Peter >>> >> I haven't been following the IntelliJ plugin. Does it use slime? SLIME >> + Lisp has had a solution for this for years by directly asking the >> running lisp process. The high level description is that the process >> keeps track of all of the functions it has loaded/compiled, and the >> list of functions each of those functions calls. Then to find out who >> calls foo, you just ask the process. The answer is pretty reliable and >> doesn't require writing your own parser. Of course, it too can't deal >> with eval'ing and identifiers in XML, but I'm not sure that anything >> can. >> >> I've been toying with the idea of implementing this in clojure. >> >> Allen >> >> It would be fairly straightforward to modify the running clojure >> > > > > --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Namespace/Classpath Question
I have the following structure setup: In ~/src/foo/bar/alpha.clj : (ns foo.bar.alpha (:require (foo.bar beta))) (println (get-stuff)) In ~/src/foo/bar/beta.clj : (ns foo.bar.beta) (defn get-stuff [] "from beta") When I run this command: java -cp .:~/src/clojure/clojure.jar clojure.lang.Script foo/bar/ alpha.clj I get this error: Exception in thread "main" java.lang.Exception: Unable to resolve symbol: get-stuff in this context (alpha.clj:4) I am relatively new to the Java world, so I'm sure I'm missing something regarding the classpath or the namespace. Thanks, Kevin Albrecht --~--~-~--~~~---~--~~ 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: Namespace/Classpath Question
On Jan 16, 2009, at 5:01 PM, Kevin Albrecht wrote: In ~/src/foo/bar/alpha.clj : (ns foo.bar.alpha (:require (foo.bar beta))) (println (get-stuff)) The :require clause succeeded in loading foo.bar.beta, but :require does not bring get-stuff into namespace foo.bar.alpha. You can solve this by qualifying get-stuff's namespace when you call it: (println (foo.bar.beta/get-stuff)) or by using the :as option in :require to give foo.bar.beta a shorter alias and qualifying with that in the call: (:require (foo.bar [beta :as beta]))) (println (beta/get-stuff)) or by using :use instead of :require: (:use (foo.bar [beta :only (get-stuff)]))) --Steve smime.p7s Description: S/MIME cryptographic signature
Re: Macros in interaction with Functions
Stuart Sierra said: > It's not covered much. You get used to it. Think of it this way -- macros > only exist during compilation. Functions like "apply" get evaluated at > run-time. A macro like "and" has no value at run-time, so you can't use it > as an argument to a function. I'll tell you my current understanding of how Clojure works, so you can correct me where I may be wrong: - The compiler has for target a living environment; thus, it's dynamic. - There's no interpreter; thus, the following points will be easier to reason about. - When code is sent for evaluation, it's first read. - The reader performs a few substitutions, then gives the resulting code to the compiler. - The compiler starts by expanding macros into their substitution. --- Thus, for functions, there's no such thing as macros. --- Thus, all that functions see of macros is what came out of macros' complete expansion. --- Therefore, like Timothy Pratley wrote so well, a function can have for parameter a macro call, but not a macro itself. - After macro expansion, the compiler starts compiling all functions in need of being compiled, including the functions modified during macro expansion. - Then, code is ready for evaluation. Now, I see that (function macro arg-given-to-macro-by-function) can't work, because 'function', in its body, during its evaluation, would have to give 'arg-given...' to 'macro'; but since 'function' is a function, before eval was inside 'function's body, it needed to evaluate each one of 'function's parameters; thus, at this precise moment, 'macro' would have said "hey, now that you're evaluating me, will you please give me my parameter?", and eval would have answered "I can't, its 'function's responsibility, but we're not yet inside its body", and thus, eval would have blocked. Ok, so although it's a live system, when a new bunch of code is sent for evaluation, all macros inside it must be expanded before runtime evaluation can occur. Thus, functions can't act on macros. I thought that somehow my code could still work because what would have happened is 'reduce' would have acted on 'and's expansion, but I see and's expansion couldn't be done because it would have to wait for reduce's evaluation. If we were speaking of concurrency, wouldn't this be a deadlock issue? ...I also thought it could be possible that 'and' expands to a partial application that waits for 'reduce' to provide it its arguments. Wouldn't this make sense? Konrad Hinsen said: > The universal workaround is to define a > function that contains nothing but the macro, such as > > (fn [x y] (and x y)) > > which can also be written in Clojure using the shorthand notation > > #(and %1 %2) > > Here the macro gets expanded inside the function *body*, but what you > pass around is the function *object*. Wouldn't this defeat the purpose of having 'and's arguments short- circuited when false is found? Now, why is this workaround possible? For sure, the wrapper function is ok as a parameter of a function call. And in the called function's body, when it's going to call the wrapper function, the arguments for the macro wrapped in the wrapper function will be ready. And the wrapper function contains the macro's substitution anyways. So if we're willing to sacrifice macros' lazy parameters evaluation, we can wrap them inside functions to achieve this effect. We could also say that as long as macros are either called or wrapped in any function, they can go anywhere. In other words, the only limitation seems to be that runtime code can't use the symbol to which a macro is binded. Phew, does this all make perfect sense? Chouser said: >>> Is there anyway to write a macro/function that acts as a function when >>> necessary (so it can be passed as an argument), but expands into a >>> macro (for speed) when deemed possible? >> I don't think this is possible without some sort of support for a >> macro/function duality in core Clojure. > Which is one way to describe what's provided by definline. It's > marked experimental, has an unusual format and proviso's, but it's > there get a blend of macro performance and function first-classness. Cool. Let's see how this develops. It's definitely interesting. ...All those years doing imperative programming, I knew I somehow wasn't doing what I really always wanted to do. ...Anyways, before I devote 100% of my programming time to macro-ed functional languages, I want to get rid of the imperative way of programming as much as possible, so I thought it might be good for me to do a small detour by learning Haskell before coming back full strength to Clojure and Qi +CL. If someone has any opinion about this, I'm all ears open. --~--~-~--~~~---~--~~ 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..
Re: configurable bash script to launch Clojure available
I guess another way would be to just rebind *command-line-script* to nil on subsequent loads? It doesn't feel like an complete solution but I believe it covers the use cases discussed so far. --~--~-~--~~~---~--~~ 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: configurable bash script to launch Clojure available
On Jan 16, 2009, at 7:36 PM, Timothy Pratley wrote: I guess another way would be to just rebind *command-line-script* to nil on subsequent loads? It doesn't feel like an complete solution but I believe it covers the use cases discussed so far. That could work, but I think this kind of mechanism should operate at the lowest level "load" bottleneck to ensure it's correctly implemented. Making that low level code aware of a high level concept like *command-line-script* seems to be a less maintainable design than we should strive for. --Steve smime.p7s Description: S/MIME cryptographic signature
QT Jambi and the Repl
Has anyone here had success in using Clojure with QT Jambi? I'm currently experimenting with porting my app from Swing to QT, and although Jambi might well be the theoretically superior framework, it seems like Swing is a lot easier to use with Clojure. The issue I'm currently running into is that you can't call any methods on QT gui objects unless you're in the same thread they were created in. But that can't be the Repl thread, because QApplication.exec() basically sets up an event loop and takes control of whatever thread you start it in. So, it looks like I can't do any of that cool interactive gui development that I fell in love with in Rich's presentations, and have continued to love using myself. Am I missing something? I thought I'd give QT a try, since everyone seems to rave about it, but so far, in most ways, Swing seems easier to use and more powerful. But maybe I'm just not familiar enough with Jambi. Many thanks, -Luke --~--~-~--~~~---~--~~ 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: QT Jambi and the Repl
On Jan 16, 5:38 pm, levand wrote: > Has anyone here had success in using Clojure with QT Jambi? > > I'm currently experimenting with porting my app from Swing to QT, and > although Jambi might well be the theoretically superior framework, it > seems like Swing is a lot easier to use with Clojure. > > The issue I'm currently running into is that you can't call any > methods on QT gui objects unless you're in the same thread they were > created in. But that can't be the Repl thread, because > QApplication.exec() basically sets up an event loop and takes control > of whatever thread you start it in. > > So, it looks like I can't do any of that cool interactive gui > development that I fell in love with in Rich's presentations, and have > continued to love using myself. > > Am I missing something? I thought I'd give QT a try, since everyone > seems to rave about it, but so far, in most ways, Swing seems easier > to use and more powerful. But maybe I'm just not familiar enough with > Jambi. > > Many thanks, > -Luke I have had some success writing a little app[1] in Qt Jambi in Clojure, for what it's worth. You can use QCoreApplication/ invokeLater or invokeAndWait to mess with Qt objects from different threads. I have managed to segfault the JVM while poking a running Qt Jambi app from a REPL. I also had some problems with memory leaks [2] for a time. It's not as stable and solid as Swing. It works though, and Qt is a nice framework to work with. [1]: http://github.com/briancarper/bcc-clojure/tree/master [2]: Most likely this issue: http://www.mail-archive.com/qt-jambi-inter...@trolltech.com/msg00592.html --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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 -~--~~~~--~~--~--~---
javadoc.clj
This is very useful. Thanks for doing it. On windows xp find-javadoc-url would not work for local javadocs, maybe because of window's "c:\xx" syntax. Using (.toURL file) seemed to fix it. Maybe that will work for the other systems also. (defn find-javadoc-url "Searches for a URL for the given class name. Tries *local-javadocs* first, then *remote-javadocs*. Returns a string." [classname] (let [file-path (.replace classname \. File/separatorChar) url-path (.replace classname \. \/)] (if-let [file (first (filter #(.exists %) (map #(File. % (str file-path ".html")) @*local-javadocs*)))] (.toExternalForm (.toURL file)) ;; If no local file, try remote URLs: (some (fn [[prefix url]] (when (.startsWith classname prefix) (str url url-path ".html"))) @*remote-javadocs* Thanks again --~--~-~--~~~---~--~~ 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 it type hint?
Hi, is #^ type hint below? I don't see any type at all. It's from clojure core. (def #^{:arglists '([& items]) :doc "Creates a new list containing the items."} list (. clojure.lang.PersistentList creator)) --~--~-~--~~~---~--~~ 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 it type hint?
Just made sense to me today as well. #^Class is short form for saying set the metadata for the symbol being defined (in this case list) to the map {:tag Class}. #^ is a reader macro for setting metadata for the compiler. That code is simple tagging the symbol clojure/list. (meta #'list) will give you the map representing the metadata. :tag is used by the compiler, but it's not clear to me in what cases... On Fri, Jan 16, 2009 at 9:46 PM, wubbie wrote: > > Hi, > > is #^ type hint below? I don't see any type at all. > It's from clojure core. > > > (def > #^{:arglists '([& items]) >:doc "Creates a new list containing the items."} > list (. clojure.lang.PersistentList creator)) > > > > --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Reading non-printing characters in the reader?
Question: How do I read non-printing characters in the reader? When I call (char 3) at the REPL, it gives me \ and then the puts the ascii 3 to the output (under slime this shows up as \\003). But there seems to be no reader way to read these non-printing characters. There are special cases for \space, \newline, and \tab, but in general the only way to get one of these is by converting from somewhere else or using the char function. This isn't a super big deal, but it does seem like the reader should be able to read an arbitrary character literal. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---