Re: Newbie: Creating a macro that just calls a function but evaluates its arguments lazily
On 12.01.2009, at 01:01, samppi wrote: > The problem is that even though "some" and "filter" are lazy, "alt" is > still not, so calling "(alt (sub-function1 c) ...)" in the meta-meta- > function still evaluates (sub-function1 c), etc. It could be shown in > the REPL: How about changing the interface of alt to (defn alt [functions] ...) and pass it a lazy sequence of functions? 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: How to create and read from a stream of random characters?
> (defn seq-of-rand-strings [maxlength] > (repeatedly (fn [] > (apply str (take (rand-int maxlength) > (repeatedly #(char (+ (int \a) (rand-int 26) > > user=> (take 3 (seq-of-rand-strings 10)) > ("kae" "xwuwyp" "xa") Thanks Chouser. I learned some useful and interesting things from your reply. I was unaware of 'char and 'repeatedly. Gavin --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: when performance matters
On 12.01.2009, at 06:41, Mark P wrote: > 1. Some of the algorithms I use have the potential > to be parallelized. I am hoping that as the number > of cores in PCs increase, at some point Clojure's > performance will beat C++'s due to Clojure's > superior utilization of multiple cores. (Any ideas > on how many cores are needed for this to become > true?) It all depends on your algorithms and your code. Clojure has lots of support (data structures and algorithms) for concurrent programming, but you have to choose and combine them yourself to get efficient parallelization. > 2. The JVM is continually being improved. Hopefully > in a year or two, the performance of HotSpot will be > closer to that of C++. (But maybe this is just > wishful thinking.) Again this depends a lot on what you are doing. Hotspot is already doing an impressive job on some applications, but remains bad at others. Optimization of a JIT compiler is quite different from optimization by hand: the compiler knows nothing about your algorithm at large that could help it to speed up execution, but on the other hand it knows where optimization is really useful and it can create specialized code versions that no sane person would ever attempt to write by hand. > 3. Maybe I can implement certain performance critical > components in C++ via the JNI. (But I get the impression > that JNI itself isn't particularly efficient. Also, the more > I pull over into the C++ side, the fewer advantages to > using Clojure.) I also wish there were a better interface between the Java world and the C world than JNI. Perhaps there is? I'd happily trade some safety for performance. One source of hope for better interfaces is new virtual machines. One candidate is VMKit (http://vmkit.llvm.org/), an implementation of the JVM (and .Net as well) on top of LLVM. Combine this with the gcc version that produces LLVM code, and it should be possible to get Java-C interoperability with much less friction than through the JNI. On the other hand, it will be a long time before VMKit matches the performance of HotSpot. > If all else fails, maybe I could use Clojure as a prototyping > language. Then when I get it right, I code up the actual > programs in C++. But probably a lot would get lost in > the translation from Clojure -> C++ so would it be worth > it? You could also consider writing Clojure code that generates C++ code. Or C, or why not directly LLVM. > I'd love to be convinced that Clojure is a viable choice, > but I need to be a realist too. So what do people think? I am in a very similar situation if I ever want to use Clojure in my professional environment. For the moment I have decided that Clojure is fun enough to explore even if I never will use it professionally, so it's not an immediate concern. Time will tell what can be done realistically. 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 -~--~~~~--~~--~--~---
YACS - Yes another one (Snake that is)
Hi, Following in a growing tradition I have written YACS (Yet Another Clojure Snake); this one uses an Agent to hold the state and has separate GUI and model threads using invokeLater to update the GUI from the model in a thread safe way. At least that was the plan. My specific aims were to practice use a more complex agent and to comunicate with the EDT correctly. I would very much appreciate any comments on the correctness (especially of the agent code) and of any Clojure idioms I could have used to simplify or improve it. Thanks Tom --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~--- yacs.clj Description: Binary data
Re: when performance matters
On Mon, Jan 12, 2009 at 6:41 AM, Mark P wrote: > 1. Some of the algorithms I use have the potential > to be parallelized. I am hoping that as the number > of cores in PCs increase, at some point Clojure's > performance will beat C++'s due to Clojure's > superior utilization of multiple cores. (Any ideas > on how many cores are needed for this to become > true?) Asuming the right algorithm, single-threaded C++ and no reflection or boxing overhead in Clojure, then I think 2 will do. > > 2. The JVM is continually being improved. Hopefully > in a year or two, the performance of HotSpot will be > closer to that of C++. (But maybe this is just > wishful thinking.) We're already there. As Konrad said, they optimize differently so objective testing is hard. I think that Java is behind on optimizing cache locality because the structure of the typical Java program makes this a harder problem, that's what I've heard anyway. Sun has some wiki pages on HotSpot specific optmization techniques, which might come in handy when you want to squeeze those last 5% of performance. > > 3. Maybe I can implement certain performance critical > components in C++ via the JNI. (But I get the impression > that JNI itself isn't particularly efficient. Also, the more > I pull over into the C++ side, the fewer advantages to > using Clojure.) JNA might be an alternative to JNI: https://jna.dev.java.net/ But I wouldn't know; haven't used either. But instead of interfacing with C++, you might find that simply interfacing with Java will provide enough of a boost in those super-critical sections. Unless, that is, if your C++ is using dirty tricks like CUDA and what-ever-the-AMD-version-is-called. :) > > If all else fails, maybe I could use Clojure as a prototyping > language. Then when I get it right, I code up the actual > programs in C++. But probably a lot would get lost in > the translation from Clojure -> C++ so would it be worth > it? > > I'd love to be convinced that Clojure is a viable choice, > but I need to be a realist too. So what do people think? > How realistic are my three "hopes"? And are there > any other performance enhancing possibilities that I > have not taken into account? > > Thanks, > > Mark P. > > > > -- 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: YACS - Yes another one (Snake that is)
For example, I am pretty sure I don't need to wrap 'send' in 'dosync' (it works without it). Tom 2009/1/12 Tom Ayerst > Hi, > > Following in a growing tradition I have written YACS (Yet Another Clojure > Snake); this one uses an Agent to hold the state and has separate GUI and > model threads using > invokeLater to update the GUI from the model in a thread safe way. At > least that was the plan. > > My specific aims were to practice use a more complex agent and to > comunicate with the EDT correctly. > > I would very much appreciate any comments on the correctness (especially of > the agent code) and of any Clojure idioms I could have used to simplify or > improve it. > > Thanks > > Tom > --~--~-~--~~~---~--~~ You 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 can I be useful to Clojure?
Hey, I would like to contribute to Clojure but I'm not a language designer, neither familiar with LISP :( How can I be useful to Clojure project? Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
What is a LISP dialect?
Hey, Clojure is described as a modern dialect of LISP. What is a "LISP dialect"? Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: What is a LISP dialect?
Lisp languages stem from the general concept of representing a program as a data structure made up of lists. Hence, LISt Processing. There are a lot of variations in how things can work though, for example how variables are scoped and bound, how variables and functions are referenced, the built-in functions, how macros work, etc. You should do a bit of wikipedia reading and googling though, because this is a rich, interesting topic that is worth exploring, and it is probably too general a question for this list. Cheers, Jeff HB wrote: > Hey, > Clojure is described as a modern dialect of LISP. > What is a "LISP dialect"? > Thanks. > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: when performance matters
This might help: java libraries for fast computing. I guess they will be usable from within clojure as well. http://acs.lbl.gov/~hoschek/colt/ Welcome to the Colt Project. Colt provides a set of Open Source Libraries for High Performance Scientific and Technical Computing in Java. Scientific and technical computing, as, for example, carried out at CERN, is characterized by demanding problem sizes and a need for high performance at reasonably small memory footprint. There is a perception by many that the Java language is unsuited for such work. However, recent trends in its evolution suggest that it may soon be a major player in performance sensitive scientific and technical computing. For example, IBM Watson's Ninja project showed that Java can indeed perform BLAS matrix computations up to 90% as fast as optimized Fortran. The Java Grande Forum Numerics Working Group provides a focal point for information on numerical computing in Java. With the performance gap steadily closing, Java has recently found increased adoption in the field. The reasons include ease of use, cross-platform nature, built-in support for multi-threading, network friendly APIs and a healthy pool of available developers. Still, these efforts are to a significant degree hindered by the lack of foundation toolkits broadly available and conveniently accessible in C and Fortran. I ran into these when fiddling with JUNG, as I'll be drawing networks soon. Another speedup I recently managed to integrate in clojure into a simulation is the brics automaton regular expression engine, which is faster than java regex engine. Good luck! On 12 jan, 10:42, "Christian Vest Hansen" wrote: > On Mon, Jan 12, 2009 at 6:41 AM, Mark P wrote: > > 1. Some of the algorithms I use have the potential > > to be parallelized. I am hoping that as the number > > of cores in PCs increase, at some point Clojure's > > performance will beat C++'s due to Clojure's > > superior utilization of multiple cores. (Any ideas > > on how many cores are needed for this to become > > true?) > > Asuming the right algorithm, single-threaded C++ and no reflection or > boxing overhead in Clojure, then I think 2 will do. > > > > > 2. The JVM is continually being improved. Hopefully > > in a year or two, the performance of HotSpot will be > > closer to that of C++. (But maybe this is just > > wishful thinking.) > > We're already there. As Konrad said, they optimize differently so > objective testing is hard. I think that Java is behind on optimizing > cache locality because the structure of the typical Java program makes > this a harder problem, that's what I've heard anyway. > > Sun has some wiki pages on HotSpot specific optmization techniques, > which might come in handy when you want to squeeze those last 5% of > performance. > > > > > 3. Maybe I can implement certain performance critical > > components in C++ via the JNI. (But I get the impression > > that JNI itself isn't particularly efficient. Also, the more > > I pull over into the C++ side, the fewer advantages to > > using Clojure.) > > JNA might be an alternative to JNI:https://jna.dev.java.net/ > But I wouldn't know; haven't used either. > > But instead of interfacing with C++, you might find that simply > interfacing with Java will provide enough of a boost in those > super-critical sections. Unless, that is, if your C++ is using dirty > tricks like CUDA and what-ever-the-AMD-version-is-called. :) > > > > > > > > > If all else fails, maybe I could use Clojure as a prototyping > > language. Then when I get it right, I code up the actual > > programs in C++. But probably a lot would get lost in > > the translation from Clojure -> C++ so would it be worth > > it? > > > I'd love to be convinced that Clojure is a viable choice, > > but I need to be a realist too. So what do people think? > > How realistic are my three "hopes"? And are there > > any other performance enhancing possibilities that I > > have not taken into account? > > > Thanks, > > > Mark P. > > -- > Venlig hilsen / Kind regards, > Christian Vest Hansen.- Tekst uit oorspronkelijk bericht niet weergeven - > > - Tekst uit oorspronkelijk bericht weergeven - --~--~-~--~~~---~--~~ You 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 can I be useful to Clojure?
1Learn Clojure 2Use it to solve real problems 3Help other people learn it 4Give feedback to Rich about issues so he can improve the implementation 5Maybe submit some useful generic pieces to Clojure Contrib 6Develop the first Killer App (Personally I'm still on 1 / 2) Cheers Tom 2009/1/12 HB > > Hey, > I would like to contribute to Clojure but I'm not a language designer, > neither familiar with LISP :( > How can I be useful to Clojure project? > Thanks. > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: YACS - Yes another one (Snake that is)
What is (Yet Another Clojure Snake)? Something like YACC? On Jan 12, 1:15 pm, "Tom Ayerst" wrote: > For example, I am pretty sure I don't need to wrap 'send' in 'dosync' (it > works without it). > > Tom > > 2009/1/12 Tom Ayerst > > > Hi, > > > Following in a growing tradition I have written YACS (Yet Another Clojure > > Snake); this one uses an Agent to hold the state and has separate GUI and > > model threads using > > invokeLater to update the GUI from the model in a thread safe way. At > > least that was the plan. > > > My specific aims were to practice use a more complex agent and to > > comunicate with the EDT correctly. > > > I would very much appreciate any comments on the correctness (especially of > > the agent code) and of any Clojure idioms I could have used to simplify or > > improve it. > > > Thanks > > > Tom --~--~-~--~~~---~--~~ You 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: YACS - Yes another one (Snake that is)
I just knew someone would say that ;-) (Your acronymic options shrink once you start with Yet Another... ) If you haven't been following, search for Clojure Snake earlier in the list (or run the code). Cheers Tom 2009/1/12 HB > > What is (Yet Another Clojure Snake)? > Something like YACC? > > On Jan 12, 1:15 pm, "Tom Ayerst" wrote: > > For example, I am pretty sure I don't need to wrap 'send' in 'dosync' (it > > works without it). > > > > Tom > > > > 2009/1/12 Tom Ayerst > > > > > Hi, > > > > > Following in a growing tradition I have written YACS (Yet Another > Clojure > > > Snake); this one uses an Agent to hold the state and has separate GUI > and > > > model threads using > > > invokeLater to update the GUI from the model in a thread safe way. At > > > least that was the plan. > > > > > My specific aims were to practice use a more complex agent and to > > > comunicate with the EDT correctly. > > > > > I would very much appreciate any comments on the correctness > (especially of > > > the agent code) and of any Clojure idioms I could have used to simplify > or > > > improve it. > > > > > Thanks > > > > > Tom > > > --~--~-~--~~~---~--~~ You 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: Creating a macro that just calls a function but evaluates its arguments lazily
Not a macro, but does what you want: (defn alt [& functions] (fn [tokens] (some #((force %) tokens) functions))) ;define sub-functions the same way (defn a-meta-meta-function [c] (alt (delay (sub-function1 c)) (delay (sub-function2 c)) (delay (sub- function3 c --~--~-~--~~~---~--~~ You 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: YACS - Yes another one (Snake that is)
On Mon, Jan 12, 2009 at 5:15 AM, Tom Ayerst wrote: > For example, I am pretty sure I don't need to wrap 'send' in 'dosync' (it > works without it). Right. dosync starts a transaction. Agents and Atoms aren't affected by transactions. You only need dosync when working with Refs. > 2009/1/12 Tom Ayerst >> >> Hi, >> >> Following in a growing tradition I have written YACS (Yet Another Clojure >> Snake); this one uses an Agent to hold the state and has separate GUI and >> model threads using >> invokeLater to update the GUI from the model in a thread safe way. At >> least that was the plan. >> >> My specific aims were to practice use a more complex agent and to >> comunicate with the EDT correctly. >> >> I would very much appreciate any comments on the correctness (especially >> of the agent code) and of any Clojure idioms I could have used to simplify >> or improve it. -- 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: YACS - Yes another one (Snake that is)
On Mon, Jan 12, 2009 at 9:01 AM, Mark Volkmann wrote: > > On Mon, Jan 12, 2009 at 5:15 AM, Tom Ayerst wrote: >> For example, I am pretty sure I don't need to wrap 'send' in 'dosync' (it >> works without it). > > Right. dosync starts a transaction. Agents and Atoms aren't affected > by transactions. You only need dosync when working with Refs. That's not quite true. Agents are "affected" to the extent that 'send' and 'send-off' operations done inside a 'dosync' are held until the transaction commits before being sent. Maybe you didn't mean to say otherwise, but I thought I'd mention it in case. --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: newbie question on binding
On Tue, Jan 6, 2009 at 12:00 AM, wubbie wrote: > > Hi, > Why are there multiple "Logging str" output. Because str calls itself recursively. > Also in (apply str-orig args), I don't see any args passed at all! I'm not sure what you mean here. The "args" in (apply str-orig args) is the list of arguments that are passed to str-orig. -- Michael Wood --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: YACS - Yes another one (Snake that is)
On Mon, Jan 12, 2009 at 8:27 AM, Chouser wrote: > > On Mon, Jan 12, 2009 at 9:01 AM, Mark Volkmann > wrote: >> >> On Mon, Jan 12, 2009 at 5:15 AM, Tom Ayerst wrote: >>> For example, I am pretty sure I don't need to wrap 'send' in 'dosync' (it >>> works without it). >> >> Right. dosync starts a transaction. Agents and Atoms aren't affected >> by transactions. You only need dosync when working with Refs. > > That's not quite true. Agents are "affected" to the extent that > 'send' and 'send-off' operations done inside a 'dosync' are held until > the transaction commits before being sent. Maybe you didn't mean to > say otherwise, but I thought I'd mention it in case. Ah ... good clarification. Thanks for reminding me about 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 -~--~~~~--~~--~--~---
sending off 1,10,100,1000,10k,100k agents to do fib is fine, but 1M agents not
Hi All. While familiarizing myself with different ways of making my models concurrent, I ran into something that might be a bug. given this code, and a 4core machine: (defn fib [n] (if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2) (defn pow "from the tiny math library" [x# y#] (. java.lang.Math (pow #^java.lang.Double x# #^java.lang.Double y#))) (dotimes [t 7] (time (let [agents (for [i (range (pow 10 t))] (agent 15))] (do (println (pow 10 t) "fib 15 agents send-off") (doseq [a agents] (send-off a fib)) (apply await agents) I get this output: 1.0 fib 15 agents send-off "Elapsed time: 1.120026 msecs" 10.0 fib 15 agents send-off "Elapsed time: 1.853112 msecs" 100.0 fib 15 agents send-off "Elapsed time: 13.192213 msecs" 1000.0 fib 15 agents send-off "Elapsed time: 106.954241 msecs" 1.0 fib 15 agents send-off "Elapsed time: 1117.189967 msecs" 10.0 fib 15 agents send-off "Elapsed time: 11377.972402 msecs" 100.0 fib 15 agents send-off java.lang.OutOfMemoryError: Java heap space (NO_SOURCE_FILE:0) [Thrown class clojure.lang.Compiler$CompilerException] Restarts: 0: [ABORT] Return to SLIME's top level. 1: [CAUSE] Throw cause of this exception Backtrace: 0: clojure.lang.Compiler.eval(Compiler.java:4127) 1: clojure.core$eval__3503.invoke(core.clj:1463) 2: swank.commands.basic$eval_region__557.invoke(basic.clj:35) 3: swank.commands.basic$interactive_eval__563.invoke(basic.clj:44) 4: clojure.lang.Var.invoke(Var.java:327) 5: user$eval__1383.invoke(Unknown Source) 6: clojure.lang.Compiler.eval(Compiler.java:4116) 7: clojure.core$eval__3503.invoke(core.clj:1463) 8: swank.core$eval_in_emacs_package__266.invoke(core.clj:53) 9: swank.core$eval_for_emacs__339.invoke(core.clj:120) 10: clojure.lang.Var.invoke(Var.java:335) 11: clojure.lang.AFn.applyToHelper(AFn.java:199) 12: clojure.lang.Var.applyTo(Var.java:444) 13: clojure.core$apply__2841.doInvoke(core.clj:374) 14: clojure.lang.RestFn.invoke(RestFn.java:428) 15: swank.core$eval_from_control__269.invoke(core.clj:60) 16: swank.core$spawn_worker_thread__342$fn__370$fn__372.invoke (core.clj:144) 17: clojure.lang.AFn.applyToHelper(AFn.java:191) 18: clojure.lang.AFn.applyTo(AFn.java:184) 19: clojure.core$apply__2841.doInvoke(core.clj:374) 20: clojure.lang.RestFn.invoke(RestFn.java:428) 21: swank.core$spawn_worker_thread__342$fn__370.doInvoke(core.clj: 142) 22: clojure.lang.RestFn.invoke(RestFn.java:402) 23: clojure.lang.AFn.run(AFn.java:38) 24: java.lang.Thread.run(Unknown Source) (something goes wrong when sending off a million agents, and for a while I am only using 1 of the four CPU's.) (using send or send-off doesn't seem to make a difference here, performance or crash-wise) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: when performance matters
Okay, I'm one of Clojure's biggest fans, and probably one of a very few using it regularly at work. But let me attempt to inject some reality into the discussion. The big advantages of Clojure are succinctness and expressiveness within a Java environment. If you have highly-optimized, custom-designed numerical algorithms written in a low-level language like C++, you will never be able to write a version that is equally fast in a dynamic, virtual-machine language. Compilers are smart, but they are not that smart. Relying on constantly-improving compilers is a dangerous wager. Parallelism may help, but adapting non-parallel algorithms to parallel computation is fiendishly difficult, and the performance aspects of parallel computing are net yet well understood. That being said, experience is the only reliable guide. If you want to know if Clojure will work for your job, the only thing to do is try it. -Stuart Sierra On Jan 12, 12:41 am, Mark P wrote: > I have recently found out about Clojure and am > rather impressed. I am seriously considering > whether Clojure is a viable language for use at > work. The main stumbling block would be if > performance (both speed and memory) turns out > to be insufficent. I currently use C++, but I'd love > to be able to leave C++ behind and use Clojure > (or similar) instead. > > The programs I write perform applied mathematical > optimization (using mainly integer arithmetic) > and often take hours (occasionally even days) > to run. So even small percentage improvements > in execution speed can make a significant > practical difference. And large problems can use > a large amount of memory - so memory efficiency > is also a concern. > > Given these performance considerations, at first > glance Clojure does not seem like a good choice. > But I don't want to give up on the idea just yet. > The allure of modernized lisp-style programming > is really tempting. > > There are three key factors that still give me > hope: > > 1. Some of the algorithms I use have the potential > to be parallelized. I am hoping that as the number > of cores in PCs increase, at some point Clojure's > performance will beat C++'s due to Clojure's > superior utilization of multiple cores. (Any ideas > on how many cores are needed for this to become > true?) > > 2. The JVM is continually being improved. Hopefully > in a year or two, the performance of HotSpot will be > closer to that of C++. (But maybe this is just > wishful thinking.) > > 3. Maybe I can implement certain performance critical > components in C++ via the JNI. (But I get the impression > that JNI itself isn't particularly efficient. Also, the more > I pull over into the C++ side, the fewer advantages to > using Clojure.) > > If all else fails, maybe I could use Clojure as a prototyping > language. Then when I get it right, I code up the actual > programs in C++. But probably a lot would get lost in > the translation from Clojure -> C++ so would it be worth > it? > > I'd love to be convinced that Clojure is a viable choice, > but I need to be a realist too. So what do people think? > How realistic are my three "hopes"? And are there > any other performance enhancing possibilities that I > have not taken into account? > > Thanks, > > Mark P. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Why aren't lists callable?
On Jan 12, 12:11 am, Mark Fredrickson wrote: > I can't imagine this idea will be met warmly, but I have a suggestion. > It requires ending maps and vectors as functions of keys. Instead, > make the first argument to a collection be a function which is mapped > to across the collection. Any additional arguments are passed to the > function on each invocation. For maps and hashes, this would only be > applied to the values. Keys would remain the same. > > Some examples: > ('(1 2 3) * 2) => (2 4 6) > ({:greet "hello" :farewell "goodbye"} str " Mark") => {:greet "hello > Mark" :farewell "goodbye Mark"} Hi Mark, I find the callable map VERY useful, and would hate to lose it. You can use maps for lots of things besides keyword=>value structures, and the callable map becomes more valuable in those situations. Your first example can be written almost as succinctly with map: (map #(* % 2) '(1 2 3)) ;;=> (2 4 6) The second is a little more complicated, but still doable: (reduce (fn [m [k v]] (assoc m k (str v " Mark"))) {} {:greet "hello" :farewell "goodbye"}) ;;=> {:farewell "goodbye Mark", :greet "hello Mark"} -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: Why aren't lists callable?
On Jan 12, 10:31 am, Stuart Sierra wrote: > On Jan 12, 12:11 am, Mark Fredrickson > wrote: > > > I can't imagine this idea will be met warmly, but I have a suggestion. > > It requires ending maps and vectors as functions of keys. Instead, > > make the first argument to a collection be a function which is mapped > > to across the collection. Any additional arguments are passed to the > > function on each invocation. For maps and hashes, this would only be > > applied to the values. Keys would remain the same. > > > Some examples: > > ('(1 2 3) * 2) => (2 4 6) > > ({:greet "hello" :farewell "goodbye"} str " Mark") => {:greet "hello > > Mark" :farewell "goodbye Mark"} > > Hi Mark, > > I find the callable map VERY useful, and would hate to lose it. You > can use maps for lots of things besides keyword=>value structures, and > the callable map becomes more valuable in those situations. > > Your first example can be written almost as succinctly with map: > > (map #(* % 2) '(1 2 3)) > ;;=> (2 4 6) > > The second is a little more complicated, but still doable: > > (reduce (fn [m [k v]] (assoc m k (str v " Mark"))) > {} {:greet "hello" :farewell "goodbye"}) > ;;=> {:farewell "goodbye Mark", :greet "hello Mark"} > I'd just like to add to this discussion that maps and vectors are functions not just because it's neat or possible, with the implementation one of many possibilities, but because they are associative, and associative collections are inherently functions of their keys/indices. Lists/seqs are not associative, thus not functions. Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Newbie: Creating a macro that just calls a function but evaluates its arguments lazily
Awesome—thanks for everyone's answers; I think I'll go with delay/ force. What I'm a little worried about is the caching. After a calling of "alt" finishes, what happens to all those Delay objects and their cached values? Are they garbage-collected, or will they remain indefinitely? Should I worry? On Jan 12, 6:13 am, MikeM wrote: > Not a macro, but does what you want: > > (defn alt [& functions] > (fn [tokens] > (some #((force %) tokens) functions))) > > ;define sub-functions the same way > > (defn a-meta-meta-function [c] > (alt (delay (sub-function1 c)) (delay (sub-function2 c)) (delay (sub- > function3 c --~--~-~--~~~---~--~~ You 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: Creating a macro that just calls a function but evaluates its arguments lazily
On Jan 12, 2009, at 17:11, samppi wrote: > Awesome—thanks for everyone's answers; I think I'll go with delay/ > force. What I'm a little worried about is the caching. After a calling > of "alt" finishes, what happens to all those Delay objects and their > cached values? Are they garbage-collected, or will they remain > indefinitely? Should I worry? They will be garbage-collected as soon as there is no more reference to the cached value. You needn't worry about this any more than for any other data item. What can become problematic (as has been discussed here recently) is very long or even infinite lazy sequences that are being cached. If some variable anywhere in the program holds on to a reference to the first item, then the calculated values will remain cached forever since nothing can be garbage collected. 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: Newbie: Creating a macro that just calls a function but evaluates its arguments lazily
> After a calling > of "alt" finishes, what happens to all those Delay objects and their > cached values? Are they garbage-collected, or will they remain > indefinitely? Should I worry? > I believe the references to the delays will be dropped as alt executes, so they'll be eligible for grabage collection. --~--~-~--~~~---~--~~ You 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: what does -> mean?
On Sun, Jan 11, 2009 at 9:12 PM, Mark Triggs wrote: > > I've also found this useful for accessing members in nested maps. For > example: > > (let [me {:person {:name {:first "Mark" >:last "Triggs"} > :email "mark.h.tri...@gmail.com"}}] >(-> me :person :name :first)) > > => "Mark" > > On Jan 12, 1:04 pm, kkw wrote: >> One use I've found for -> (though there are others I haven't come to >> appreciate yet) is when I have something like: >> (f1 (f2 (f3 (f4 x >> >> which can be re-written as >> (-> x f4 f3 f2 f1) >> >> I find the latter expression easier to read. >> >> Kev >> >> On Dec 30 2008, 2:49 pm, wubbie wrote: >> >> > Very criptic for newbie. >> > What does "Threads the expr through the forms." mean? >> > Does it create a thread to execute? >> >> > thanks >> > sun >> >> > On Dec 29, 10:07 pm, Paul Barry wrote: >> >> > > You can look up the documentation for a function/macro interactively >> > > from the repl: >> >> > > user=> (doc ->) >> > > - >> > > clojure.core/-> >> > > ([x form] [x form & more]) >> > > Macro >> > > Threads the expr through the forms. Inserts x as the >> > > second item in the first form, making a list of it if it is not a >> > > list already. If there are more forms, inserts the first form as the >> > > second item in second form, etc. >> > > nil >> >> > > On Dec 29, 8:27 pm, wubbie wrote: >> >> > > > Hi all, >> >> > > > Looking intoants.clj, I came across >> > > > (defn place [[x y]] >> > > > (-> world (nth x) (nth y))) >> >> > > > What -> mean here? >> >> > > > thanks >> > > > sun I initially stumbled on what -> is good for. But over time it makes more sense. I like to think of it as similar to this construct, which you often see in the Java world: Object result = object.doSomething().doSomethingElse().andMoreThings(); Of course the doSomethings could also be get*s() or what-have-you. /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: How can I be useful to Clojure?
If you have a blog, you may certainly write about your experience, the difficulties you encountered learning the language, etc. This can provide valuable help to other new users as well as give an indication of what the documentation should cover. On Jan 12, 4:21 am, HB wrote: > Hey, > I would like to contribute to Clojure but I'm not a language designer, > neither familiar with LISP :( > How can I be useful to Clojure project? > Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: newbie question on binding
Hi, I'm sorry. I wanted to answer you but it somehow got lost. Am 05.01.2009 um 23:00 schrieb wubbie: Why are there multiple "Logging str" output. As Michael already said, it's because the originial str calls itself recursively. Here is a thread, which explains this in more detail. http://groups.google.com/group/clojure/tree/browse_frm/thread/63ff934f1a2d4afd/0e97295c76f057e3?rnum=1&q=binding+str+logging&_done=%2Fgroup%2Fclojure%2Fbrowse_frm%2Fthread%2F63ff934f1a2d4afd%2F0e97295c76f057e3%3Flnk%3Dgst%26q%3Dbinding%2Bstr%2Blogging%26#doc_4e855da814b45e0b Also in (apply str-orig args), I don't see any args passed at all! Again: as Michael already said, the list of arguments to str-orig is contained in args. (apply str-orig [:a :b :c]) <=> (str-orig :a :b :c) Only the last argument to str-orig must be a sequable thing, like a vector or a list. Any arguments given directly are inserted before the arguments form the list. (apply str-orig 1 2 [:a :b :c]) <=> (str-orig 1 2 :a :b :c) Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Re: non recursive impl in presence of persistence?
On Jan 12, 5:24 am, e wrote: > It's funny, whenever I tried to be all safe like this and take the time to > make stuff safe in C++, coworkers would say, "we are grown-ups. At some > point you gotta stop being a paranoid programmer. Given that software bugs are a very common occurrence, I'd say we're far from being paranoid enough :) > Another thing is to make the common case easy . . . .and uh, mutable local > variables are pretty darn common, In imperative languages, yes, but not really in functional languages. I've written a fair amount of Clojure code, and I haven't used with- local-vars once. - James --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from 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: what does -> mean?
On Mon, Jan 12, 2009 at 11:15 AM, Michael Reid wrote: > > On Sun, Jan 11, 2009 at 9:12 PM, Mark Triggs wrote: >> >> I've also found this useful for accessing members in nested maps. For >> example: >> >> (let [me {:person {:name {:first "Mark" >>:last "Triggs"} >> :email "mark.h.tri...@gmail.com"}}] >>(-> me :person :name :first)) >> >> => "Mark" >> >> On Jan 12, 1:04 pm, kkw wrote: >>> One use I've found for -> (though there are others I haven't come to >>> appreciate yet) is when I have something like: >>> (f1 (f2 (f3 (f4 x >>> >>> which can be re-written as >>> (-> x f4 f3 f2 f1) >>> >>> I find the latter expression easier to read. >>> >>> Kev >>> >>> On Dec 30 2008, 2:49 pm, wubbie wrote: >>> >>> > Very criptic for newbie. >>> > What does "Threads the expr through the forms." mean? >>> > Does it create a thread to execute? >>> >>> > thanks >>> > sun >>> >>> > On Dec 29, 10:07 pm, Paul Barry wrote: >>> >>> > > You can look up the documentation for a function/macro interactively >>> > > from the repl: >>> >>> > > user=> (doc ->) >>> > > - >>> > > clojure.core/-> >>> > > ([x form] [x form & more]) >>> > > Macro >>> > > Threads the expr through the forms. Inserts x as the >>> > > second item in the first form, making a list of it if it is not a >>> > > list already. If there are more forms, inserts the first form as the >>> > > second item in second form, etc. >>> > > nil >>> >>> > > On Dec 29, 8:27 pm, wubbie wrote: >>> >>> > > > Hi all, >>> >>> > > > Looking intoants.clj, I came across >>> > > > (defn place [[x y]] >>> > > > (-> world (nth x) (nth y))) >>> >>> > > > What -> mean here? >>> >>> > > > thanks >>> > > > sun > > I initially stumbled on what -> is good for. But over time it makes > more sense. I like to think of it as similar to this construct, which > you often see in the Java world: > > Object result = object.doSomething().doSomethingElse().andMoreThings(); > > Of course the doSomethings could also be get*s() or what-have-you. While we're on this topic, don't forget the closely related doto function which calls many functions on the same object, unlike -> which calls many functions on the result of the previous function. Here's the example from the doc string. (doto (new java.util.HashMap) (.put "a" 1) (.put "b" 2)) -- 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: How to create and read from a stream of random characters?
Chouser's solution works well, but I found that you can end up with an empty string sometimes or never getting the maxlength that you passed in. 1:2 user=> (take 3 (seq-of-rand-strings 10)) ("ngene" "" "dwlbzndqx") I added an inc before calling the take and that clears things up. (defn seq-of-rand-strings [maxlength] (repeatedly (fn [] (apply str (take (inc (rand-int maxlength)) (repeatedly #(char (+ (int \a) (rand-int 26) On Mon, Jan 12, 2009 at 1:38 AM, GS wrote: > > > > (defn seq-of-rand-strings [maxlength] > > (repeatedly (fn [] > > (apply str (take (rand-int maxlength) > > (repeatedly #(char (+ (int \a) (rand-int 26) > > > > user=> (take 3 (seq-of-rand-strings 10)) > > ("kae" "xwuwyp" "xa") > > Thanks Chouser. I learned some useful and interesting things from > your reply. I was unaware of 'char and 'repeatedly. > > Gavin > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: what does -> mean?
Yeah, doto is a handy complement to ->. I forgot about doto, and there's a place some code which I'll use now. Thanks Mark! Kev On Jan 13, 6:38 am, "Mark Volkmann" wrote: > On Mon, Jan 12, 2009 at 11:15 AM, Michael Reid wrote: > > > On Sun, Jan 11, 2009 at 9:12 PM, Mark Triggs > > wrote: > > >> I've also found this useful for accessing members in nested maps. For > >> example: > > >> (let [me {:person {:name {:first "Mark" > >> :last "Triggs"} > >> :email "mark.h.tri...@gmail.com"}}] > >> (-> me :person :name :first)) > > >> => "Mark" > > >> On Jan 12, 1:04 pm, kkw wrote: > >>> One use I've found for -> (though there are others I haven't come to > >>> appreciate yet) is when I have something like: > >>> (f1 (f2 (f3 (f4 x > > >>> which can be re-written as > >>> (-> x f4 f3 f2 f1) > > >>> I find the latter expression easier to read. > > >>> Kev > > >>> On Dec 30 2008, 2:49 pm, wubbie wrote: > > >>> > Very criptic for newbie. > >>> > What does "Threads the expr through the forms." mean? > >>> > Does it create a thread to execute? > > >>> > thanks > >>> > sun > > >>> > On Dec 29, 10:07 pm, Paul Barry wrote: > > >>> > > You can look up the documentation for a function/macro interactively > >>> > > from the repl: > > >>> > > user=> (doc ->) > >>> > > - > >>> > > clojure.core/-> > >>> > > ([x form] [x form & more]) > >>> > > Macro > >>> > > Threads the expr through the forms. Inserts x as the > >>> > > second item in the first form, making a list of it if it is not a > >>> > > list already. If there are more forms, inserts the first form as the > >>> > > second item in second form, etc. > >>> > > nil > > >>> > > On Dec 29, 8:27 pm, wubbie wrote: > > >>> > > > Hi all, > > >>> > > > Looking intoants.clj, I came across > >>> > > > (defn place [[x y]] > >>> > > > (-> world (nth x) (nth y))) > > >>> > > > What -> mean here? > > >>> > > > thanks > >>> > > > sun > > > I initially stumbled on what -> is good for. But over time it makes > > more sense. I like to think of it as similar to this construct, which > > you often see in the Java world: > > > Object result = object.doSomething().doSomethingElse().andMoreThings(); > > > Of course the doSomethings could also be get*s() or what-have-you. > > While we're on this topic, don't forget the closely related doto > function which calls many functions on the same object, unlike -> > which calls many functions on the result of the previous function. > Here's the example from the doc string. > > (doto (new java.util.HashMap) (.put "a" 1) (.put "b" 2)) > > -- > R. Mark Volkmann > Object Computing, Inc. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Parameterized query with clojure.contrib.sql
I couldn't figure out how to do this with the included functions/ macros in clojure.contrib.sql so I massaged with-results and do- prepared together to get this macro (with supporting fn), which seems to work. Useful addition for contrib.sql? ;; query-with-results should work just like with-results, only parameterizing query variables. (defn- get-ps "Generate a prepared statement with a vector of parameters to support the query." [sql params] (let [ps (.prepareStatement (connection) sql)] (doseq [[index value] (map vector (iterate inc 1) params)] (.setObject ps index value)) ps)) (defmacro query-with-results "Executes a query with parameterized results and then evaluates body with results bound to a seq of the results. Example usage: (with-connection db (query-with-results res \"select * from mytable where name = ? or id = ?\" [\"Foo\" 3] (println res)))" [results sql params & body] `(with-open [stmt# (get-ps ~sql ~params) rset# (.executeQuery stmt#)] (let [~results (resultset-seq rset#)] ~...@body))) I would have liked to eliminate the helper function and just get this all into the macro, but I burned my allotted time on it before I got that working... -Greg On Jan 9, 5:05 pm, Greg Harman wrote: > Would someone mind posting an example of a parameterized query using > clojure.contrib.sql? There are examples in the source of non- > parameterized queries, and do-prepared is used to parameterize values > for inserts, but I can't seem to get my form quite right for a query. > > thanks, > 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 -~--~~~~--~~--~--~---
Example Java oriented SWT GUI application in Clojure
Here is an example SWT application. It is a 'search' tool. Open a file and the search term is highlighted. It has a java oriented approach because I copied the java code verbatim. This might be useful if you are still used to imperative programming. Main source: http://jvmnotebook.googlecode.com/svn/trunk/clojure/swt/search/src/octane_main.clj Additional Files (all you really need is what is in the lib directory) http://jvmnotebook.googlecode.com/svn/trunk/clojure/swt/search But, I am all ears for suggestions (I am sure there are very, very many) and if you want, send me a patch file, I will be glad to update it. Might help for newbies like me. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Strange 'new' constructor error
Just a bug in my code, sorry. On Jan 9, 6:49 pm, BerlinBrown wrote: > Does anyone see what I am doing here. I am creating someSWTcode. > > > > (import '(org.eclipse.swt.widgets Display Shell Text Widget)) > (import '(org.eclipse.swt.widgets Label Menu MenuItem Control)) > (import '(org.eclipse.swt.widgets FileDialog MessageBox)) > > (defn create-menu-bar [sh] > (let [bar (new Menu sh (.SWTBAR))] > (. sh setMenuBar bar) > (doto bar > (. (new MenuItem (.SWTCASCADE))) > (. setText (. resources getString "Window_title") > > - > > Here is some similar code that works, > > (defn build-menu-bar [sh] > (let [menu-bar (new Menu sh (.SWTBAR))] > (doto (new MenuItem menu-bar (.SWTCASCADE)) > (setText "&File")) > menu-bar)) > > But I keep getting this error. > > java.lang.IllegalArgumentException: No matching method found: new for > class org. > eclipse.swt.widgets.Menu (octane_main.clj:0) > at clojure.lang.Compiler.eval(Compiler.java:4153) > at clojure.lang.Compiler.load(Compiler.java:4470) > at clojure.lang.Compiler.loadFile(Compiler.java:4437) > at clojure.lang.Repl.main(Repl.java:66) > Caused by: java.lang.IllegalArgumentException: No matching method > found: new for > class org.eclipse.swt.widgets.Menu > at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java: > 48) > at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java: > 28) > at user$create_menu_bar__50.invoke(octane_main.clj:71) > at user$simple_swt__68.invoke(octane_main.clj:99) > at user$main__72.invoke(octane_main.clj:116) > at user$eval__75.invoke(octane_main.clj:118) > at clojure.lang.Compiler.eval(Compiler.java:4142) > ... 3 more > Clojure > > Here is the constructor of the Super Class of Menu. > public Widget(Widget arg0, int arg1) > > Strange. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Why aren't lists callable?
For mapping across maps I often find the following utility helpful: (defn map-map "Like map, but expects f to produce pairs that are combined to produce a map output." [f & maps] (reduce #(conj %1 %2) {} (apply map f maps))) 1:1 user=> (map-map (fn [[k v]] [k (str v " Mark")]) {:greet "hello" :farewell "goodbye"}) {:farewell "goodbye Mark", :greet "hello Mark"} -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: sending off 1,10,100,1000,10k,100k agents to do fib is fine, but 1M agents not
Hi Boris > (something goes wrong when sending off a million agents, and for a > while I am only using 1 of the four CPU's.) > (using send or send-off doesn't seem to make a difference here, > performance or crash-wise) Your issue is not agent specific, consider this code which for me blows up with out of memory error: (dotimes [t 8] (time (let [numbers (for [i (range (pow 10 t))] 15)] (do (println (pow 10 t) "additions") (doseq [a numbers] (+ 1 a)) (doseq [a numbers] (+ 1 a)) (NB: I used pow 8 for raw numbers, however you can run out of memory with pow 7 using atoms) There was a recent thread about true lazyness which might provide a solution (not sure sorry). 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 -~--~~~~--~~--~--~---
Utilities for clojure.contrib?
Hi all, I've got lots of utilities that I think people might find useful, and might fit well in clojure.contrib (just sent in my contrib agreement last week). I don't know how the process works to get code in there, but I figured I'd go ahead and post them all here so people can chime in about what they like / don't like first. Some of these depend on each-other, but I think the collection as a whole is self-sufficient. ;;; Sequences. (defn combinations "Take a seq of seqs and return a lazy seq of ordered combinations (pick 1 from each seq)" [seqs] (if (empty? seqs) '(()) (forcat [item (first seqs)] (map #(cons item %) (combinations (rest seqs)) (defn power-set "Returns a lazy seq of possible subvectors of seq s." [s] (loop [s (seq s), sets [[]]] (if s (recur (rest s) (lazy-cat sets (map #(conj % (first s)) sets))) sets))) (defn random-permutation [s] "Return a random permutation of this seq." (let [arr (to-array s) len (alength arr)] (dotimes [i (dec len)] (let [r (+ i (rand-int (- len i))), prev (aget arr i)] (aset arr i (aget arr r)) (aset arr r prev))) (seq arr))) (defn random-element [s] "Return a random element of this seq" (nth s (rand-int (count s (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 (import '(java.util HashSet)) (defn distinct-elts? "Are all of the elements of this sequence distinct? Works on infinite sequences with repititions, making it useful for, e.g., detecting cycles in graphs." [s] (let [hs (HashSet.)] (loop [s (seq s)] (cond (empty? s)true (.contains hs (first s))false :else (do (.add hs (first s)) (recur (rest s))) (defn concat-elts "Lazily concatenate elements of a seq of seqs." [s] (when (seq s) (lazy-cat (first s) (concat-elts (rest s) (defn lazy-mapcat "Like mapcat but is lazy like map" [f s] (concat-elts (map f s))) (defn map-when "Like map but discards logically false entries" [fn & seqs] (filter identity (apply map fn seqs))) (defn iterate-while [f x] (take-while identity (iterate f x))) (defn chunk "Lazily break s into chunks of length n (or less, for the final chunk)." [n s] (when (seq s) (lazy-cons (take n s) (chunk n (drop n s) (defn mevery? "Like every but takes multiple seq args like map." ([f & seqs] (or (some empty? seqs) (and (apply f (map first seqs)) (recur f (map rest seqs)) ;;; Maps (defn map-map "Like map, but expects f to return pairs/map entries that are combined to make a map return value." [f & maps] (reduce #(conj %1 %2) {} (apply map f maps))) (defmacro lazy-get "Like get but lazy about evaluating the default value" [m k d] `(if-let [pair# (find ~m ~k)] (second pair#) ~d)) (defn safe-get "Like get but throws an exception if not found" [m k] (lazy-get m k (throw (IllegalArgumentException. (format "Key %s not found" k) (defn merge-agree "Like merge but returns nil if there are inconsistent key/value pairs." ([] {}) ([map] map) ([m1 m2 & maps] (when (every? (fn [[k v]] (= v (get m1 k v))) m2) (apply merge-agree (merge m1 m2) maps (defn merge-reduce "Combines maps, reducing sets of values with same key. Assumes nil value = not present. The first map entry must be a real map, but the remaining arguments can be seqs of map entries/key- value pairs." ([f ] {}) ([f m1 & maps] (reduce (fn [m [k v]] (if-let [v2 (get m k)] (assoc m k (f v2 v)) (assoc m k v))) m1 (concat-elts maps ;;; Miscellaneous (defn prln "Print all arguments and return the first argument" [& args] (do (println (apply print-str args)) (first args))) (defn xor [& args] (odd? (count (filter identity args (defmacro forcat "Like for, but concatenates the results." [& args] `(concat-elts (for ~...@args))) (defmacro assert-is "Like assert, but prints some more info (like is) about the offending form (may multiple eval on error)" ([form] `(assert-is ~form "")) ([form format-str & args] `(when-not ~form (throw (Exception. (str (format ~format-str ~...@args) ": Got " '~form " as " (cons '~(first form) (list ~@(rest form) (I have more too, but these are the ones I use most frequently.) Comments/criticisms welcome
Re: Why aren't lists callable?
Then why are sets callable? Not that I'm complaining - I found it handy, then came to wonder why lists aren't. -Ethan > I'd just like to add to this discussion that maps and vectors are > functions not just because it's neat or possible, with the > implementation one of many possibilities, but because they are > associative, and associative collections are inherently functions of > their keys/indices. > > Lists/seqs are not associative, thus not functions. > > Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
java.lang.IncompatibleClassChangeError: [class] and [inner class] disagree on InnerClasses attribute
Hi all, I've just been fiddling with Lucene indexing from Clojure, and wanted to access a static field of this inner class: http://lucene.apache.org/java/2_4_0/api/org/apache/lucene/index/IndexWriter.MaxFieldLength.html I'm importing IndexWriter$MaxFieldLength with no problems, but attempts to eval: IndexWriter$MaxFieldLength/UNLIMITED or (. IndexWriter$MaxFieldLength UNLIMITED) both yield the following exception: java.lang.IncompatibleClassChangeError: org.apache.lucene.index.IndexWriter and org.apache.lucene.index.IndexWriter$MaxFieldLength disagree on InnerClasses attribute (NO_SOURCE_FILE:0) [Thrown class clojure.lang.Compiler$CompilerException] I'm running SVN r1205. Am I doing something wrong here? Thanks, Mark --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Why aren't lists callable?
On Mon, Jan 12, 2009 at 5:56 PM, Jason Wolfe wrote: > > For mapping across maps I often find the following utility helpful: > > (defn map-map "Like map, but expects f to produce pairs that are > combined to produce a map output." > [f & maps] (reduce #(conj %1 %2) {} (apply map f maps))) > > 1:1 user=> (map-map (fn [[k v]] [k (str v " Mark")]) {:greet > "hello" :farewell "goodbye"}) > {:farewell "goodbye Mark", :greet "hello Mark"} This is a pattern, isn't it. I've generally used 'for' when I want destructuring and producing vectors. Combined with 'into' you get: (into {} (for [[k v] {:greet "hello" :farewell "goodbye"}] [k (str v " Mark")])) --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 -~--~~~~--~~--~--~---
Something's possibly wrong with backquote expansion.
After a fair amount of macro writing in CL, I think I got the backquote expansion mechanism pretty much nailed down (after all, it is quite clear in the HyperSpec). Now, I thought I understood the Clojure algorithm just as well. It looked very similar (concat instead of append and so on). Apart from the namespace resolution business, and a few other irrelevant details, the essence looked the same. But I did the following just for fun, and I got a surprising result: > (def x `a) > (def a 5) > `(list `(list ,,x)) What I theoretically was expecting was the outcome of this: (concat (list `list) (list (concat (list `concat) (list (concat (list `list) (list ``list))) (list (concat (list `list) (list x)) In other words, behind the curtains, the latter was supposed to be evaluated. Now, as Guy Steele points out, with a k-level nested backquote, you are guaranteed to get the same result only after k evaluations. So evaluating twice the result is: ((clojure.core/list 5)) I checked this in Common Lisp and the result was sure enough exactly the equivalent, as I expected. Yet, in clojure this is what happens (of course you see the first evaluation directly in this case): > `(list `(list ,,x)) (clojure.core/list (clojure.core/concat (clojure.core/list (quote clojure.core/list)) (clojure.core/list (quote user/x Another evaluation gives: ((clojure.core/list user/x)) That's ALMOST the same but not quite. See the "user/x"? It came from a very strange (quote user/x) above which wasn't supposed to be there. I mean user/x should not have been quoted. Is this a bug? Rock --~--~-~--~~~---~--~~ You 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: java.nio.channels.FileChannel.MapMode
user=> (import '(java.nio.channels FileChannel)) nil user=> java.nio.channels.FileChannel$MapMode/READ_ONLY # Sorry for the noise! --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~---
java.nio.channels.FileChannel.MapMode
To achieve high speed IO I've tried to used mapped FileChannel but failed to specify MapMode. user=> (import '(java.nio.channels.FileChannel MapMode)) java.lang.ClassNotFoundException: java.nio.channels.FileChannel.MapMode (NO_SOURCE_FILE:0) while user=> (import '(java.nio ByteOrder)) nil user=> ByteOrder/BIG_ENDIAN # user=> (import '(java.nio.channels FileChannel)) nil This is with the latest SVN versions, i haven't tried anything older then three weeks. Am I missing something or this is a bug? /Attila --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Why aren't lists callable?
A set is, in a sense, a function mapping from arbitrary objects to Boolean values. If the object is in the set, it returns true. A list, in the Lisp world at least, only has two elements, first and rest (car and cdr in older Lisps). A list object isn't really a "complete" collection the way vectors and maps are. There isn't a good way to conceptualize that as a function. I've probably just made this more confusing, but that's the best I could come up with. -Stuart Sierra On Jan 12, 6:51 pm, Ethan Herdrick wrote: > Then why are sets callable? Not that I'm complaining - I found it > handy, then came to wonder why lists aren't. > > -Ethan > > > I'd just like to add to this discussion that maps and vectors are > > functions not just because it's neat or possible, with the > > implementation one of many possibilities, but because they are > > associative, and associative collections are inherently functions of > > their keys/indices. > > > Lists/seqs are not associative, thus not functions. > > > Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: non recursive impl in presence of persistence?
I give up.I don't know what's wrong and I don't want to just punt and go on to a totally different implementation. Can while loops have more that one statement in the body? Maybe it's something dumb. I'm not turning my back on what people say about loop/recur or functional programming. I'm just trying to accomplish my original goal of constructing an iterative-looking example. I get the added benefit of learning how reference dereference works, while loops . . .and how to read the errors. Or not. I'm not making headway. I just want to get this out of my system, but I'm getting some class cast exception and no useful line number. Can you not set a variable to a vector? the definition passes (compiles?), but when I call it I get a runtime error. I've made the code as simple (broken down) as possible. listmerge works (because I didn't write it myself). (defn listmerge [l1 l2] (let [l1first (first l1) l2first (first l2)] (cond (empty? l1) l2 (empty? l2) l1 (< l1first l2first) (cons l1first (listmerge (rest l1) l2)) :else (cons l2first (listmerge (rest l2) l1)) (defn msort [toSort] (with-local-vars [my-list (for [x toSort] [x]) l1 0 l2 0] (while (rest @my-list) (var-set l1 (first @my-list)) (var-set l2 (second @my-list)) (var-set my-list (drop 2 @my-list)) (var-set my-list (concat @my-list (listmerge [...@l1] [...@l2] @my-list)) (msort [64 45 2 67 1]) Thanks again. On Mon, Jan 12, 2009 at 1:10 PM, James Reeves wrote: > > On Jan 12, 5:24 am, e wrote: > > It's funny, whenever I tried to be all safe like this and take the time > to > > make stuff safe in C++, coworkers would say, "we are grown-ups. At some > > point you gotta stop being a paranoid programmer. > > Given that software bugs are a very common occurrence, I'd say we're > far from being paranoid enough :) > > > Another thing is to make the common case easy . . . .and uh, mutable > local > > variables are pretty darn common, > > In imperative languages, yes, but not really in functional languages. > I've written a fair amount of Clojure code, and I haven't used with- > local-vars once. > > - James > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from 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: Something's possibly wrong with backquote expansion.
On Jan 12, 6:49 pm, Rock wrote: > After a fair amount of macro writing in CL, I think I got the > backquote expansion mechanism pretty much nailed down (after all, it > is quite clear in the HyperSpec). Now, I thought I understood the > Clojure algorithm just as well. It looked very similar (concat instead > of append and so on). Apart from the namespace resolution business, > and a few other irrelevant details, the essence looked the same. > > But I did the following just for fun, and I got a surprising result: > > > (def x `a) > > (def a 5) > > `(list `(list ,,x)) > > What I theoretically was expecting was the outcome of this: > > (concat (list `list) (list (concat (list `concat) (list (concat (list > `list) (list ``list))) (list (concat (list `list) (list x)) > > In other words, behind the curtains, the latter was supposed to be > evaluated. Now, as Guy Steele points out, with a k-level nested > backquote, you are guaranteed to get the same result only after k > evaluations. So evaluating twice the result is: > > ((clojure.core/list 5)) > > I checked this in Common Lisp and the result was sure enough exactly > the equivalent, as I expected. > > Yet, in clojure this is what happens (of course you see the first > evaluation directly in this case): > > > `(list `(list ,,x)) > > (clojure.core/list (clojure.core/concat (clojure.core/list (quote > clojure.core/list)) (clojure.core/list (quote user/x > > Another evaluation gives: > ((clojure.core/list user/x)) > > That's ALMOST the same but not quite. See the "user/x"? It came from a > very strange (quote user/x) above which wasn't supposed to be there. I > mean user/x should not have been quoted. > > Is this a bug? The unquote character in Clojure is ~ not comma. user=> (eval `(list `(list ~~x))) ((clojure.core/list 5)) 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: Something's possibly wrong with backquote expansion.
OK. Perfect. Thanks. I was worried there for a moment. Next time I'll read the docs more carefully. My fault. On Jan 13, 3:29 am, Rich Hickey wrote: > On Jan 12, 6:49 pm, Rock wrote: > > > > > After a fair amount of macro writing in CL, I think I got the > > backquote expansion mechanism pretty much nailed down (after all, it > > is quite clear in the HyperSpec). Now, I thought I understood the > > Clojure algorithm just as well. It looked very similar (concat instead > > of append and so on). Apart from the namespace resolution business, > > and a few other irrelevant details, the essence looked the same. > > > But I did the following just for fun, and I got a surprising result: > > > > (def x `a) > > > (def a 5) > > > `(list `(list ,,x)) > > > What I theoretically was expecting was the outcome of this: > > > (concat (list `list) (list (concat (list `concat) (list (concat (list > > `list) (list ``list))) (list (concat (list `list) (list x)) > > > In other words, behind the curtains, the latter was supposed to be > > evaluated. Now, as Guy Steele points out, with a k-level nested > > backquote, you are guaranteed to get the same result only after k > > evaluations. So evaluating twice the result is: > > > ((clojure.core/list 5)) > > > I checked this in Common Lisp and the result was sure enough exactly > > the equivalent, as I expected. > > > Yet, in clojure this is what happens (of course you see the first > > evaluation directly in this case): > > > > `(list `(list ,,x)) > > > (clojure.core/list (clojure.core/concat (clojure.core/list (quote > > clojure.core/list)) (clojure.core/list (quote user/x > > > Another evaluation gives: > > ((clojure.core/list user/x)) > > > That's ALMOST the same but not quite. See the "user/x"? It came from a > > very strange (quote user/x) above which wasn't supposed to be there. I > > mean user/x should not have been quoted. > > > Is this a bug? > > The unquote character in Clojure is ~ not comma. > > user=> (eval `(list `(list ~~x))) > ((clojure.core/list 5)) > > 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: non recursive impl in presence of persistence?
i forgot about the wiki. why is this maintained in a totally different page from clojure.org? I should be looking at these examples: http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples On Mon, Jan 12, 2009 at 9:15 PM, e wrote: > I give up.I don't know what's wrong and I don't want to just punt and > go on to a totally different implementation. Can while loops have more that > one statement in the body? Maybe it's something dumb. > > I'm not turning my back on what people say about loop/recur or functional > programming. I'm just trying to accomplish my original goal of constructing > an iterative-looking example. I get the added benefit of learning how > reference dereference works, while loops . . .and how to read the errors. > Or not. I'm not making headway. > > I just want to get this out of my system, but I'm getting some class cast > exception and no useful line number. Can you not set a variable to a > vector? > > the definition passes (compiles?), but when I call it I get a runtime > error. I've made the code as simple (broken down) as possible. listmerge > works (because I didn't write it myself). > > (defn listmerge [l1 l2] > (let [l1first (first l1) l2first (first l2)] >(cond > (empty? l1) l2 > (empty? l2) l1 > (< l1first l2first) >(cons l1first (listmerge (rest l1) l2)) > :else >(cons l2first (listmerge (rest l2) l1)) > > (defn msort [toSort] > (with-local-vars [my-list (for [x toSort] [x]) l1 0 l2 0] >(while (rest @my-list) > (var-set l1 (first @my-list)) > (var-set l2 (second @my-list)) > (var-set my-list (drop 2 @my-list)) > (var-set my-list (concat @my-list (listmerge [...@l1] [...@l2] > @my-list)) > > (msort [64 45 2 67 1]) > > Thanks again. > > > On Mon, Jan 12, 2009 at 1:10 PM, James Reeves > wrote: > >> >> On Jan 12, 5:24 am, e wrote: >> > It's funny, whenever I tried to be all safe like this and take the time >> to >> > make stuff safe in C++, coworkers would say, "we are grown-ups. At some >> > point you gotta stop being a paranoid programmer. >> >> Given that software bugs are a very common occurrence, I'd say we're >> far from being paranoid enough :) >> >> > Another thing is to make the common case easy . . . .and uh, mutable >> local >> > variables are pretty darn common, >> >> In imperative languages, yes, but not really in functional languages. >> I've written a fair amount of Clojure code, and I haven't used with- >> local-vars once. >> >> - James >> >> >> > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from 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: Example Java oriented SWT GUI application in Clojure
what is "set!"? I don't see that in the api On Mon, Jan 12, 2009 at 5:24 PM, BerlinBrown wrote: > > Here is an example SWT application. It is a 'search' tool. Open a > file and the search term is highlighted. It has a java oriented > approach because I copied the java code verbatim. This might be > useful if you are still used to imperative programming. > > Main source: > > http://jvmnotebook.googlecode.com/svn/trunk/clojure/swt/search/src/octane_main.clj > > Additional Files (all you really need is what is in the lib directory) > http://jvmnotebook.googlecode.com/svn/trunk/clojure/swt/search > > But, I am all ears for suggestions (I am sure there are very, very > many) and if you want, send me a patch file, I will be glad to update > it. > > Might help for newbies like me. > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
command-line in clojure.contrib suggestions
Hi, I've got some suggestions for improving command-line.clj... It would be great if you could provide a function to be called with the value of the option and the result of that function binds to the variable. This would take care of the annoying stuff like calling (Integer/parseInt intAsStr) to convert to numerics but also things like loading resources (with-command-line *command-line-args* "my-program" [[picture "Path to Picture" (fn [path] (load-picture path))]] (blah)) Currently, you'd need to do something like this, where you might re- def the var (with-command-line *command-line-args* "my-program" [[picture "Path to Picture" "/default/path"]] (def picture (load-picture picture)) (blah)) Unless there's something I'm missing. --~--~-~--~~~---~--~~ You 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: Example Java oriented SWT GUI application in Clojure
http://clojure.org/vars#toc1 On Jan 12, 2009, at 9:42 PM, e wrote: > what is "set!"? I don't see that in the api > > On Mon, Jan 12, 2009 at 5:24 PM, BerlinBrown > wrote: > > Here is an example SWT application. It is a 'search' tool. Open a > file and the search term is highlighted. It has a java oriented > approach because I copied the java code verbatim. This might be > useful if you are still used to imperative programming. > > Main source: > http://jvmnotebook.googlecode.com/svn/trunk/clojure/swt/search/src/octane_main.clj > > Additional Files (all you really need is what is in the lib directory) > http://jvmnotebook.googlecode.com/svn/trunk/clojure/swt/search > > But, I am all ears for suggestions (I am sure there are very, very > many) and if you want, send me a patch file, I will be glad to update > it. > > Might help for newbies like me. > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Example Java oriented SWT GUI application in Clojure
thanks. I think this will be useful, but I have to figure out how to get it to build in enclojure. Right now I get, "Exception in thread "main" java.util.MissingResourceException: Can't find bundle for base name octane_main, locale en_US (octane_main.clj:136)" On Mon, Jan 12, 2009 at 5:24 PM, BerlinBrown wrote: > > Here is an example SWT application. It is a 'search' tool. Open a > file and the search term is highlighted. It has a java oriented > approach because I copied the java code verbatim. This might be > useful if you are still used to imperative programming. > > Main source: > > http://jvmnotebook.googlecode.com/svn/trunk/clojure/swt/search/src/octane_main.clj > > Additional Files (all you really need is what is in the lib directory) > http://jvmnotebook.googlecode.com/svn/trunk/clojure/swt/search > > But, I am all ears for suggestions (I am sure there are very, very > many) and if you want, send me a patch file, I will be glad to update > it. > > Might help for newbies like me. > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: non recursive impl in presence of persistence?
> I just want to get this out of my system, but I'm getting some class cast > exception and no useful line number. In situations like these I find that looking at the entire stack trace provides clues. The REPL by default does not print the entire stack though I'm sure there is a way to achieve that. However I prefer to put the code in the file and run it as a script, which by default prints the entire stack and from that you can see what line it occured on (search for the first appearance of your filename). Doing so showed me that the exception was actually thrown in listmerge, because listmerge was passed in two integers instead of two lists, so I looked at where you called listmerge, and saw that you called concat probabbly expecting it to concat lists, but actually it concats the contents of the lists > (var-set my-list (concat @my-list (listmerge [...@l1] [...@l2] > @my-list)) Here is a naive solution: (var-set my-list (concat @my-list (list (listmerge @l1 @l2) @my-list) So in total your code minimally changed is: (defn msort [toSort] (with-local-vars [my-list (for [x toSort] [x]) l1 0 l2 0] (while (rest @my-list) ; (println @my-list) (var-set l1 (first @my-list)) (var-set l2 (second @my-list)) (var-set my-list (drop 2 @my-list)) (var-set my-list (concat @my-list (list (listmerge @l1 @l2) @my-list)) user=> (msort [64 45 2 67 1 7]) ((1 2 7 45 64 67)) NB: the good old print out my-list also helps narrow down what is happening. Again, I'm just providing a fix for your code, not suggesting this is the best approach. 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 -~--~~~~--~~--~--~---
typo near http://clojure.org/API#toc248
The gen-class documentation at http://clojure.org/API#toc248 has a minor typo: the description of the :state keyword begins at the end of the :factory paragraph instead of beginning a new paragraph. Not a big deal but it makes the :state description harder to find. --~--~-~--~~~---~--~~ You 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: command-line in clojure.contrib suggestions
On Mon, Jan 12, 2009 at 9:44 PM, aria42 wrote: > > Currently, you'd need to do something like this, where you might re- > def the var > > (with-command-line *command-line-args* > "my-program" > [[picture "Path to Picture" "/default/path"]] > (def picture (load-picture picture)) > (blah)) I usually use the body of with-command-line to simply call other functions, so it might look more like: (with-command-line *command-line-args* "my-program" [[picture "Path to Picture" "/default/path"] [size "The size of something" "99"]] (process-picture (load-picture picture) (Integer. size))) If each option provided a function, that function wouldn't have access to any of the other option values, right? How useful would that be? --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: non recursive impl in presence of persistence?
o! all the stuff from listmerge ended up in my-list directly. so then when listmerge was called on these elements it rightly complained! Awesome. Lots of good lessons coming out of this. I need to learn how to run closure code as a script then. I seem to remember something about this where you do java -cp clojure.jar something.something.REPL yourcode.clj . . . . I'll try to find it. I'm glad I was pretty close. Was gettin' ready to throw in the towel . . . which could have been good 'cause I have a lot of languages in the queue to try out. . . but nope. Gonna keep at it for now. I think I need to build an 800 core machine so I can get an appreciation for it all! But I already appreciate all the help. You guys are dedicated! Thanks again. On Mon, Jan 12, 2009 at 10:23 PM, Timothy Pratley wrote: > > > I just want to get this out of my system, but I'm getting some class cast > > exception and no useful line number. > > In situations like these I find that looking at the entire stack trace > provides clues. The REPL by default does not print the entire stack > though I'm sure there is a way to achieve that. However I prefer to > put the code in the file and run it as a script, which by default > prints the entire stack and from that you can see what line it occured > on (search for the first appearance of your filename). Doing so showed > me that the exception was actually thrown in listmerge, because > listmerge was passed in two integers instead of two lists, so I looked > at where you called listmerge, and saw that you called concat > probabbly expecting it to concat lists, but actually it concats the > contents of the lists > > > (var-set my-list (concat @my-list (listmerge [...@l1] [...@l2] > @my-list)) > > Here is a naive solution: > (var-set my-list (concat @my-list (list (listmerge @l1 @l2) > @my-list) > > So in total your code minimally changed is: > > (defn msort [toSort] > (with-local-vars [my-list (for [x toSort] [x]) l1 0 l2 0] > (while (rest @my-list) > ; (println @my-list) > (var-set l1 (first @my-list)) > (var-set l2 (second @my-list)) > (var-set my-list (drop 2 @my-list)) > (var-set my-list (concat @my-list (list (listmerge @l1 @l2) > @my-list)) > > user=> (msort [64 45 2 67 1 7]) > ((1 2 7 45 64 67)) > > NB: the good old print out my-list also helps narrow down what is > happening. > Again, I'm just providing a fix for your code, not suggesting this is > the best approach. > > > 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: non recursive impl in presence of persistence?
by the way, Tim, I've seen NB before as comments in J. What's it stand for? On Mon, Jan 12, 2009 at 10:39 PM, e wrote: > o! all the stuff from listmerge ended up in my-list directly. so > then when listmerge was called on these elements it rightly complained! > Awesome. Lots of good lessons coming out of this. > > I need to learn how to run closure code as a script then. I seem to > remember something about this where you do java -cp clojure.jar > something.something.REPL yourcode.clj . . . . I'll try to find it. I'm glad > I was pretty close. Was gettin' ready to throw in the towel . . . which > could have been good 'cause I have a lot of languages in the queue to try > out. . . but nope. Gonna keep at it for now. I think I need to build an > 800 core machine so I can get an appreciation for it all! > > But I already appreciate all the help. You guys are dedicated! > > Thanks again. > > > On Mon, Jan 12, 2009 at 10:23 PM, Timothy Pratley < > timothyprat...@gmail.com> wrote: > >> >> > I just want to get this out of my system, but I'm getting some class >> cast >> > exception and no useful line number. >> >> In situations like these I find that looking at the entire stack trace >> provides clues. The REPL by default does not print the entire stack >> though I'm sure there is a way to achieve that. However I prefer to >> put the code in the file and run it as a script, which by default >> prints the entire stack and from that you can see what line it occured >> on (search for the first appearance of your filename). Doing so showed >> me that the exception was actually thrown in listmerge, because >> listmerge was passed in two integers instead of two lists, so I looked >> at where you called listmerge, and saw that you called concat >> probabbly expecting it to concat lists, but actually it concats the >> contents of the lists >> >> > (var-set my-list (concat @my-list (listmerge [...@l1] [...@l2] >> @my-list)) >> >> Here is a naive solution: >> (var-set my-list (concat @my-list (list (listmerge @l1 @l2) >> @my-list) >> >> So in total your code minimally changed is: >> >> (defn msort [toSort] >> (with-local-vars [my-list (for [x toSort] [x]) l1 0 l2 0] >> (while (rest @my-list) >> ; (println @my-list) >> (var-set l1 (first @my-list)) >> (var-set l2 (second @my-list)) >> (var-set my-list (drop 2 @my-list)) >> (var-set my-list (concat @my-list (list (listmerge @l1 @l2) >> @my-list)) >> >> user=> (msort [64 45 2 67 1 7]) >> ((1 2 7 45 64 67)) >> >> NB: the good old print out my-list also helps narrow down what is >> happening. >> Again, I'm just providing a fix for your code, not suggesting this is >> the best approach. >> >> >> 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: non recursive impl in presence of persistence?
o #2 . . . and I totally lost site of what I was doing with l1 and l2 ! they were already lists because my-list was a list of lists. I new that when I started, like on Friday. On Mon, Jan 12, 2009 at 10:39 PM, e wrote: > o! all the stuff from listmerge ended up in my-list directly. so > then when listmerge was called on these elements it rightly complained! > Awesome. Lots of good lessons coming out of this. > > I need to learn how to run closure code as a script then. I seem to > remember something about this where you do java -cp clojure.jar > something.something.REPL yourcode.clj . . . . I'll try to find it. I'm glad > I was pretty close. Was gettin' ready to throw in the towel . . . which > could have been good 'cause I have a lot of languages in the queue to try > out. . . but nope. Gonna keep at it for now. I think I need to build an > 800 core machine so I can get an appreciation for it all! > > But I already appreciate all the help. You guys are dedicated! > > Thanks again. > > > On Mon, Jan 12, 2009 at 10:23 PM, Timothy Pratley < > timothyprat...@gmail.com> wrote: > >> >> > I just want to get this out of my system, but I'm getting some class >> cast >> > exception and no useful line number. >> >> In situations like these I find that looking at the entire stack trace >> provides clues. The REPL by default does not print the entire stack >> though I'm sure there is a way to achieve that. However I prefer to >> put the code in the file and run it as a script, which by default >> prints the entire stack and from that you can see what line it occured >> on (search for the first appearance of your filename). Doing so showed >> me that the exception was actually thrown in listmerge, because >> listmerge was passed in two integers instead of two lists, so I looked >> at where you called listmerge, and saw that you called concat >> probabbly expecting it to concat lists, but actually it concats the >> contents of the lists >> >> > (var-set my-list (concat @my-list (listmerge [...@l1] [...@l2] >> @my-list)) >> >> Here is a naive solution: >> (var-set my-list (concat @my-list (list (listmerge @l1 @l2) >> @my-list) >> >> So in total your code minimally changed is: >> >> (defn msort [toSort] >> (with-local-vars [my-list (for [x toSort] [x]) l1 0 l2 0] >> (while (rest @my-list) >> ; (println @my-list) >> (var-set l1 (first @my-list)) >> (var-set l2 (second @my-list)) >> (var-set my-list (drop 2 @my-list)) >> (var-set my-list (concat @my-list (list (listmerge @l1 @l2) >> @my-list)) >> >> user=> (msort [64 45 2 67 1 7]) >> ((1 2 7 45 64 67)) >> >> NB: the good old print out my-list also helps narrow down what is >> happening. >> Again, I'm just providing a fix for your code, not suggesting this is >> the best approach. >> >> >> 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: command-line in clojure.contrib suggestions
Couldn't it have access to the other bindings so far like let? And then just have the order of options reflect the partial order induced by dependency? So is this possible... (with-command-line *command-line-args* "my-program" [[size "The size of something" #(if % (Integer/parseInt %) 99)] [picture "Path to Picture" #(load-picture % size)]] (do-stuff-with-picture)) Also, other suggestions might be being able to declare an option or conditional dependencies. Ideally we could have lots of optional keyword arguments :default, :required, :depends, etc... This is probably more heavy than most people use, but I would definitely find it useful. Thanks, Aria > (with-command-line *command-line-args* > > "my-program" > > [[picture "Path to Picture" "/default/path"]] > > (def picture (load-picture picture)) > > (blah)) > > I usually use the body of with-command-line to simply call other > functions, so it might look more like: > > (with-command-line *command-line-args* > "my-program" > [[picture "Path to Picture" "/default/path"] > [size "The size of something" "99"]] > (process-picture (load-picture picture) (Integer. size))) > > If each option provided a function, that function wouldn't have access > to any of the other option values, right? How useful would that be? > > --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: non recursive impl in presence of persistence?
> by the way, Tim, I've seen NB before as comments in J. What's it stand for? An abbreviation for nota bene, a Latin expression meaning "note well". > I need to learn how to run closure code as a script then. http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started first section shows you how --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Utilities for clojure.contrib?
On Mon, Jan 12, 2009 at 6:48 PM, Jason Wolfe wrote: > > (defn map-when "Like map but discards logically false entries" > [fn & seqs] > (filter identity (apply map fn seqs))) I'd use map-when. > (defn iterate-while [f x] > (take-while identity (iterate f x))) This one too. It raises a question, though -- how much functionality should a function provide to be worth making everyone who reads the code learn the new vocabulary? I've written each of these inline when I've needed them. Are they better as idioms or functions? --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: when performance matters
> It all depends on your algorithms and your code. Clojure has lots of > support (data structures and algorithms) for concurrent programming, > but you have to choose and combine them yourself to get efficient > parallelization. I know that there are other functional approaches where the compiler automatically finds ways to parallelize. Is there much scope for this in Clojure? Or is it all pretty much manually added concurrency? And this leads to another question I have about Lisp-style languages in general. I get the impression that in Lisp much of the "compiler" is Lisp code itself. Ie, layer and layer of macros build up towards the language that then actually gets "used". Does this layer upon layer of macros lead to inefficiencies in itself? Or is the opposite true? > Again this depends a lot on what you are doing. Hotspot is already > doing an impressive job on some applications, but remains bad at > others. That seems to match what I've read. On average I get the impression that it is about 2 times as slow as efficient C++ code and uses maybe 10 times as much memory. What I'm wondering is whether there is still quite a bit of "fat to be trimmed" with HotSpot, or whether it's approaching the limits of what is achievable. > One source of hope for better interfaces is new virtual machines. One > candidate is VMKit (http://vmkit.llvm.org/), an implementation of the > JVM (and .Net as well) on top of LLVM. Combine this with the gcc > version that produces LLVM code, and it should be possible to get > Java-C interoperability with much less friction than through the JNI. > On the other hand, it will be a long time before VMKit matches the > performance of HotSpot. Thanks for the info! This does sound like a promising approach. For the future though. > You could also consider writing Clojure code that generates C++ code. > Or C, or why not directly LLVM. Thanks. Worth considering. Though I don't really know whether this is a practical option or not. Maybe it is. Thanks Konrad for your thoughts. Most useful. Cheers, Mark P. --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~---
[ANN] Ring: A Web application library for Clojure.
Hi All, I'm happy to announce the alpha release of 'Ring', a library inspired by Python's WSGI and Ruby's Rack for developing web applications in Clojure. I've made it as easy as humanly possible for you to try it out: git clone git://github.com/mmcgrana/ring.git cd ring java -Djava.ext.dirs=jars clojure.main src/ring/examples/ hello_world.clj And your up and running with your first Ring web app, which you can see at http://localhost:8080/ in your browser. The basic idea of Ring is that web apps are just Clojure functions that take a standardized request as a single argument and return and standardized response. For example, the hello_world.clj script from above is: (ns ring.examples.hello-world (:require ring.jetty) (:import java.util.Date java.text.SimpleDateFormat)) (def formatter (SimpleDateFormat. "HH:mm:ss")); (defn app [req] {:status 200 :headers {"Content-Type" "text/html"} :body(str "Hello World from Ring" "The current time is " (.format formatter (Date.)) ".")}) (ring.jetty/run {:port 8080} app) Its nice to be able to get to "Hello World" so quickly, but the real power of Ring is that apps are just functions - hence we can combine, wrap, curry, and generally manipulate them as first class values. For example, someone asked in #clojure today how they could make their web app provide a cleaned backtrace as an HTML response when it raised exceptions. To add such exception handling to our Hello World Ring app we would just use the ring.backtrace middleware: (ring.jetty/run {:port 8080} app) becomes (ring.jetty/run {:port 8080} (ring.backtrace/wrap app)) Similarly, one might want to have changes to a web app's code be reflected in real time in the development environment, so as to avoid constantly having to reboot the webserver. The ring.reload middleware accomplishes exactly that: (ring.jetty/run {:port 8080} (ring.backtrace/wrap (ring.reload/wrap '(ring.examples.hello-world) app) These are some of the features that originally motivated me to develop Ring, but the complete list of functionality available to Ring apps is larger and continues to grow: * ring.jetty: Handler for the Jetty webserver. * ring.file: Middleware that serves static files out of a public directory. * ring.file-info: Middleware that augments response headers with info about File responses. * ring.dump: Endpoint that dumps the Ring requests as HTML responses for debugging. * ring.show-exceptions: Middleware that catches exceptions and displays readable backtraces for debugging. * ring.reload: Middleware to automatically reload selected libs before each requests, minimizing server restarts. * ring.builder: Helpers for combining Ring endpoints and middleware into Ring apps. * ring.lint: Linter for the Ring interface, ensures compliance with the Ring spec. * ring.examples.*: Various example Ring apps. You can find more details about Ring at its project page on GitHub, including a README file for new users and a draft SPEC file that documents the Ring interface: http://github.com/mmcgrana/ring I've built an open source web app on Ring: http://cljre.com. The source for this simple app, available at http://github.com/mmcgrana/cljre.com, could serve as a good introduction to how apps can consume Ring requests and to the use of modular Ring middleware; see in particular the src/cljre/app.clj file, where most of that application is defined. Also, I think I should mention how I see Ring relating to the Java Servlet abstraction and to existing and new Clojure web frameworks. Ring heavily leverages the Servlet API internally, as I strongly believe in not reinventing wheels such as basic HTTP parsing. Furthermore, I think that the interface that Ring presents to Clojure web application developers by pre-processing the servlet requests is dramatically more useful than that of the raw servlet. Ring uses Servlets for what they are really good at - implementing HTTP - and presents a simple API against which additional logic can be defined in the application layer. In terms of Clojure web frameworks, I think that there is a lot to be gained by leveraging the Ring interface, especially from the modular functionality provided by Ring middleware. I'd like in particular to be able to run Compojure apps in Ring - if the users and authors of Compojure are interested I'd be happy to work with them to see what we can do. If you've made it this far, thanks a lot for reading! I welcome any comments or suggestions that you have about Ring, the draft SPEC document, or the Clojure web app space in general. Thanks again, - Mark --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to cloju
Re: [ANN] Ring: A Web application library for Clojure.
Mark, This looks great! Thanks for writing and sharing. -Matt On Jan 12, 2009, at 11:45 PM, Mark McGranaghan wrote: > > Hi All, > > I'm happy to announce the alpha release of 'Ring', a library inspired > by Python's WSGI and Ruby's Rack for developing web applications in > Clojure. > > I've made it as easy as humanly possible for you to try it out: > >git clone git://github.com/mmcgrana/ring.git >cd ring >java -Djava.ext.dirs=jars clojure.main src/ring/examples/ > hello_world.clj > > And your up and running with your first Ring web app, which you can > see at http://localhost:8080/ in your browser. > > The basic idea of Ring is that web apps are just Clojure functions > that take a standardized request as a single argument and return and > standardized response. For example, the hello_world.clj script from > above is: > > (ns ring.examples.hello-world > (:require ring.jetty) > (:import java.util.Date java.text.SimpleDateFormat)) > > (def formatter (SimpleDateFormat. "HH:mm:ss")); > > (defn app > [req] > {:status 200 > :headers {"Content-Type" "text/html"} > :body(str "Hello World from Ring" >"The current time is " >(.format formatter (Date.)) ".")}) > > (ring.jetty/run {:port 8080} app) > > Its nice to be able to get to "Hello World" so quickly, but the real > power of Ring is that apps are just functions - hence we can combine, > wrap, curry, and generally manipulate them as first class values. > > For example, someone asked in #clojure today how they could make their > web app provide a cleaned backtrace as an HTML response when it raised > exceptions. To add such exception handling to our Hello World Ring app > we would just use the ring.backtrace middleware: > >(ring.jetty/run {:port 8080} app) > >becomes > >(ring.jetty/run {:port 8080} > (ring.backtrace/wrap >app)) > > Similarly, one might want to have changes to a web app's code be > reflected in real time in the development environment, so as to avoid > constantly having to reboot the webserver. The ring.reload middleware > accomplishes exactly that: > >(ring.jetty/run {:port 8080} > (ring.backtrace/wrap >(ring.reload/wrap '(ring.examples.hello-world) > app) > > These are some of the features that originally motivated me to develop > Ring, but the complete list of functionality available to Ring apps is > larger and continues to grow: > > * ring.jetty: Handler for the Jetty webserver. > * ring.file: Middleware that serves static files out of a public > directory. > * ring.file-info: Middleware that augments response headers with info > about File responses. > * ring.dump: Endpoint that dumps the Ring requests as HTML responses > for debugging. > * ring.show-exceptions: Middleware that catches exceptions and > displays readable backtraces for debugging. > * ring.reload: Middleware to automatically reload selected libs before > each requests, minimizing server restarts. > * ring.builder: Helpers for combining Ring endpoints and middleware > into Ring apps. > * ring.lint: Linter for the Ring interface, ensures compliance with > the Ring spec. > * ring.examples.*: Various example Ring apps. > > You can find more details about Ring at its project page on GitHub, > including a README file for new users and a draft SPEC file that > documents the Ring interface: > > http://github.com/mmcgrana/ring > > I've built an open source web app on Ring: http://cljre.com. The > source for this simple app, available at http://github.com/mmcgrana/cljre.com > , > could serve as a good introduction to how apps can consume Ring > requests and to the use of modular Ring middleware; see in particular > the src/cljre/app.clj file, where most of that application is defined. > > Also, I think I should mention how I see Ring relating to the Java > Servlet abstraction and to existing and new Clojure web frameworks. > Ring heavily leverages the Servlet API internally, as I strongly > believe in not reinventing wheels such as basic HTTP parsing. > Furthermore, I think that the interface that Ring presents to Clojure > web application developers by pre-processing the servlet requests is > dramatically more useful than that of the raw servlet. Ring uses > Servlets for what they are really good at - implementing HTTP - and > presents a simple API against which additional logic can be defined in > the application layer. > > In terms of Clojure web frameworks, I think that there is a lot to be > gained by leveraging the Ring interface, especially from the modular > functionality provided by Ring middleware. I'd like in particular to > be able to run Compojure apps in Ring - if the users and authors of > Compojure are interested I'd be happy to work with them to see what we > can do. > > If you've made it this far, thanks a lot for reading! I welcome any > comments or suggestions that you have about Ring, the draft SPEC > document, or the Cl
Re: non recursive impl in presence of persistence?
my unsafe version works now, thanks to a LOT of help. (defn msort [toSort] (with-local-vars [my-list (for [x toSort] [x])] (while (rest @my-list) (let [[l1 l2 & my-list-rest] @my-list] (var-set my-list (conj my-list-rest (listmerge l1 l2))) )) (first @my-list))) now I'm trying to make a shorter version of the loop/recur version than James provided because, even though I think I understand, somehow I probably don't. From what it looks like the my-list get's it's initial bindings from the vector map operation, but after that, it gets them from recur. Here's what I'm trying, but it says wrong number of arguments. I haven't taken the time yet to make the script environment. (defn msort2 [toSort] (loop [[l1 l2 & my-list] (for [x toSort] [x])] (if (l2) (recur (conj my-list (listmerge l1 l2))) l1))) i'm trying to say, "if there's a second list in my-list, then there's still merging to do. i tested that l1 l2 & stuff with edge cases, and it handles them fine (no elements in list, one element, two, 3, etc). I like that construct, a lot. smart! but my code doesn't work. On Mon, Jan 12, 2009 at 10:59 PM, Timothy Pratley wrote: > > > by the way, Tim, I've seen NB before as comments in J. What's it stand > for? > > An abbreviation for nota bene, a Latin expression meaning "note > well". > > > > I need to learn how to run closure code as a script then. > > http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started > first section shows you how > > > > --~--~-~--~~~---~--~~ You 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: [ANN] Ring: A Web application library for Clojure.
I'm incredibly impressed! Have only looked at the code briefly but I read the whole post and I'm really excited for where this is going. On Jan 12, 2009, at 11:45 PM, Mark McGranaghan wrote: > > Hi All, > > I'm happy to announce the alpha release of 'Ring', a library inspired > by Python's WSGI and Ruby's Rack for developing web applications in > Clojure. > > I've made it as easy as humanly possible for you to try it out: > >git clone git://github.com/mmcgrana/ring.git >cd ring >java -Djava.ext.dirs=jars clojure.main src/ring/examples/ > hello_world.clj > > And your up and running with your first Ring web app, which you can > see at http://localhost:8080/ in your browser. > > The basic idea of Ring is that web apps are just Clojure functions > that take a standardized request as a single argument and return and > standardized response. For example, the hello_world.clj script from > above is: > > (ns ring.examples.hello-world > (:require ring.jetty) > (:import java.util.Date java.text.SimpleDateFormat)) > > (def formatter (SimpleDateFormat. "HH:mm:ss")); > > (defn app > [req] > {:status 200 > :headers {"Content-Type" "text/html"} > :body(str "Hello World from Ring" >"The current time is " >(.format formatter (Date.)) ".")}) > > (ring.jetty/run {:port 8080} app) > > Its nice to be able to get to "Hello World" so quickly, but the real > power of Ring is that apps are just functions - hence we can combine, > wrap, curry, and generally manipulate them as first class values. > > For example, someone asked in #clojure today how they could make their > web app provide a cleaned backtrace as an HTML response when it raised > exceptions. To add such exception handling to our Hello World Ring app > we would just use the ring.backtrace middleware: > >(ring.jetty/run {:port 8080} app) > >becomes > >(ring.jetty/run {:port 8080} > (ring.backtrace/wrap >app)) > > Similarly, one might want to have changes to a web app's code be > reflected in real time in the development environment, so as to avoid > constantly having to reboot the webserver. The ring.reload middleware > accomplishes exactly that: > >(ring.jetty/run {:port 8080} > (ring.backtrace/wrap >(ring.reload/wrap '(ring.examples.hello-world) > app) > > These are some of the features that originally motivated me to develop > Ring, but the complete list of functionality available to Ring apps is > larger and continues to grow: > > * ring.jetty: Handler for the Jetty webserver. > * ring.file: Middleware that serves static files out of a public > directory. > * ring.file-info: Middleware that augments response headers with info > about File responses. > * ring.dump: Endpoint that dumps the Ring requests as HTML responses > for debugging. > * ring.show-exceptions: Middleware that catches exceptions and > displays readable backtraces for debugging. > * ring.reload: Middleware to automatically reload selected libs before > each requests, minimizing server restarts. > * ring.builder: Helpers for combining Ring endpoints and middleware > into Ring apps. > * ring.lint: Linter for the Ring interface, ensures compliance with > the Ring spec. > * ring.examples.*: Various example Ring apps. > > You can find more details about Ring at its project page on GitHub, > including a README file for new users and a draft SPEC file that > documents the Ring interface: > > http://github.com/mmcgrana/ring > > I've built an open source web app on Ring: http://cljre.com. The > source for this simple app, available at http://github.com/mmcgrana/cljre.com > , > could serve as a good introduction to how apps can consume Ring > requests and to the use of modular Ring middleware; see in particular > the src/cljre/app.clj file, where most of that application is defined. > > Also, I think I should mention how I see Ring relating to the Java > Servlet abstraction and to existing and new Clojure web frameworks. > Ring heavily leverages the Servlet API internally, as I strongly > believe in not reinventing wheels such as basic HTTP parsing. > Furthermore, I think that the interface that Ring presents to Clojure > web application developers by pre-processing the servlet requests is > dramatically more useful than that of the raw servlet. Ring uses > Servlets for what they are really good at - implementing HTTP - and > presents a simple API against which additional logic can be defined in > the application layer. > > In terms of Clojure web frameworks, I think that there is a lot to be > gained by leveraging the Ring interface, especially from the modular > functionality provided by Ring middleware. I'd like in particular to > be able to run Compojure apps in Ring - if the users and authors of > Compojure are interested I'd be happy to work with them to see what we > can do. > > If you've made it this far, thanks a lot for reading! I welcome any > comments o
Re: when performance matters
> JNA might be an alternative to JNI:https://jna.dev.java.net/ > But I wouldn't know; haven't used either. Thanks for this info. It sounds like JNA may be worth looking into. Cheers, Mark. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Designing a Performance Vector Math library in Clojure.
Hi, I'm still getting used to the primitive support in Clojure, and I want to confirm my understanding. As far as I know, primitive support is only supported in local let bindings, right? So in designing a vector math library, To translate from Java, one would write a class with primitive fields. class Vector{ float x,y,z; } What would be the best choice in Clojure? {:x 0 :y 0 :z 0} I think a map would have too much overhead to retrieve and set keys. Is that correct? Although this is the most straight-forward conversion. A 3-element vector [0 0 0] Still has the boxing/unboxing overhead. (Unless Clojure supports primitives in collections, which I'm not sure about) A Java array (make-array Float/TYPE 0) Is this the most efficient representation? I don't really like this representation, cause I lose the named fields, as well as the ability to put other types of data into the same vector struct. --~--~-~--~~~---~--~~ You 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: non recursive impl in presence of persistence?
> (if (l2) The problem is on this line. (l2) is a function call. Replace with (if l2 and it works fine :) java.lang.IllegalArgumentException: Wrong number of args passed to: LazilyPersistentVector (NO_SOURCE_FILE:0) The error message bears a little explaining: vectors are functions, user=> ([1 2 3] 1) 2 here I called a a vector [1 2 3] with the argument 1, which gets the element at 1 Hence where l2 is a vector in your case, (l2) is a function call but no index argument was supplied. --~--~-~--~~~---~--~~ You 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: [ANN] Ring: A Web application library for Clojure.
What's does the req object that is passed into the function have in it? On Mon, Jan 12, 2009 at 11:45 PM, Mark McGranaghan wrote: > > Hi All, > > I'm happy to announce the alpha release of 'Ring', a library inspired > by Python's WSGI and Ruby's Rack for developing web applications in > Clojure. > > I've made it as easy as humanly possible for you to try it out: > >git clone git://github.com/mmcgrana/ring.git >cd ring >java -Djava.ext.dirs=jars clojure.main src/ring/examples/ > hello_world.clj > > And your up and running with your first Ring web app, which you can > see at http://localhost:8080/ in your browser. > > The basic idea of Ring is that web apps are just Clojure functions > that take a standardized request as a single argument and return and > standardized response. For example, the hello_world.clj script from > above is: > > (ns ring.examples.hello-world > (:require ring.jetty) > (:import java.util.Date java.text.SimpleDateFormat)) > > (def formatter (SimpleDateFormat. "HH:mm:ss")); > > (defn app > [req] > {:status 200 > :headers {"Content-Type" "text/html"} > :body(str "Hello World from Ring" >"The current time is " >(.format formatter (Date.)) ".")}) > > (ring.jetty/run {:port 8080} app) > > Its nice to be able to get to "Hello World" so quickly, but the real > power of Ring is that apps are just functions - hence we can combine, > wrap, curry, and generally manipulate them as first class values. > > For example, someone asked in #clojure today how they could make their > web app provide a cleaned backtrace as an HTML response when it raised > exceptions. To add such exception handling to our Hello World Ring app > we would just use the ring.backtrace middleware: > >(ring.jetty/run {:port 8080} app) > >becomes > >(ring.jetty/run {:port 8080} > (ring.backtrace/wrap >app)) > > Similarly, one might want to have changes to a web app's code be > reflected in real time in the development environment, so as to avoid > constantly having to reboot the webserver. The ring.reload middleware > accomplishes exactly that: > >(ring.jetty/run {:port 8080} > (ring.backtrace/wrap >(ring.reload/wrap '(ring.examples.hello-world) > app) > > These are some of the features that originally motivated me to develop > Ring, but the complete list of functionality available to Ring apps is > larger and continues to grow: > > * ring.jetty: Handler for the Jetty webserver. > * ring.file: Middleware that serves static files out of a public > directory. > * ring.file-info: Middleware that augments response headers with info > about File responses. > * ring.dump: Endpoint that dumps the Ring requests as HTML responses > for debugging. > * ring.show-exceptions: Middleware that catches exceptions and > displays readable backtraces for debugging. > * ring.reload: Middleware to automatically reload selected libs before > each requests, minimizing server restarts. > * ring.builder: Helpers for combining Ring endpoints and middleware > into Ring apps. > * ring.lint: Linter for the Ring interface, ensures compliance with > the Ring spec. > * ring.examples.*: Various example Ring apps. > > You can find more details about Ring at its project page on GitHub, > including a README file for new users and a draft SPEC file that > documents the Ring interface: > > http://github.com/mmcgrana/ring > > I've built an open source web app on Ring: http://cljre.com. The > source for this simple app, available at > http://github.com/mmcgrana/cljre.com, > could serve as a good introduction to how apps can consume Ring > requests and to the use of modular Ring middleware; see in particular > the src/cljre/app.clj file, where most of that application is defined. > > Also, I think I should mention how I see Ring relating to the Java > Servlet abstraction and to existing and new Clojure web frameworks. > Ring heavily leverages the Servlet API internally, as I strongly > believe in not reinventing wheels such as basic HTTP parsing. > Furthermore, I think that the interface that Ring presents to Clojure > web application developers by pre-processing the servlet requests is > dramatically more useful than that of the raw servlet. Ring uses > Servlets for what they are really good at - implementing HTTP - and > presents a simple API against which additional logic can be defined in > the application layer. > > In terms of Clojure web frameworks, I think that there is a lot to be > gained by leveraging the Ring interface, especially from the modular > functionality provided by Ring middleware. I'd like in particular to > be able to run Compojure apps in Ring - if the users and authors of > Compojure are interested I'd be happy to work with them to see what we > can do. > > If you've made it this far, thanks a lot for reading! I welcome any > comments or suggestions that you have about Ring, the draft SPEC > document, o
Re: [ANN] Ring: A Web application library for Clojure.
To answer my own question: [#^HttpServletRequest request] {:server-port (.getServerPort request) :server-name (.getServerName request) :remote-addr (.getRemoteAddr request) :uri (.getRequestURI request) :query-string (.getQueryString request) :scheme (keyword (.getScheme request)) :request-method (keyword (.toLowerCase (.getMethod request))) :headers (reduce (fn [header-map #^String header-name] (assoc header-map (.toLowerCase header-name) (.getHeader request header-name))) {} (enumeration-seq (.getHeaderNames request))) :content-type (.getContentType request) :content-length (let [len (.getContentLength request)] (if (>= len 0) len)) :character-encoding (.getCharacterEncoding request) :body (.getInputStream request)}) Which by the way is awesome, because you function takes a map, which doesn't have to be created from an HttpServletRequest object. For the purposes of testing, you can just construct a map with the parts you want and pass that to your function. Great Work! On Tue, Jan 13, 2009 at 1:13 AM, Paul Barry wrote: > What's does the req object that is passed into the function have in it? > > > On Mon, Jan 12, 2009 at 11:45 PM, Mark McGranaghan wrote: > >> >> Hi All, >> >> I'm happy to announce the alpha release of 'Ring', a library inspired >> by Python's WSGI and Ruby's Rack for developing web applications in >> Clojure. >> >> I've made it as easy as humanly possible for you to try it out: >> >>git clone git://github.com/mmcgrana/ring.git >>cd ring >>java -Djava.ext.dirs=jars clojure.main src/ring/examples/ >> hello_world.clj >> >> And your up and running with your first Ring web app, which you can >> see at http://localhost:8080/ in your browser. >> >> The basic idea of Ring is that web apps are just Clojure functions >> that take a standardized request as a single argument and return and >> standardized response. For example, the hello_world.clj script from >> above is: >> >> (ns ring.examples.hello-world >> (:require ring.jetty) >> (:import java.util.Date java.text.SimpleDateFormat)) >> >> (def formatter (SimpleDateFormat. "HH:mm:ss")); >> >> (defn app >> [req] >> {:status 200 >> :headers {"Content-Type" "text/html"} >> :body(str "Hello World from Ring" >>"The current time is " >>(.format formatter (Date.)) ".")}) >> >> (ring.jetty/run {:port 8080} app) >> >> Its nice to be able to get to "Hello World" so quickly, but the real >> power of Ring is that apps are just functions - hence we can combine, >> wrap, curry, and generally manipulate them as first class values. >> >> For example, someone asked in #clojure today how they could make their >> web app provide a cleaned backtrace as an HTML response when it raised >> exceptions. To add such exception handling to our Hello World Ring app >> we would just use the ring.backtrace middleware: >> >>(ring.jetty/run {:port 8080} app) >> >>becomes >> >>(ring.jetty/run {:port 8080} >> (ring.backtrace/wrap >>app)) >> >> Similarly, one might want to have changes to a web app's code be >> reflected in real time in the development environment, so as to avoid >> constantly having to reboot the webserver. The ring.reload middleware >> accomplishes exactly that: >> >>(ring.jetty/run {:port 8080} >> (ring.backtrace/wrap >>(ring.reload/wrap '(ring.examples.hello-world) >> app) >> >> These are some of the features that originally motivated me to develop >> Ring, but the complete list of functionality available to Ring apps is >> larger and continues to grow: >> >> * ring.jetty: Handler for the Jetty webserver. >> * ring.file: Middleware that serves static files out of a public >> directory. >> * ring.file-info: Middleware that augments response headers with info >> about File responses. >> * ring.dump: Endpoint that dumps the Ring requests as HTML responses >> for debugging. >> * ring.show-exceptions: Middleware that catches exceptions and >> displays readable backtraces for debugging. >> * ring.reload: Middleware to automatically reload selected libs before >> each requests, minimizing server restarts. >> * ring.builder: Helpers for combining Ring endpoints and middleware >> into Ring apps. >> * ring.lint: Linter for the Ring interface, ensures compliance with >> the Ring spec. >> * ring.examples.*: Various example Ring apps. >> >> You can find more details about Ring at its project page on GitHub, >> including a README file for new users and a draft SPEC file that >> documents the Ring interface: >> >> http://github.com/mmcgrana/ring >> >> I've built an open source web app on Ring: http://cljre.com. The >> source for this simple app, available at >> http://github.com/mmcgrana/cljre.com, >> could
Re: non recursive impl in presence of persistence?
seriously? Wow! Interesting. On Tue, Jan 13, 2009 at 12:53 AM, Timothy Pratley wrote: > > >(if (l2) > > The problem is on this line. (l2) is a function call. > Replace with (if l2 > and it works fine :) > > java.lang.IllegalArgumentException: Wrong number of args passed to: > LazilyPersistentVector (NO_SOURCE_FILE:0) > > The error message bears a little explaining: > vectors are functions, > user=> ([1 2 3] 1) > 2 > here I called a a vector [1 2 3] with the argument 1, which gets the > element at 1 > Hence where l2 is a vector in your case, (l2) is a function call but > no index argument was supplied. > > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Designing a Performance Vector Math library in Clojure.
I hear about boxing a lot. What is it? Thanks. On Tue, Jan 13, 2009 at 12:49 AM, CuppoJava wrote: > > Hi, > I'm still getting used to the primitive support in Clojure, and I want > to confirm my understanding. > > As far as I know, primitive support is only supported in local let > bindings, right? > > So in designing a vector math library, > > To translate from Java, one would write a class with primitive fields. > > class Vector{ > float x,y,z; > } > > What would be the best choice in Clojure? > > {:x 0 :y 0 :z 0} > I think a map would have too much overhead to retrieve and set keys. > Is that correct? Although this is the most straight-forward > conversion. > > A 3-element vector > [0 0 0] > Still has the boxing/unboxing overhead. (Unless Clojure supports > primitives in collections, which I'm not sure about) > > A Java array > (make-array Float/TYPE 0) > Is this the most efficient representation? > I don't really like this representation, cause I lose the named > fields, as well as the ability to put other types of data into the > same vector struct. > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Can't lookup java.lang.Long keys in a map using int literal
Keys in a map that are of type long can't be looked up in a map using int literal syntax: user=> (def my_map { (java.lang.Long. "42") "foo"}) #'user/my_map user=> my_map {42 "foo"} user=> (my_map 42) nil user=> (my_map (long 42)) "foo" user=> (= 42 (java.lang.Long. "42")) true I found this behavior incredibly confusing, especially given the fact that ints and longs print the same. I believe this is a bug. Rich, do you agree? Allen --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: when performance matters
On Jan 13, 1:21 am, Stuart Sierra wrote: > If you have > highly-optimized, custom-designed numerical algorithms written in a > low-level language like C++, you will never be able to write a version > that is equally fast in a dynamic, virtual-machine language. I think you are essentially right (although some optimizations can only be performed with runtime information). But highly-optimized low-level code is very rigid. It is difficult to maintain it and adapt it to changing program needs and new technology (with different optimization characteristics). So I am willing to wear a certain loss of performance in exchange for a more agile program, but not too much. I think I'd be willing to wear a 20% loss in performance (perhaps even 50%), but not magnitudes much higher than this. And my gut feeling is that 20% or so should be achievable for a lisp-style language. But the Clojure+JVM solution sounds like it is still a way off from this. > Compilers are smart, but they are not that smart. I am a relative newcomer to lisp, but my impression is that lisp should be thought of as both low level and high level all in one. Ie, that the leverage from lower levels to higher ones happens primarily via macros... which the programmer has direct access to. So in theory a developer could use macros to perform compiler-style optimizations within lisp itself, except these optimizations could be tailored to the particular application. So as long as the base level lisp was implemented efficiently, the whole top-level lisp program could be efficient. But from what I can tell, even the best lisp compilers produce slow code. Even SBCL lisp seems to be 3 to 4 times slower than C++. So I must be misunderstanding something. I can't see why lisps should be inherently so slow. > That being said, experience is the only reliable guide. If you want to > know if Clojure will work for your job, the only thing to do is try > it. Yes, I think some experimental coding might be in order. But I'd like to get as much a grip on the performance landscape as I can beforehand. Thanks for tempering any over-enthusiasm and giving me your best honest assessment. Cheers, Mark P. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Designing a Performance Vector Math library in Clojure.
Do you know Java? It'll be easier to explain if you do. In Java, everything is an Object. Object's are treated as references to a specific memory location which holds the actual data. So when you pass an Object to a method, you're only passing the method the memory location of that Object. For performance reasons Java has primitives. It makes little sense to pass a memory-location of an integer to a method, when the memory- location itself takes up the same number of bits as an integer. So primitives are passed to methods directly by value. Unfortunately, most of the standard API is written around Objects. Vectors, Lists, Maps, all are collections of Objects. If you wish to put a primitive in a Vector, you must first create a Object that wraps around the primitive. ie. class Integer { int i; } This lets you use primitives with the standard API. The process of wrapping a primitive up into a object is called boxing. The reverse is called unboxing. And when Java does it automatically for you, it's called autoboxing. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: when performance matters
There's a study someone did that compared C++, Java, and Lisp implementations of various problems. It could be urban legend, but how I remember it: The best C++ implementation was the fastest for each problem. But the average lisp implementation was faster then the average java or C++ implementation. The variance was the smallest on performance of lisp implementations -- it being a higher-level language. The time to deliver was least on average with lisp and with least variance. The code size and variance thereof was least in lisp. The correctness was greatest in lisp. Moral of the story? Either I remember this wrong or you have to be an extremely proficient programmer to get the bang for the buck out of C++. You gotta know about functors with inline constructors . . . buy lots of books, go to lots of conferences . . . .etc. Of course, another conclusion that makes sense to me is that the average lisp programmer is someone whose been coding for a while. Statistics can mislead. What were the sample sets like? Did the same people code for each language, etc., etc. Also, were it not for the terrible syntax for STL-type stuff (and the terrible, mile long errors) , , , ,and the terrible compile times, can anyone really say that C++ isn't a powerful language? Have you seen all the crazy stuff in the boost libraries? People extend them occasionally with parallel implementations, too. On Tue, Jan 13, 2009 at 1:28 AM, Mark P wrote: > > On Jan 13, 1:21 am, Stuart Sierra wrote: > > If you have > > highly-optimized, custom-designed numerical algorithms written in a > > low-level language like C++, you will never be able to write a version > > that is equally fast in a dynamic, virtual-machine language. > > I think you are essentially right (although some optimizations > can only be performed with runtime information). But highly-optimized > low-level code is very rigid. It is difficult to maintain it and > adapt it > to changing program needs and new technology (with different > optimization characteristics). > > So I am willing to wear a certain loss of performance in exchange > for a more agile program, but not too much. I think I'd be willing > to wear a 20% loss in performance (perhaps even 50%), but not > magnitudes much higher than this. And my gut feeling is that > 20% or so should be achievable for a lisp-style language. But the > Clojure+JVM solution sounds like it is still a way off from this. > > > Compilers are smart, but they are not that smart. > > I am a relative newcomer to lisp, but my impression is that > lisp should be thought of as both low level and high level > all in one. Ie, that the leverage from lower levels to higher > ones happens primarily via macros... which the programmer > has direct access to. So in theory a developer could use > macros to perform compiler-style optimizations within > lisp itself, except these optimizations could be tailored > to the particular application. So as long as the base level > lisp was implemented efficiently, the whole top-level > lisp program could be efficient. But from what I can tell, > even the best lisp compilers produce slow code. Even > SBCL lisp seems to be 3 to 4 times slower than C++. > So I must be misunderstanding something. I can't see > why lisps should be inherently so slow. > > > That being said, experience is the only reliable guide. If you want to > > know if Clojure will work for your job, the only thing to do is try > > it. > > Yes, I think some experimental coding might be in order. But > I'd like to get as much a grip on the performance landscape as > I can beforehand. > > Thanks for tempering any over-enthusiasm and giving me your > best honest assessment. > > Cheers, > > Mark P. > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Designing a Performance Vector Math library in Clojure.
> {:x 0 :y 0 :z 0} > I think a map would have too much overhead to retrieve and set keys. > Is that correct? Although this is the most straight-forward > conversion. How about a structmap? http://clojure.org/data_structures "StructMaps Often many map instances have the same base set of keys, for instance when maps are used as structs or objects would be in other languages. StructMaps support this use case by efficiently sharing the key information, while also providing optional enhanced-performance accessors to those keys." user=> (defstruct employee :name :id) #'user/employee user=> (struct employee "Mr. X" 10) {:name "Mr. X", :id 10} --~--~-~--~~~---~--~~ You 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: non recursive impl in presence of persistence?
Instead of that being an error, why not overload the vector function so that no args calls the version that returns the list. That seems like a good idea! I wonder if people will object. On Tue, Jan 13, 2009 at 1:23 AM, e wrote: > seriously? Wow! Interesting. > > > On Tue, Jan 13, 2009 at 12:53 AM, Timothy Pratley < > timothyprat...@gmail.com> wrote: > >> >> >(if (l2) >> >> The problem is on this line. (l2) is a function call. >> Replace with (if l2 >> and it works fine :) >> >> java.lang.IllegalArgumentException: Wrong number of args passed to: >> LazilyPersistentVector (NO_SOURCE_FILE:0) >> >> The error message bears a little explaining: >> vectors are functions, >> user=> ([1 2 3] 1) >> 2 >> here I called a a vector [1 2 3] with the argument 1, which gets the >> element at 1 >> Hence where l2 is a vector in your case, (l2) is a function call but >> no index argument was supplied. >> >> >> >> >> >> > --~--~-~--~~~---~--~~ You 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: [ANN] Ring: A Web application library for Clojure.
>> What's does the req object that is passed into the function have in it? The contents of the incoming Ring request (and outgoing Ring response) are described in the SPEC document. I should make this a little clearer in the docs. Good for you for checking the source though! > Which by the way is awesome, because you function takes a map, which doesn't > have to be created from an HttpServletRequest object. For the purposes of > testing, you can just construct a map with the parts you want and pass that > to your function. Exactly. By distilling the request/response process into a single function call with a Clojure map as an argument, we get all the power and flexibility of Clojure and its data structures as well as the ability to concisely construct test cases for Ring components. Note also that we are not limited to the values supplied by the original Ring handler - middleware components may want to assoc in values both on the way up to the endpoint app and on the way down back to the client. For example, post body parsing middleware could process the response body and assoc the parsed value into the request before proxying back to the main app. On the response side, middleware might assoc in additional headers to augment the response, as ring.file-info does to File responses. Thanks for your comments, - Mark On Tue, Jan 13, 2009 at 1:19 AM, Paul Barry wrote: > To answer my own question: > [#^HttpServletRequest request] > {:server-port (.getServerPort request) >:server-name (.getServerName request) >:remote-addr (.getRemoteAddr request) >:uri (.getRequestURI request) >:query-string (.getQueryString request) >:scheme (keyword (.getScheme request)) >:request-method (keyword (.toLowerCase (.getMethod request))) >:headers (reduce > (fn [header-map #^String header-name] > (assoc header-map > (.toLowerCase header-name) > (.getHeader request header-name))) > {} > (enumeration-seq (.getHeaderNames request))) >:content-type (.getContentType request) >:content-length (let [len (.getContentLength request)] > (if (>= len 0) len)) >:character-encoding (.getCharacterEncoding request) >:body (.getInputStream request)}) > Which by the way is awesome, because you function takes a map, which doesn't > have to be created from an HttpServletRequest object. For the purposes of > testing, you can just construct a map with the parts you want and pass that > to your function. Great Work! > On Tue, Jan 13, 2009 at 1:13 AM, Paul Barry wrote: >> >> What's does the req object that is passed into the function have in it? >> >> On Mon, Jan 12, 2009 at 11:45 PM, Mark McGranaghan >> wrote: >>> >>> Hi All, >>> >>> I'm happy to announce the alpha release of 'Ring', a library inspired >>> by Python's WSGI and Ruby's Rack for developing web applications in >>> Clojure. >>> >>> I've made it as easy as humanly possible for you to try it out: >>> >>>git clone git://github.com/mmcgrana/ring.git >>>cd ring >>>java -Djava.ext.dirs=jars clojure.main src/ring/examples/ >>> hello_world.clj >>> >>> And your up and running with your first Ring web app, which you can >>> see at http://localhost:8080/ in your browser. >>> >>> The basic idea of Ring is that web apps are just Clojure functions >>> that take a standardized request as a single argument and return and >>> standardized response. For example, the hello_world.clj script from >>> above is: >>> >>> (ns ring.examples.hello-world >>> (:require ring.jetty) >>> (:import java.util.Date java.text.SimpleDateFormat)) >>> >>> (def formatter (SimpleDateFormat. "HH:mm:ss")); >>> >>> (defn app >>> [req] >>> {:status 200 >>> :headers {"Content-Type" "text/html"} >>> :body(str "Hello World from Ring" >>>"The current time is " >>>(.format formatter (Date.)) ".")}) >>> >>> (ring.jetty/run {:port 8080} app) >>> >>> Its nice to be able to get to "Hello World" so quickly, but the real >>> power of Ring is that apps are just functions - hence we can combine, >>> wrap, curry, and generally manipulate them as first class values. >>> >>> For example, someone asked in #clojure today how they could make their >>> web app provide a cleaned backtrace as an HTML response when it raised >>> exceptions. To add such exception handling to our Hello World Ring app >>> we would just use the ring.backtrace middleware: >>> >>>(ring.jetty/run {:port 8080} app) >>> >>>becomes >>> >>>(ring.jetty/run {:port 8080} >>> (ring.backtrace/wrap >>>app)) >>> >>> Similarly, one might want to have changes to a web app's code be >>> reflected in real time in the development environment, so as to avoid >>> constantly having to reboot the webserver. The ring.reload middleware >>> ac
Re: Designing a Performance Vector Math library in Clojure.
ah great explanation. That will help a lot. I found that annoying in Java. On Tue, Jan 13, 2009 at 1:38 AM, CuppoJava wrote: > > Do you know Java? It'll be easier to explain if you do. > > In Java, everything is an Object. Object's are treated as references > to a specific memory location which holds the actual data. So when you > pass an Object to a method, you're only passing the method the memory > location of that Object. > > For performance reasons Java has primitives. It makes little sense to > pass a memory-location of an integer to a method, when the memory- > location itself takes up the same number of bits as an integer. So > primitives are passed to methods directly by value. > > Unfortunately, most of the standard API is written around Objects. > Vectors, Lists, Maps, all are collections of Objects. If you wish to > put a primitive in a Vector, you must first create a Object that wraps > around the primitive. > > ie. class Integer { > int i; > } > > This lets you use primitives with the standard API. > > The process of wrapping a primitive up into a object is called boxing. > The reverse is called unboxing. And when Java does it automatically > for you, it's called autoboxing. > > > --~--~-~--~~~---~--~~ You 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: non recursive impl in presence of persistence?
On Jan 13, 5:57 pm, e wrote: > Instead of that being an error, why not overload the vector function so that > no args calls the version that returns the list. That seems like a good > idea! I wonder if people will object. Actually in your case that would not work, because l2 can also be nil. (nil) is a function call to nil, and you can't call nil either. Ok so if nil were to implement a function that returned nil you would be home free... But really, isn't that just more confusing than the problem you are trying to solve? what's so bad about writing l2 instead of (l2)? Anything in parenthesis is a function call. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Designing a Performance Vector Math library in Clojure.
BTW Rich, The documentation http://clojure.org/data_structures hints that accessors are faster than regular map lookups and provides the following example: (reduce (fn [n y] (+ n (:fred y))) 0 x) -> 45 (reduce (fn [n y] (+ n (fred y))) 0 x) -> 45 However I think it would be clearer if you explicitly showed the speed improvement: user=> (time (reduce (fn [n y] (+ n (:fred y))) 0 x)) "Elapsed time: 100.838989 msecs" 45 user=> (time (reduce (fn [n y] (+ n (fred y))) 0 x)) "Elapsed time: 48.82307 msecs" 45 Regards, Tim. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: when performance matters
Lisps are not inherently slow. SBCL, Clojure and several Schemes are all much faster than most popular high-level languages (e.g. Python, Perl, Ruby...) while being at least as high-level. Optimized code in SBCL may only be marginally slower than C when type declarations are used properly. The code is usually littered with type declarations and just as unsafe as C (things like integer overflows become possible, while Lisp would ordinarily promote an int to a bigint automatically). The nice thing is that you usually only have to do this to the inner loops. All the glue code can be written in potentially slow, but highly abstract idiomatic Lisp. This is similar to a common idiom in the C world, where a scripting language like Lua is embedded to make writing the parts that aren't speed-critical easier. Clojure, at best should be about as fast as Java, if you use type hints and unchecked math. A good Common Lisp will probably be slightly faster. Stalin, a highly-optimized subset of Scheme may be even faster. There's no magic number of cores where Clojure becomes faster than C+ +. If your C++ code is parallel and well-written, it will probably always be faster than Clojure. If your current code is single- threaded, but parallelizable and you have an 8-core machine, you might get faster results merely by using one of the operations from clojure.parallel. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: when performance matters
You're probably thinking of this: http://www.flownet.com/gat/papers/lisp-java.pdf There's also the (in)famous language benchmark site: http://shootout.alioth.debian.org/ --~--~-~--~~~---~--~~ You 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 much Clojure source code is complicated?
Hey, How much Clojure source code is complicated? I'm not a programming Godfather but I would like to study Clojure source code. Could an intermediate programmer like me grasp the source code? Thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---