Re: FAQ
> Suggestions for entries welcome here. > > > > Rich > Here's another that was a "gotcha" for me for an hour or two... Why after using map/reduce/for to change a java object does the object remain unchanged? (defn initv1 [myseq] (let [v (java.util.Vector.)] (for [x myseq] (.addElement v x)) v)) (initv1 [1 2 3]) ; => (java.util.Vector. []) ; or... (defn initv2 [myseq] (let [v (java.util.Vector.)] (map (fn [x] (.addElement v x)) myseq) v)) (initv2 [1 2 3]) ; => (java.util.Vector. []) As map/reduce/for are lazy, the "let" construct does not actually "take" any elements from the map/reduce/for. In this case, use doseq... (defn initv3 [myseq] (let [v (java.util.Vector.)] (doseq [x myseq] (.addElement v x)) v)) (initv3 [1 2 3]) ; => (java.util.Vector. [1 2 3]) (Actually this happened in a more complex function, but the essence was that a new java object was instantiated in a let and I'd used a map to call a method on that object with all the items from a sequence. I could not understand why the object remained unchanged afterwards until I simplified it down to the above example). Regards, Adrian --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 encapsulate local state in closures
On Dec 22, 2:34 pm, "Mark Engelberg" wrote: > On Mon, Dec 22, 2008 at 4:23 AM, Parth Malwankar > > wrote: > > If I get it right, atoms are quite useful to maintain state > > in the context of a single thread with memoization and > > counter (within a thread) being two examples. > > No, RH said that atoms were definitely intended for multiple threads, > not just single threads. But their use is highly specific. With > memoization, it doesn't matter if things get retried, as long as > things don't get "lost". atombasically guarantees that the ref and > the set occur atomically (via swap), so you don't have to worry about > two threads losing something from the cache as follows: > Current cache {:a 1 :b 2} > One thread tries to add :c 3, and another tries to add :d 4. > Without atomic swap, one thread could try to update the cache to {:a 1 > :b 2 :c 3} and the other to {:a 1 :b 2 :d 4} (because they are both > basing their updates on what they see). Whichever one wins, one of > the values will be "lost" from the cache.) > So atoms make this one guarantee, allowing safe multithread > memoization, but at great risk for other types of applications, > because most "seemingly-obvious" uses for atoms would probably be > hosed by the possible retry. > > I fear a lot of people are going to end up misusing atoms. I assume > they were necessary to make memoization perform better than under the > ref-with-commute approach. It's important to distinguish between updating atoms within transactions and outside transactions. In the former case, one has to ensure the update function can be retried without ill-effects. However, outside a transaction, atoms are just mutable values, that can safely be shared between threads, provided that their updating does not need to be coordinated with other updates (to other atoms, refs or agents). Here's an example; say we have a multi-threaded service where we wish to share a single counter to use as say a serial id. The following code initializes serid to 0 and provides a function incserid to increment it. (def serid (atom 0)) (defn incserid [] (swap! serid inc)) (defn docount [n cntr] (dotimes [ind n] (cntr))) Now, the following uses a thread factory to instantiate (nthreads) number of threads, each which will execute the above incrementor (ncount) number of times... (import '(java.util.concurrent Executors)) (def th-factory (Executors/newSingleThreadExecutor)) (defn do-thrds [nthreads ncount] (dotimes [t nthreads] (.submit th- factory (partial docount ncount incserid So, if we then initiate 100 threads to each increment the serid 1 times... (do-thrds 100 1) @serid =>100 We see that the threads have happily shared the atom and updated it correctly with no ill-effects. Note the lack of requirement for dosync. So in summary, atoms are great (and should be used in preference to refs) where the shared state needs to be mutable, shared and independent (not requiring coordinated update with other objects). Regards, Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: SLIME: trouble with java.lang.OutOfMemoryError
>I might look at the JEdit plugin though - JEdit is nice, for simple >editing, which might be good enough for me for now. I similarly haven't had time to relearn emacs and have used jedit quite sucessfully with jedit-mode. I keep one or more terminal window tabs open each with a REPL launched with rlwrap and then just copy and paste from the associated jedit tab/buffer. With up_arrow and dn_arrow bound to "back_history" and "forward_history" in rlwrap, it's easy to try stuf in the REPL, recall/edit previous lines, etc, and copy/paste back to jedit when necessary. The main advantage for me is this works identically when I have an ssh session open to a server with REPL/rlwrap. I can similarly copy/paste from jedit and do very interactive development directly on the server as well as on my local machine, switching between everything with one or two keystrokes. I'm just about down to a pure keystroke driven dev environment with almost never touching the mouse. Primiive and a bit messy, but it works well. [Footnote to the above - I also have a terminal tab open just for compiles. Using ant (build.xml's adapted from clojure's build), the full cycle includes then tabbing to the ant terminal, recalling/running the build and using rsync to copy changed classes to the server. I can then immediately switch to the server/ssh tab and reload/work with the newly built code.] On Mon, Jan 12, 2009 at 5:28 AM, Korny Sietsma wrote: > > I have had similar problems with enclojure. But having gone through > similar IDE pain working in Ruby on Rails, the Netbeans support ended > up being way ahead of most IDEs, so I have hopes that enclojure will > get there in time. (My biggest annoyance? The fact that you can't > open existing code as a new project - I want to browse > clojure-contrib, but I can only do it by creating a new "hello world" > project first!) > > I'd kind-of like to re-learn emacs - many years ago I was a keen emacs > user - my biggest problem is that I'm on a Mac, and I have to keep > switching between IDEs and PCs (my work desktop is Linux) not to > mention languages. I don't have the spare brain cells to learn > another set of key bindings! I need an IDE with easy built-in help, > and while "M-x slime-cheatsheet" is handy, it doesn't spare me the > world-o-pain when I hit "Alt-w" (one of the few keystrokes my fingers > remember from last time) and my emacs window closes! Argh! > > So I try to stick with IDEs that have everything on menus, so when I > forget the "open file anywhere in project" command for a particular > IDE, I can look it up. (Does Emacs have this, by the way? It doesn't > really have a "project" concept... ) > > I might look at the JEdit plugin though - JEdit is nice, for simple > editing, which might be good enough for me for now. > > Incidentally, if you want a language with an editor built in, why not > look at Smalltalk? I vaguely recall that was a big part of the > original language concept. I haven't ever played with it myself, but > the most popular current flavour seems to be Squeak: > http://www.squeak.org/ > > - Korny > > > On Sun, Jan 11, 2009 at 1:18 PM, e wrote: >> >> seems like enclosjure addresses a bunch of my problems/questions. It >> also seems to work like we wanted SLIME to work, more or >> less . . .where you attach to the vm that's used for execution . . . >> only you attach to the REPL, I think, which still accomplishes the >> goal of keeping the editor separate from the memory, but what about >> having the REPL being able to attach to the vm it is managing. Then >> it wouldn't be something that NetBeans/enclosure is doing . . . rather >> something that's part of the language. >> >> So, yeah. enslojure sets up a HelloWorld that you can play with right >> away. In fact, when you click on "build" it even tells you how you >> could run your application from the command line using a java >> command. It jars up you whole clojure project and everything. Nice. >> On the other hand, I couldn't figure out how to use NetBeans' run >> button. it couldn't find main or something. So I also couldn't debug >> using NetBeans' debugger because of this. Also, it isn't clear how to >> get different clojure files to work together. Do you use the (load) >> function? If so, I don't know how the project thinks of relative file >> locations. It's not as clean/clear as java (for a beginner, at least) >> where you just import classes you want to use . . and make >> packages. . . . or modules in python. I don't know what the notion of >> "path" is in clojure. I see the namespace stuff but have no clue how >> to make it work yet. Are you just supposed to use one giant file for >> all your work? That wouldn't be good for teams, for sure. . . only >> for hacking. Also the REPL errors are USELESS to a beginner. >> something about iSeq all the time. The moral for me there was no to >> make an error. Better than where I was before enclojure. Again, I >> contend that
Re: non recursive impl in presence of persistence?
Bear with the trials and tribulations (of grokking functional/clojure). It takes a few weeks of trying things out, absorbing the documentation and group archives, watching the group posts and then suddenly there are one or two "aha" moments and then the flood gates open! When you've crossed the threshold, it's too late - you can never go back. You'll want to go and redo everything you've ever done imperatively! For me the "aha" moments came when I first (really) understood reduce, map and fn. I'd reccomend focusing on those and trying to (first) do all your looping constructs with those rather than loop/recur - that forces you to learn to think functional while loop/recur still lets your mind stick to imperative patterns. Regards, Adrian. On Mon, Jan 12, 2009 at 7:24 AM, e wrote: > here's a good explanation: > http://groups.google.com/group/clojure/browse_thread/thread/3c22b35f079e0de6/95fc0b334ab77c1f > > I wasn't thinking about closures since I've only recently even learned what > they are. I actually don't know if it will ever occur to me to use them, > but it sounds like they are the reason we are encouraged to jump through > such hoops even for local variables. closures allow them to "leak". > > 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. Document the usage, and > woe be it unto the user who doesn't 'RTFM'". > > Another thing is to make the common case easy . . . .and uh, mutable local > variables are pretty darn common, as Rich anticipated when he predicted that > people would be excited about the 'with-local-vars' macro. I was thinking > the same thing, "fine, I'll learn how to write macros, then". I can see > that this issue comes up again and again with everyone who walks in the > door, and it probably will continue to. Who knows, maybe Rich will change > the world. It sure will take a lot of energy. That's for sure. > > On Sun, Jan 11, 2009 at 10:27 PM, Timothy Pratley > wrote: >> >> > thread should own the memory that's created. Each thread should have >> > its own asynchronous stack to push local variables onto that no one >> > else is allowed to see. >> >> Just for the record, Clojure does support local variable that behave >> exactly as you would expect them: >> (with-local-vars [x 3] >> (while (> @x 0) >>(var-set x (- @x 1))) >> @x) >> -> 0 >> >> Using an atom is unnecessary in this case because access is totally >> local. Using an unsafe atom set is a bad habit, as discussed in detail >> on another thread: >> >> http://groups.google.com/group/clojure/browse_thread/thread/6497e7c8bc58bb4e/c5b3c9dbe6a1f5d5 >> >> However as you have already seen there are more elegant ways to write >> the solution without either. >> >> >> > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Common Lisp format function is now fully* CL-compatible
My compliments - this is a great addition to the clojure suite! On Thu, Jan 29, 2009 at 10:15 AM, Tom Faulhaber wrote: > > The cl-format library now implements the full* Common Lisp spec for > format (* = with the exception of a couple of things used by the > internals of the CL pretty printer). > > So if you prefer the Lisp style of formatting to the Java style, you > should be good to go. > > cl-format is hosted on github at http://github.com/tomfaulhaber/cl-format. > There's a nice long README on the home page there that will tell you > more about what it is and what it does. Being github, the source is > also there for everybody's enjoyment. > > The easiest way to install cl-format is just to grab the the jar from > github: http://github.com/tomfaulhaber/cl-format/raw/master/cl-format.jar. > Just add that to your classpath and you'll be formatting away in no > time. > > There are a few short examples at > http://github.com/tomfaulhaber/cl-format/tree/master/com/infolace/format/examples > which you can peruse. > > This is a "Clojure-friendly" implementation: written from scratch and > published under the EPL. So it can go anywhere Clojure can go. But, > because it's from scratch, it's likely to have some bugs. If you find > one, let me know. > > Next, I'll take a swing at pretty printing. > > Enjoy! > > 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: what does -> mean?
Some examples... ; using -> (f1 (f2 (f3 (f4 x ; can be "flattened" to (-> x f4 f3 f2 f1) Useful for nested maps... user=> (def m {:one {:a 1 :b 2 :c {:x 10 :y 11}}} ) #'user/m user=> (-> m :one :c :x) 10 user=> (-> x :one :b) 2 On Sun, Feb 1, 2009 at 5:31 AM, Jason Wolfe wrote: > > On Jan 31, 7:09 pm, wubbie wrote: >> Hi, >> >> I saw in ants.clj a notation (->). >> what is it? >> For example, >> (defn place [[x y]] >> (-> world (nth x) (nth y))) > > Did you check the docs? > > On the website: > http://clojure.org/API#toc21 > > Within clojure itself: > > 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. > > Also: > user> (macroexpand '(-> world (nth x) (nth y))) > (nth (clojure.core/-> world (nth x)) y) > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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?
Sorry! That should have read; (-> m :one :b) 2 On Sun, Feb 1, 2009 at 5:13 PM, e wrote: > I was able to work through the first two examples, and thanks for those. I > will have to study maps more, I guess, to understand the last one. I don't > know where 'x' came from: >> >> user=> (-> x :one :b) >> 2 >> > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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?
I would say "thread" is used here colloquially - i.e. "works the expr through the forms" and "form" is as defined in clojure.org/reader. On Sun, Feb 1, 2009 at 4:01 PM, e wrote: > is there a definition of "thread" somewhere, and a definition of "form" > somewhere? > > Thanks. > > On Sat, Jan 31, 2009 at 10:31 PM, Jason Wolfe wrote: >> >> On Jan 31, 7:09 pm, wubbie wrote: >> > Hi, >> > >> > I saw in ants.clj a notation (->). >> > what is it? >> > For example, >> > (defn place [[x y]] >> > (-> world (nth x) (nth y))) >> >> Did you check the docs? >> >> On the website: >> http://clojure.org/API#toc21 >> >> Within clojure itself: >> >> 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. >> >> Also: >> user> (macroexpand '(-> world (nth x) (nth y))) >> (nth (clojure.core/-> world (nth x)) y) >> >> > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: if-let
Here's one, I'm setting basedir to either :basedir in a map in *locs (a thread-local var) or to "." if :basedir was not found in the map... (let [basedir (if-let [bdir (:basedir *locs)] bdir ".")] ...) i.e bdir assumes the value of the test and if that is not false (or nil) returns it otherwise the else part. On Sun, Feb 8, 2009 at 4:25 PM, Mark Volkmann wrote: > > Can someone show me an example of a good use of if-let? > > I find its doc string a little confusing. It says "If test is true, > evaluates then with binding-form bound to the value of test, if not, > yields else". However, it doesn't have a parameter named "test". I > assume it means "If the binding evaluates to true ...". > > Also, it has a parameter named "bindings", but it should perhaps be > named "binding" because it doesn't allow specifying more than one > binding. > > -- > 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: if-let
Thanks Meikel. There's always something new to learn. I'm also fast learning that if something doesn't look quite elegant in one's code, then there's bound to be an elegant clojure way of doing it! On Sun, Feb 8, 2009 at 4:51 PM, Meikel Brandmeyer wrote: > Hi, > > Am 08.02.2009 um 15:47 schrieb Adrian Cuthbertson: > >> Here's one, I'm setting basedir to either :basedir in a map in *locs >> (a thread-local var) or to "." if :basedir was not found in the map... >> >> (let [basedir (if-let [bdir (:basedir *locs)] bdir ".")] >> ...) >> >> i.e bdir assumes the value of the test and if that is not false (or >> nil) returns it otherwise the else part. > > This can be written more concise with get or even with :basedir alone: > > (let [basedir (get *locs :basedir ".")] ...) > (let [basedir (:basedir *locs ".")] ...) > (let [basedir (*locs :basedir ".")] ...) > > All but the last form work also if *locs is nil. > > Sincerely > Meikel > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Idiomatic sub-hashmap
Hi, I have had need of a "sub" hash map function and implemented it as follows; (defn sub-hashmap "Return a sub map of hmap containing the specified keys." [hmap & ks] (reduce (fn [mm k] (assoc mm k (k hmap))) {} ks)) (sub-hashmap {:a 1 :b 2 :c 3} :a :c) ;=> {:c 3, :a 1} Is there a similar existing function or a more idiomatic way of doing this? Thanks, Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Idiomatic sub-hashmap
Thanks! On Fri, Feb 13, 2009 at 1:28 PM, Timothy Pratley wrote: > > Yup: select-keys > > user=> (select-keys {:a 1 :b 2 :c 3} [:a :c]) > {:c 3, :a 1} > > Regards, > Tim. > > On Feb 13, 8:01 pm, Adrian Cuthbertson > wrote: >> Hi, >> >> I have had need of a "sub" hash map function and implemented it as follows; >> >> (defn sub-hashmap >> "Return a sub map of hmap containing the specified keys." >> [hmap & ks] >> (reduce (fn [mm k] (assoc mm k (k hmap))) {} ks)) >> >> (sub-hashmap {:a 1 :b 2 :c 3} :a :c) >> ;=> {:c 3, :a 1} >> >> Is there a similar existing function or a more idiomatic way of doing this? >> >> Thanks, Adrian. > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: with-local-vars vs. let
Have a look at compojure - a good example of with-local-vars is where a servlet request is executed. Each (get, post) request occurs in its entirety on a single (jetty or tomcat) thread. The compojure call to the application service function binds the http headers, servlet request parameters, etc, using with-local-vars and then calls the app function. These values are all then in scope for the called service function _and_ any functions that it in turn calls. This is all safe without using refs/atoms as the values are all "local-thread" bound. Here's an application example... (declare *locs*) (declare my-service) (def my-servlet (proxy [HttpServlet] [] (service [request response] (binding [*locs* {:basedir "."}] (my-service this request response) (defservice "my-" ; this is a compojure macro defining my-service (ANY "*" (var-set (var *locs*) (authenticate cookies request)) (if (nil? (:usr *locs*)) (frm-login "No session") :next)) (GET "/logged-in-app-call" ... Here we declare *locs* as an unbound var in the namespace. Then my-servlet proxies the servlet class and the compojure service call has all the headers, etc bound in with-local-vars. Then for app purposes, we bind *locs* to some default app related stuff before the call to my-service. Then in my-service, the first thing we do is to authenticate the user using a cookie's information (cookies are local thread bound). Authentication then adds {:usr } to whatever was in *locs* and returns the new map. Var-set updates *locs* and either a login page is invoked or we drop through (:next) to the matching app "path". All app functions then have access to the *locs* map and can use the :usr credentials, default stuff, etc. A bit contrived from the actual app and a bit complex to explain, but local vars are very useful in this situation. Regards, Adrian. On Fri, Feb 13, 2009 at 3:10 PM, Konrad Hinsen wrote: > > On Feb 13, 2009, at 13:31, Mark Volkmann wrote: > >> What are some reasons to use with-local-vars instead of let or >> binding? > > Let just creates bindings for a lexical scope. They cannot be > modified at all. > > Binding and with-local-vars deal with vars, i.e. mutable references. > Binding creates a dynamic scope for already existing vars that are > accessible in some namespace. With-local-vars also creates a dynamic > scope, but for newly created anonymous vars. > > So far for the theory. I have to admit that in my own experience, > every time I considered using with-local-vars, I ended up realising > that what I really wanted is atoms or refs. Which means that I cannot > cite a use case for with-local-vars. I scanned through the source > code of clojure and clojure-contrib to see if with-local-vars is used > anywhere at all, but the answer is no. > > 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: with-local-vars vs. let
> What I see in your example is binding, but I don't see with-local- > vars anywhere. Or did I misunderstand something? Sorry, I checked the compojure source again and the servlet headers, cookies, etc are wrapped in a "with-servlet-vars" macro (rather than with-local-vars) which just uses let. The html parameters are wrapped in *params* using binding rather than with-local-vars, so my example does not actually demonstrate with-local-vars, but rather just thread-local use of vars with binding. On Fri, Feb 13, 2009 at 5:19 PM, Konrad Hinsen wrote: > > On Feb 13, 2009, at 15:35, Adrian Cuthbertson wrote: > >> Have a look at compojure - a good example of with-local-vars is where >> a servlet request is executed. Each (get, post) request occurs in its >> entirety on a single (jetty or tomcat) thread. The compojure call to >> the application service function binds the http headers, servlet >> request parameters, etc, using with-local-vars and then calls the app >> function. These values are all then in scope for the called service >> function _and_ any functions that it in turn calls. This is all safe >> without using refs/atoms as the values are all "local-thread" bound. > > What I see in your example is binding, but I don't see with-local- > vars anywhere. Or did I misunderstand something? > > 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: Algebraic data types in clojure.contrib
Hmm, I get a stack overflow when trying that make macro. After using macroexpand-1... (with-meta (struct stuff 1 2) {:type (keyword (str *ns*) (name (quote stuff)))}) I still get the stack overflow. I'm on svn 1307, jdk 1.5 mac osx. Any ideas? Regards, Adrian. On Thu, Feb 26, 2009 at 7:08 AM, Jeff Valk wrote: > > How about appending type metadata automagically... > > (defstruct stuff :a :b) > (defmacro make > "Creates a new instance of struct t and appends 'type' t as metadata" > [t & vs] > `(with-meta > (struct ~t ~...@vs) > {:type (keyword (str *ns*) (name '~t))})) > > user> (make stuff 1 2) > {:a 1, :b 2} > > user> (meta (make stuff 1 2)) > {:type :user/stuff} > > -Jeff > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Modular composition/plugin architecture
Hi, How would one create a "plugin" modular composition using clojure functions/modules only (i.e without resorting to java interface/ plugin class implementations)? For example; ; say myutil/ut1.clj contains (ns 'myutil.ut1) (defn foo [] :foo-ut1) ; and myutil/ut2.clj contains (ns 'myutil.ut2) (defn foo [] :foo-ut2) ;and mylib/lib1.clj contains (defn libfoo [] (foo)) Then from my app, I'd like to tell mylib.lib1 which ut to use when it loads, before calling libfoo. Is this possible, or is there some other clojure way of doing this? Thanks, Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Modular composition/plugin architecture
Thanks Itay, that's exactly what I need. On Thu, Mar 5, 2009 at 1:15 PM, Itay Maman wrote: > > Here's how plugin support is implemented in Waterfront: > > The last expression in each plugin is the "plguin init function": a > function (can be anonymous) that takes a single parameter (a map) and > returns new map. > The load-plugin function takes a strings (specifying the path to > a .clj file), and performs load-file on each string. Then, load-plugin > evals the value returned by load-file (which, in fact, is the plugin > init function) passing a map as a parameter. If you're loading several > plugins the result returned from the init function will be used as the > new map passed to the next plugin. > > Anyway, enough talking, let's go coding: > > ; say myutil/ut1.clj contains > (ns 'myutil.ut1) > (defn foo [] :foo-ut1) > > ; init function of ut1 > (fn [m] (assoc m :foo foo)) > > > ; and myutil/ut2.clj contains > (ns 'myutil.ut2) > (defn foo [] :foo-ut2) > > ; init function of ut2 > (fn [m] (assoc m :foo foo)) > > > (defn load-plugin [path] > ((load-file path) {}) ) > > ;mylib/lib1.clj > (defn libfoo [] > (((load-plugin (if some-condition "myutil/ut1.clj" "myutil/ > ut2.clj")) :foo)) ) > > > > That's it. In Waterfront this design is integrated with the context > pattern which I described here a few days ago. > > Hope that helps. > > -- > Itay Maman > http://javadots.blogspot.com > > On Mar 5, 6:48 am, Adrian Cuthbertson > wrote: >> Hi, >> >> How would one create a "plugin" modular composition using clojure >> functions/modules only (i.e without resorting to java interface/ >> plugin class implementations)? >> >> For example; >> ; say myutil/ut1.clj contains >> (ns 'myutil.ut1) >> (defn foo [] :foo-ut1) >> >> ; and myutil/ut2.clj contains >> (ns 'myutil.ut2) >> (defn foo [] :foo-ut2) >> >> ;and mylib/lib1.clj contains >> (defn libfoo [] (foo)) >> >> Then from my app, I'd like to tell mylib.lib1 which ut to use when it >> loads, before calling libfoo. >> Is this possible, or is there some other clojure way of doing this? >> >> Thanks, >> Adrian. > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: filter-split
That's the beauty of this language - there are many ways to skin the cat! Here's a version using reduce... (defn filt-split [pred col] (reduce (fn [[a b] x] (if (pred x) [(conj a x) b] [a (conj b x)])) [[] []] col)) (filt-split even? [1 2 3 4 5 6 7 8]) [[2 4 6 8] [1 3 5 7]] But when you look at separate in clojure.contrib.seq-utils its simple and elegant; (defn separate [f s] [(filter f s) (filter (complement f) s)]) Rgds, Adrian. On Sun, Mar 8, 2009 at 6:44 AM, e wrote: > check the discussion with the subject, "time lies, even with doall". We > came up with something like the following, but some name change change > tweaks were suggested. This thing takes a pred and a collection and returns > a list of two collections -- one that passes the pred, and one that fails. > > (defn filt-rem [pred coll] > (loop [l1 () l2 () [f & r] coll] > (if f > (if (pred f) > (recur (conj l1 f) l2 r) > (recur l1 (conj l2 f) r)) > (list l1 l2 > > > On Sat, Mar 7, 2009 at 11:37 PM, Jeffrey Straszheim > wrote: >> >> There is separate in seq_utils in contrib. >> >> On Sat, Mar 7, 2009 at 11:29 PM, David Sletten wrote: >>> >>> I'm reading the Sequences chapter of Programming Clojure, and Stu >>> points out that split-with combines the semantics of take-while and >>> drop-while. But is there a function that does something similar with >>> "filter"? Namely, rather than simply filtering the elements of a >>> collection that satisfy a predicate I also want to capture those that >>> don't. Something like this: >>> (defn filter-split [pred coll] >>> (loop [trues '() falses '() coll coll] >>> (cond (empty? coll) >>> (vector (reverse trues) (reverse falses)) >>> (pred (first coll)) >>> (recur (cons (first coll) trues) falses (rest coll)) >>> :else >>> (recur trues (cons (first coll) falses) (rest coll) >>> >>> (filter-split #{\a\e\i\o\u} "is this not pung?") => [(\i \i \o \u) >>> (\s \space \t \h \s \space \n \t \space \p \n \g \?)] >>> (filter-split even? (range 10)) => [(0 2 4 6 8) (1 3 5 7 9)] >>> >>> Aloha, >>> David Sletten >>> >>> >> >> >> > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: filter-split
> ...repeated creation of the ephemeral vectors isn't too expensive. With Clojure, although it looks like the immutable vectors are being re-created on each iteration, under the covers it's really just pointers being updated and the operations are (about) as efficient as a loop/recur method. > ...I don't want to traverse the collection twice. Yes, I guess that even though each filter clause is lazy they each will pass through the entire collection once. On Sun, Mar 8, 2009 at 7:53 AM, David Sletten wrote: > > > On Mar 7, 2009, at 7:17 PM, Adrian Cuthbertson wrote: > >> >> That's the beauty of this language - there are many ways to skin >> the cat! > > Hmmm...I'm not sure what I'll do with a skinless cat. :) > >> Here's a version using reduce... >> >> (defn filt-split [pred col] >> (reduce (fn [[a b] x] (if (pred x) [(conj a x) b] [a (conj b x)])) >> [[] []] col)) >> >> (filt-split even? [1 2 3 4 5 6 7 8]) >> [[2 4 6 8] [1 3 5 7]] >> > > I like that a lot. As long as the repeated creation of the ephemeral > vectors isn't too expensive. > >> But when you look at separate in clojure.contrib.seq-utils its simple >> and elegant; >> (defn separate [f s] >> [(filter f s) (filter (complement f) s)]) >> > > This is exactly what I'm trying to avoid. I don't want to traverse > the collection twice. > > Aloha, > David Sletten > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: filter-split
You're absolutely right... user=> (time (let [[a b] (separate even? (range 100))] (nth a 3))) "Elapsed time: 0.115 msecs" 6 user=> (time (let [[a b] (filt-split even? (range 100))] (nth a 3))) "Elapsed time: 413.614 msecs" 6 and is also more efficient over large sequences... (time (let [[a b] (filt-split even? (range 10))] (nth a 4))) "Elapsed time: 44.64 msecs" 8 user=> (time (let [[a b] (separate even? (range 10))] (nth a 4))) "Elapsed time: 24.042 msecs" 8 I guess there's only one way to skin this cat :-) On Sun, Mar 8, 2009 at 10:29 AM, Laurent PETIT wrote: > It seems to me that neither filt-split nor filter-rem from e are lazy > operations (one uses reduce, the other one uses recur). > The version in clojurecontrib seems to preserve the original property of > filter of returning a lazy sequence. > > My 0,02€, > > -- > Laurent > > 2009/3/8 Adrian Cuthbertson >> >> That's the beauty of this language - there are many ways to skin the cat! >> Here's a version using reduce... >> >> (defn filt-split [pred col] >> (reduce (fn [[a b] x] (if (pred x) [(conj a x) b] [a (conj b x)])) >> [[] []] col)) >> >> (filt-split even? [1 2 3 4 5 6 7 8]) >> [[2 4 6 8] [1 3 5 7]] >> >> But when you look at separate in clojure.contrib.seq-utils its simple >> and elegant; >> (defn separate [f s] >> [(filter f s) (filter (complement f) s)]) >> Rgds, Adrian. >> - Afficher le texte des messages précédents - >> On Sun, Mar 8, 2009 at 6:44 AM, e wrote: >> > check the discussion with the subject, "time lies, even with doall". We >> > came up with something like the following, but some name change change >> > tweaks were suggested. This thing takes a pred and a collection and >> > returns >> > a list of two collections -- one that passes the pred, and one that >> > fails. >> > >> > (defn filt-rem [pred coll] >> > (loop [l1 () l2 () [f & r] coll] >> > (if f >> > (if (pred f) >> > (recur (conj l1 f) l2 r) >> > (recur l1 (conj l2 f) r)) >> > (list l1 l2 >> > >> > >> > On Sat, Mar 7, 2009 at 11:37 PM, Jeffrey Straszheim >> > wrote: >> >> >> >> There is separate in seq_utils in contrib. >> >> >> >> On Sat, Mar 7, 2009 at 11:29 PM, David Sletten >> >> wrote: >> >>> >> >>> I'm reading the Sequences chapter of Programming Clojure, and Stu >> >>> points out that split-with combines the semantics of take-while and >> >>> drop-while. But is there a function that does something similar with >> >>> "filter"? Namely, rather than simply filtering the elements of a >> >>> collection that satisfy a predicate I also want to capture those that >> >>> don't. Something like this: >> >>> (defn filter-split [pred coll] >> >>> (loop [trues '() falses '() coll coll] >> >>> (cond (empty? coll) >> >>> (vector (reverse trues) (reverse falses)) >> >>> (pred (first coll)) >> >>> (recur (cons (first coll) trues) falses (rest coll)) >> >>> :else >> >>> (recur trues (cons (first coll) falses) (rest coll) >> >>> >> >>> (filter-split #{\a\e\i\o\u} "is this not pung?") => [(\i \i \o \u) >> >>> (\s \space \t \h \s \space \n \t \space \p \n \g \?)] >> >>> (filter-split even? (range 10)) => [(0 2 4 6 8) (1 3 5 7 9)] >> >>> >> >>> Aloha, >> >>> David Sletten >> >>> >> >>> >> >> >> >> >> >> >> > >> > >> > > >> > >> >> > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: filter-split
Sorry, further to that last example, if you actually consume all of both even and odd sets then the reduce version is more efficient... (time (let [[a b] (filt-split even? (range 10))] [(nth a 4) (nth b 4)])) "Elapsed time: 36.711 msecs" [8 9] (time (let [[a b] (separate even? (range 10))] [(nth a 4) (nth b 4)])) "Elapsed time: 67.004 msecs" [8 9] On Sun, Mar 8, 2009 at 12:11 PM, Adrian Cuthbertson wrote: > You're absolutely right... > > user=> (time (let [[a b] (separate even? (range 100))] (nth a 3))) > "Elapsed time: 0.115 msecs" > 6 > user=> (time (let [[a b] (filt-split even? (range 100))] (nth a 3))) > "Elapsed time: 413.614 msecs" > 6 > > and is also more efficient over large sequences... > > (time (let [[a b] (filt-split even? (range 10))] (nth a 4))) > "Elapsed time: 44.64 msecs" > 8 > user=> (time (let [[a b] (separate even? (range 10))] (nth a 4))) > "Elapsed time: 24.042 msecs" > 8 > > I guess there's only one way to skin this cat :-) > > > On Sun, Mar 8, 2009 at 10:29 AM, Laurent PETIT > wrote: >> It seems to me that neither filt-split nor filter-rem from e are lazy >> operations (one uses reduce, the other one uses recur). >> The version in clojurecontrib seems to preserve the original property of >> filter of returning a lazy sequence. >> >> My 0,02€, >> >> -- >> Laurent >> >> 2009/3/8 Adrian Cuthbertson >>> >>> That's the beauty of this language - there are many ways to skin the cat! >>> Here's a version using reduce... >>> >>> (defn filt-split [pred col] >>> (reduce (fn [[a b] x] (if (pred x) [(conj a x) b] [a (conj b x)])) >>> [[] []] col)) >>> >>> (filt-split even? [1 2 3 4 5 6 7 8]) >>> [[2 4 6 8] [1 3 5 7]] >>> >>> But when you look at separate in clojure.contrib.seq-utils its simple >>> and elegant; >>> (defn separate [f s] >>> [(filter f s) (filter (complement f) s)]) >>> Rgds, Adrian. >>> - Afficher le texte des messages précédents - >>> On Sun, Mar 8, 2009 at 6:44 AM, e wrote: >>> > check the discussion with the subject, "time lies, even with doall". We >>> > came up with something like the following, but some name change change >>> > tweaks were suggested. This thing takes a pred and a collection and >>> > returns >>> > a list of two collections -- one that passes the pred, and one that >>> > fails. >>> > >>> > (defn filt-rem [pred coll] >>> > (loop [l1 () l2 () [f & r] coll] >>> > (if f >>> > (if (pred f) >>> > (recur (conj l1 f) l2 r) >>> > (recur l1 (conj l2 f) r)) >>> > (list l1 l2 >>> > >>> > >>> > On Sat, Mar 7, 2009 at 11:37 PM, Jeffrey Straszheim >>> > wrote: >>> >> >>> >> There is separate in seq_utils in contrib. >>> >> >>> >> On Sat, Mar 7, 2009 at 11:29 PM, David Sletten >>> >> wrote: >>> >>> >>> >>> I'm reading the Sequences chapter of Programming Clojure, and Stu >>> >>> points out that split-with combines the semantics of take-while and >>> >>> drop-while. But is there a function that does something similar with >>> >>> "filter"? Namely, rather than simply filtering the elements of a >>> >>> collection that satisfy a predicate I also want to capture those that >>> >>> don't. Something like this: >>> >>> (defn filter-split [pred coll] >>> >>> (loop [trues '() falses '() coll coll] >>> >>> (cond (empty? coll) >>> >>> (vector (reverse trues) (reverse falses)) >>> >>> (pred (first coll)) >>> >>> (recur (cons (first coll) trues) falses (rest coll)) >>> >>> :else >>> >>> (recur trues (cons (first coll) falses) (rest coll) >>> >>> >>> >>> (filter-split #{\a\e\i\o\u} "is this not pung?") => [(\i \i \o \u) >>> >>> (\s \space \t \h \s \space \n \t \space \p \n \g \?)] >>> >>> (filter-split even? (range 10)) => [(0 2 4 6 8) (1 3 5 7 9)] >>> >>> >>> >>> Aloha, >>> >>> David Sletten >>> >>> >>> >>> >>> >> >>> >> >>> >> >>> > >>> > >>> > > >>> > >>> >>> >> >> >> >> >> > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: filter-split
Hmm, on the same (micro admittedly) benchmark as above... (time (let [[a b] (unzip-with even? (range 10))] [(nth a 4) (nth b 4)])) "Elapsed time: 177.797 msecs" [8 9] that's a bit slower than both the previous versions. The reduce version does only apply the pred once per item I think? On Sun, Mar 8, 2009 at 12:37 PM, Christophe Grand wrote: > > The question showed up the other day on #clojure with the additional > constraint to evaluate pred only once per item, here is Rich's solution: > > http://paste.lisp.org/display/76458#1 > > (defn unzip-with [pred coll] > (let [pvs (map #(vector (pred %) %) coll)] > [(for [[p v] pvs :when p] v) > (for [[p v] pvs :when (not p)] v)])) > > > Christophe > > David Sletten a écrit : >> I'm reading the Sequences chapter of Programming Clojure, and Stu >> points out that split-with combines the semantics of take-while and >> drop-while. But is there a function that does something similar with >> "filter"? Namely, rather than simply filtering the elements of a >> collection that satisfy a predicate I also want to capture those that >> don't. Something like this: >> (defn filter-split [pred coll] >> (loop [trues '() falses '() coll coll] >> (cond (empty? coll) >> (vector (reverse trues) (reverse falses)) >> (pred (first coll)) >> (recur (cons (first coll) trues) falses (rest coll)) >> :else >> (recur trues (cons (first coll) falses) (rest coll) >> >> (filter-split #{\a\e\i\o\u} "is this not pung?") => [(\i \i \o \u) >> (\s \space \t \h \s \space \n \t \space \p \n \g \?)] >> (filter-split even? (range 10)) => [(0 2 4 6 8) (1 3 5 7 9)] >> >> Aloha, >> David Sletten >> >> > >> >> > > > -- > Professional: http://cgrand.net/ (fr) > On Clojure: http://clj-me.blogspot.com/ (en) > > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
class of java array
I have a java object that either contains a String or an array of Strings. (instance? java.lang.String obj... works fine for the String, but how would I check for the String Array? Thanks, Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: class of java array
Thanks Stuart, Bill - both answers are very useful. On Mon, Mar 9, 2009 at 6:58 PM, .Bill Smith wrote: > >> Here is one way: >> >> (-> (into-array ["one" "two"]) (class) (.getComponentType)) >> -> java.lang.String >> (-> (to-array ["one" "two"]) (class) (.getComponentType)) >> -> java.lang.Object > > The above answer seems to answer the question, "How do I determine > what type of object is inside an array?" I interpreted the original > question to be, "How do I distinguish Arrays from other kinds of > objects?" Here's one way to do that: > > user=> (.isArray (class (into-array ["a"]))) > true > user=> (.isArray (class "a")) > false > > Bill Smith > Austin, TX > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: generating a static method
HI Bill, I also tried the metadata tag and couldn't get it to work, but the following does... (ns gncls.MyStatic (:gen-class :methods [[say-hi [String] String]])) (defn -say-hi [this who] (str "Hi " who)) (defn -say-static-hi [who] (str "Hi " who)) user=> (compile 'gncls.MyStatic) user=> (.say-hi (gncls.MyStatic.) "Bill") "Hi Bill" user=> (gncls.MyStatic/-say-hi "" "Bill") "Hi Bill" user=> (gncls.MyStatic/-say-static-hi "Bill") "Hi Bill" That is, a static method is automatically created for the "prefixed" method which you can call directly. You could make use of :prefix in :gen-class to tidy this up. I'm not sure if this is the whole story though. Regards, Adrian. On Tue, Mar 10, 2009 at 6:03 AM, .Bill Smith wrote: > > The genclass documentation says, "Static methods can be specified with > #^{:static true} in the signature's metadata." I thought that would > mean this: > > (ns tango.test.unit.StaticTest > (:gen-class > :methods [[f [] #^{:static true} void ]])) > > (defn -init [_] ()) > > (defn -f [] (println "hello world!")) > > But that doesn't seem to do the trick: > > ~/projects/junit-clojure$ javap -classpath /home/bsmith/software/ > clojure/trunk/clojure.jar:/home/bsmith/software/junit-4.4/ > junit-4.4.jar:$PWD:$PWD/classes tango.test.unit.StaticTest > public class tango.test.unit.StaticTest extends java.lang.Object{ > public static {}; > public tango.test.unit.StaticTest(); > public java.lang.String toString(); > public boolean equals(java.lang.Object); > public java.lang.Object clone(); > public int hashCode(); > public void f(); > public static void main(java.lang.String[]); > } > > I'm using Clojure rev 1327. > > Bill Smith > Austin, Texas > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: generating a static method
Hi Christophe, It works as per your example, but not with arguments to the method... ns gncls.MyStatic (:gen-class :methods [#^{:static true} [f [String] void ]])) (defn -f [s] ; also [this s] doesn't work (prn "Hi from " s )) (gncls.MyStatic/f "me") java.lang.Exception: No such var: gncls.MyStatic/f (NO_SOURCE_FILE:2) On Tue, Mar 10, 2009 at 9:18 AM, Christophe Grand wrote: > > .Bill Smith a écrit : >> The genclass documentation says, "Static methods can be specified with >> #^{:static true} in the signature's metadata." I thought that would >> mean this: >> >> (ns tango.test.unit.StaticTest >> (:gen-class >> :methods [[f [] #^{:static true} void ]])) >> >> > > Try: > > (ns tango.test.unit.StaticTest > (:gen-class > :methods [#^{:static true} [f [] void ]])) > > > (untested but that's where gen-class expects the metadata to be/) > > HTH > > Christophe > > > -- > Professional: http://cgrand.net/ (fr) > On Clojure: http://clj-me.blogspot.com/ (en) > > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: New in the group and question about Java interaction
> One more question: is there a way to call a function similar to > reloadClasses in Clojure? If so, it would be my solution. Yep, I work with a multi-tab console with a rlwrap repl window and another window for builds (ant) and other general stuff, then I use the clojure load function to reload any classes and/or clj sources that have changed, for example; from the repl... (use 'twlib.jty)(start-jty 8080) which loads and starts my jetty instance. The twlib.jty module (clj) uses (ns :use/:import etc, to load all the dependencies. Then during the session, I might say change twlib/xxx.clj, and I then just use (load "twlib/xxx") to reload the new version. It's not totally reloadable as you have to restart if you add new functions or other structural changes. With rlwrap I have the up-arrow/down-arrows set to incremental command history recall, so you can just type one or 2 characters of a previous repl line, hit the up arrow to recall and press Enter to execute. Tabbing between console tabs and with a good recall setup, it's little more than a couple of key strokes to almost instantaneously do a build, reload or restart. And of course you have full interactivity with the executing environmnent (jetty and other java libs, etc) directly through the repl. I also typically have one or more other console tabs open with ssh sessions to (linux) servers where I have similar setups. It sounds messy but it's the most efficient jvm platform dev environment I've worked with. I have the identical setup on my mac laptop and linux servers. I'm not sure how the equivalent would work on Windows though. Rgds, Adrian. On Tue, Mar 10, 2009 at 2:40 PM, Javier wrote: > > Thank you for your response. I'm actually using BeanShell for doing > most of this stuff, as it provides reloadClasses(), wich allows a very > fast reloading of every change (anyway, changes in code which is > actually in use are not propagated, but this is an expected issue). > I'll have a glance to the link you provide. > > One more question: is there a way to call a function similar to > reloadClasses in Clojure? If so, it would be my solution. > > > > > On 10 mar, 11:44, Chas Emerick wrote: >> In general, no -- in a typical project setup, any changes to Java code >> precipitate a rebuild and a restart of your application. >> >> There are plenty of ways to avoid this, but currently, they're only >> used in the major IDEs when debugging (e.g. while debugging an >> application, you can usually make various changes to java code, and >> then load those changes into the running application without >> restarting). This is accomplished by bootstrapping the application >> with a custom classloader (or, more likely, many, many classloaders) >> that allows the IDE to replace bytecode at various levels of >> granularity (class, method, etc). In my experience, eclipse is much >> better at this than netbeans, although the latter should approach >> parity with the 6.7 release if I've read the tea leaves properly. >> >> I know of people who have used JavaRebel >> (http://www.zeroturnaround.com/javarebel/ >> ) to implement this kind of hot code reloading in a production >> environment; apparently, it works quite well. You could try using it >> yourself -- it appears to be free for personal and open-source >> development. How it will interact with clojure and the details of its >> classloader-related implementation is anyone's guess. >> >> - Chas >> >> On Mar 10, 2009, at 2:01 AM, Javier wrote: >> >> >> >> > Hello, I'd like to thank you for providing us Clojure. This is >> > fantastic. >> >> > My background in Lisp if for several years now, just for fun, and >> > using >> > Common Lisp, mainly. >> > I have some programs in Java, and would like to use Clojure to >> > test/develop them. My question is: >> >> > Is it easy to test/load Java code in real time in Clojure while >> > developing it? For example, I have a bunch of classes I want to >> > continue >> > developing in Java, while other parts are made in Clojure. Is it >> > possible to test my modifications of the Java part in Clojure in >> > real time? >> >> > I'm using Netbeans. > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: VimClojure 2
I think the " could be a problem in generating your path in .vimrc. Try... let vimclojure#NailgunClient='/your_path/vimclojure-2.0.0/ng' and don't forget also for .vimrc let g:clj_want_gorilla = 1 Rgds, Adrian. On Fri, Mar 13, 2009 at 2:09 AM, Yasuto TAKENAKA wrote: > > In my environment, same error occurs ... although I have erased > Gorilla and previous vimclojure packages. I install it using my > installer script. If wrong, let me know. > -- > #!/bin/sh > # installer.sh - a simple vimclojure installer. > # Please rewrite CLOJURE, CLOJURECONTRIB and VIMCLOJUREHOME. > # The example is that CLOJURE is ~/opt/clojure/clojure.jar, > # that CLOJURECONTRIB is ~/opt/clojure-contrib/clojure-contrib.jar > # and that VIMCLOJUREHOME is ~/opt/vimclojure . > > CLOJURE="${HOME}/opt/clojure/clojure.jar" > CLOJURECONTRIB="${HOME}/opt/clojure-contrib/clojure-contrib.jar" > NAILGUNCLIENT="ng" > VIMCLOJUREHOME="${HOME}/opt/vimclojure" > > cp -r {autoload,doc,ftdetect,ftplugin,indent,syntax} ${HOME}/.vim > ant -Dnailgun-client=${NAILGUNCLIENT} -Dclojure.jar=${CLOJURE} - > Dclojure-contrib.jar=${CLOJURE-CONTRIB} > > # ./ngserver is a shell script for clojure server of vimclojure. > > echo '#!/bin/sh' > ngserver > echo java -cp ${CLOJURE}:${CLOJURECONTRIB}:${VIMCLOJUREHOME}/ > vimclojure.jar com.martiansoftware.nailgun.NGServer 127.0.0.1 >> > ngserver > chmod 755 ngserver > > # echo let vimclojure#NailgunClient=\"${VIMCLOJUREHOME}/ng\">> $ > {HOME}/.vimrc > -- > > On 3月13日, 午前5:30, Mark Volkmann wrote: >> On Mar 12, 3:21 pm, Mark Volkmann wrote: >> >> > The README.txt file doesn't describe the files that need to be copied >> > to ~/.vim. I'm getting errors starting Vim now. I suspect it's because >> > I haven't copied all the necessary files to my ~/.vim directory. Which >> > files do I need to copy? >> >> Here is the copy command I used: >> >> cp -r {autoload,bin,doc,ftdetect,ftplugin,indent,syntax} ~/.vim >> >> Here are the errors I'm getting. >> >> Error detected while processing function >> vimclojure#ExecuteNailWithInput: >> line 23: >> E605: Exception not caught: Couldn't execute Nail! ng >> de.kotka.vimclojure.nails.N >> amespaceOfFile > v920635/0 >> Error detected while processing /Users/Mark/.vim/ftplugin/clojure.vim: >> line 131: >> E171: Missing :endif >> Error detected while processing function 9_LoadFTPlugin: >> line 17: >> E170: Missing :endfor >> >> I do have nailgun running. The window it's in says "NGServer started >> on 127.0.0.1, port 2113." > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: VimClojure 2
Hi Mark, I'm also running on OSX 10.5. I couldn't get it working with the vim that comes with leopard - vim version 7.0.x I first downloaded and tried MacVim 7.2 from http://code.google.com/p/macvim/ but I couldn't unpack the .tbz files. I then tried the Vim.app 7.2 from http://sourceforge.net/projects/macosxvim/ and this works fantastically. I'm not sure what the difference is between this and MacVim - there's not much documentation. The setup was easy - I just installed from the .dmg and created a .gvimrc in addition to my .vimrc and .vim directory as before. The only problem I had was in getting vim to see the ng client but that was solved as per my previous post. Hope that helps. On Fri, Mar 13, 2009 at 1:51 PM, Mark Volkmann wrote: > > On Fri, Mar 13, 2009 at 2:50 AM, Adrian Cuthbertson > wrote: >> >> I think the " could be a problem in generating your path in .vimrc. Try... >> let vimclojure#NailgunClient='/your_path/vimclojure-2.0.0/ng' >> >> and don't forget also for .vimrc >> let g:clj_want_gorilla = 1 > > I fixed the "let vimclojure" line to be just like yours and I already > had the clj_want_gorilla line, but I'm getting the same error. Here > are all the lines I added to my .vimrc. > > let g:clj_want_gorilla=1 > let g:clj_highlight_builtins=1 > let g:clj_highlight_contrib=1 > let g:clj_paren_rainbow=1 > let > vimclojure#NailgunClient='/Users/Mark/Documents/Programming/Languages/Clojure/vimclojure-2.0.0/ng' > > BTW, I'm running on a Mac with OS X 10.5. > >> On Fri, Mar 13, 2009 at 2:09 AM, Yasuto TAKENAKA >> wrote: >>> >>> In my environment, same error occurs ... although I have erased >>> Gorilla and previous vimclojure packages. I install it using my >>> installer script. If wrong, let me know. >>> -- >>> #!/bin/sh >>> # installer.sh - a simple vimclojure installer. >>> # Please rewrite CLOJURE, CLOJURECONTRIB and VIMCLOJUREHOME. >>> # The example is that CLOJURE is ~/opt/clojure/clojure.jar, >>> # that CLOJURECONTRIB is ~/opt/clojure-contrib/clojure-contrib.jar >>> # and that VIMCLOJUREHOME is ~/opt/vimclojure . >>> >>> CLOJURE="${HOME}/opt/clojure/clojure.jar" >>> CLOJURECONTRIB="${HOME}/opt/clojure-contrib/clojure-contrib.jar" >>> NAILGUNCLIENT="ng" >>> VIMCLOJUREHOME="${HOME}/opt/vimclojure" >>> >>> cp -r {autoload,doc,ftdetect,ftplugin,indent,syntax} ${HOME}/.vim >>> ant -Dnailgun-client=${NAILGUNCLIENT} -Dclojure.jar=${CLOJURE} - >>> Dclojure-contrib.jar=${CLOJURE-CONTRIB} >>> >>> # ./ngserver is a shell script for clojure server of vimclojure. >>> >>> echo '#!/bin/sh' > ngserver >>> echo java -cp ${CLOJURE}:${CLOJURECONTRIB}:${VIMCLOJUREHOME}/ >>> vimclojure.jar com.martiansoftware.nailgun.NGServer 127.0.0.1 >> >>> ngserver >>> chmod 755 ngserver >>> >>> # echo let vimclojure#NailgunClient=\"${VIMCLOJUREHOME}/ng\">> $ >>> {HOME}/.vimrc >>> -- >>> >>> On 3月13日, 午前5:30, Mark Volkmann wrote: >>>> On Mar 12, 3:21 pm, Mark Volkmann wrote: >>>> >>>> > The README.txt file doesn't describe the files that need to be copied >>>> > to ~/.vim. I'm getting errors starting Vim now. I suspect it's because >>>> > I haven't copied all the necessary files to my ~/.vim directory. Which >>>> > files do I need to copy? >>>> >>>> Here is the copy command I used: >>>> >>>> cp -r {autoload,bin,doc,ftdetect,ftplugin,indent,syntax} ~/.vim >>>> >>>> Here are the errors I'm getting. >>>> >>>> Error detected while processing function >>>> vimclojure#ExecuteNailWithInput: >>>> line 23: >>>> E605: Exception not caught: Couldn't execute Nail! ng >>>> de.kotka.vimclojure.nails.N >>>> amespaceOfFile >>> v920635/0 >>>> Error detected while processing /Users/Mark/.vim/ftplugin/clojure.vim: >>>> line 131: >>>> E171: Missing :endif >>>> Error detected while processing function 9_LoadFTPlugin: >>>> line 17: >>>> E170: Missing :endfor >>>> >>>> I do have nailgun running. The window it's in says "NGServer started >>>> on 127.0.0.1, port 2113." >>> >>> > >>> >> >> > >> > > > > -- > 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: March 20th 2009 Rich Hickey Appreciation Day!
I wrote my first program in Fortran in 1975. Since then I've worked in Assember, Jcl, Rexx, Lisp 370, C, C++, VB (the low-light of my career), and a host of scripting/macro tools. I started with Java in 1998 and my own business in 2002 (web apps and backends with Java/Jsp/Js). I became disillusioned with Java in 2006 and embarked on trying to find a new platform that would take my business into the future with dramatically improved development productivites. I explored and tried D, perl, python, C again (a back to basics moment), Ruby, SISC, CL, Haskell, CAML, Erlang. None of these met my (admittedly lofty) ambitions. The I found Scala. Mabye this would be it. It would integrate with my Java legacy stuff, had good functional and looked like the NBT. After 6 month's of learning/dabbling I started using it in business. Then a reasonably complex application, a real deadline and Scala's type system made me want to throw it all out and go back to C again. And then I found Clojure. That was 6 months ago. My quest for the grail has been fulfilled. Thank you, thank you, Rich. And the great community. However long I've got left as a programmer, I can now just get on and do those many, many things I've always wanted to do but been perpetually frustrated by the (in-)capabilities of the language I've been working in. At last. Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: LZW compression
There's apache commons; http://commons.apache.org/compress/ and Java also has a built-in zip/gzip library - see java.util.zip in the Java docs. Adrian. On Mon, Mar 30, 2009 at 10:19 PM, Sean wrote: > > Hi, > Does anyone know of a good compression library in java or clojure? A > quick google didn't reveal much useful. I need an LZW filter for an > app I'm working on. > > Sean > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: basic question on structuring refs
I came across a thread from Jul '08 which seems to be the definitive on handling side-effects within transactions - http://groups.google.co.za/group/clojure/browse_thread/thread/d645d77a8b51f01/667e833c1ea381d7 Adrian. On Wed, Apr 1, 2009 at 9:24 AM, Timothy Pratley wrote: > > Hi Korny, > > > That is a very interesting question to me, specifically this part: > >> how do I stop parallel >> changes to two unrelated structures in the world from causing transaction >> retries? > > Actually I don't think you can ever rule out retries if you are using > a ref (or atom) and more than one thread to access it. For me this > poses a problem because my 'transaction' has side-effects. I have a > function which modifies the state, but it also reports the > modification (reporting should only happen once). I can think of two > solutions: > (1) Use an agent instead - changes are coordinated on a queue and the > modification is only run once. > (2) Use watchers to do the reporting. > Neither of these are particularly appealing to me as (1) is > asynchronous and (2) appears to slightly complicate things. In my case > it seems a regular old lock would be sufficient? > > There is a discussion on STM generally: > http://groups.google.com/group/clojure/browse_thread/thread/822e21c9a36c5a0f/c81692a8dc1bd198 > But I'm still a little unsure what I should do in this situation. > > > 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: Questions about Clojure and Common Lisp
I have used Java and Jsp for many years as the platform for my business offerings. All new development is now being done in Clojure - I am comfortable (nay, delighted) with it's stability and viability. On Wed, Apr 1, 2009 at 6:12 PM, Jon Harrop wrote: > > On Wednesday 01 April 2009 16:51:49 Joshua Fox wrote: >> > 3. Clojure can use Java libraries. Common Lisp can use C/C++ >> > libraries. Is it possible to say Clojure has strong points to Common >> > Lisp in the power of libraries? >> >> Accessing Java from Clojure is easier & more transparent than accessing C >> from Common Lisp. > > And safe! You get an easily-debuggable exception instead of machine-level > errors and silent corruption. > > And more efficient because your data is not crossing GC boundaries and > possibly not even changing representation. > > -- > Dr Jon Harrop, Flying Frog Consultancy Ltd. > http://www.ffconsultancy.com/?e > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Keeping a ref and a DB in sync
Perhaps you could do the db update as an agent action and then the ref update within the agent action if it is successful - see http://groups.google.co.za/group/clojure/browse_thread/thread/d645d77a8b51f01/667e833c1ea381d7 Regards, Adrian. On Fri, Apr 3, 2009 at 11:02 AM, Brian Carper wrote: > > Is there a safe way to keep the data in a Clojure ref and the data in > a table in an external (e.g. mysql) database in sync, given concurrent > creates/updates/deletes from within Clojure? > > I can't do a DB update from within a dosync because of retries. If I > send-off an agent for the DB update from within a dosync, it won't > happen until after the dosync is done, and then if the DB update > throws an exception, it'll be too late to rollback the ref and they'll > be out of sync. If I do the DB update and ref update separately, > there's the potential for race conditions if things happen in between. > > Is manual locking the only way? > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: introspect namespace ?
Nice case of clojure reductio :-) On Mon, Apr 6, 2009 at 7:51 AM, Stephen C. Gilardi wrote: > (str *ns*) > > On Apr 6, 2009, at 1:27 AM, Kevin Downey wrote: > >> (.toString *ns*) >> >> On Sun, Apr 5, 2009 at 12:39 PM, Stephen C. Gilardi >> wrote: >>> >>> >>> (-> *ns* ns-name name) > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Enlive questions
I'm just starting out on Enlive - any examples added would be welcome. I'll also accumulate some documentation as I go through the learning curve. Thanks, Adrian. On Wed, Apr 15, 2009 at 5:05 AM, David Nolen wrote: > One early thought, would you like me to extend the number of examples? I'm > really getting into the nitty gritty of what's possible with Enlive and it > would be nice to have a relatively informative list of possibilities > distributed with the library vs. the single example that's in there right > now ;) > On Tue, Apr 14, 2009 at 1:31 PM, Christophe Grand > wrote: >> >> I pushed do->, attr=, attr? and snippets values as source to github >> http://github.com/cgrand/enlive/commits/right >> >> Christophe Grand a écrit : >> > Hello David, >> > >> > David Nolen a écrit : >> > >> >> Considering the above, I'm left wondering if it's possible to further >> >> eliminate these redundancies and make templates more reusable. I'm not >> >> sure if this is what you had in mind for Enlive, but allowing >> >> templates to be created without references to files would make it >> >> possible to build very, very composable interfaces. >> >> Of course it's quite possible that you can already do this with Enlive >> >> and I'm just unclear about how to accomplish it. >> >> >> > >> > I'm sorry for the lack of documentation. >> > >> > The "source" of a template/snippet can either be: >> > - a string (a resource path resolved by the classloader) >> > - a File, URI or URL, >> > - a map (a "literal" xml/html tree). >> > >> > A template is a function that returns a seq of strings. (It's the end of >> > the "pipeline".) >> > >> > A snippet is a function that now (in the "new" enlive) returns a seq of >> > nodes. (I suppose I should add "seq of nodes" as a valid source type.) >> > Snippets are valid values on the right-hand side of rules. The only >> > difference between templates and snippets is that templates serialize >> > their return value. >> > >> > >> >> This is great. I had thought that supporting some kind of partial >> >> template thing would be interesting, but that's actually just my poor >> >> logic at work ;) >> >> >> >> It seems like with the new version of Enlive I could do something like >> >> this: >> >> >> >> (deftemplate pageA-template path >> >> [] >> >> [[:div (attr? :tiptree:replace)]] (fn [xml-node] >> >> >> >> (find-the-widget-html-file-that-corresponds-to-a-certain-attr-and-return-as-result))) >> >> >> >> (deftemplate pageB-template path >> >> [] >> >> [[:div (attr? :tiptree:replace)]] (fn [xml-node] >> >> >> >> (find-the-widget-html-file-that-corresponds-to-a-certain-attr-and-return-as-result))) >> >> >> >> (def pageAPartial (pageA-template)) >> >> (def pageBPartial (pageB-template)) >> >> >> >> ;; the following would work only if templates allowed passing html as >> >> strings and not just as files >> >> >> >> (deftemplate widgetsPageA pageAPartial >> >> [map] >> >> [[:div (attr? :tiptree:widget)]] (fn [xml] >> >> (use-xml-attr-and-map-to-apply-and-return-a-snippet)) >> >> >> >> (deftemplate widgetsPageB pageBPartial >> >> [map] >> >> [[:div (attr? :tiptree:widget)]] (fn [xml] >> >> (use-xml-attr-and-map-to-apply-and-return-a-snippet)) >> >> >> >> (def pageA (widgetsPageA someMap)) >> >> (def pageB (widgetsPageA someMap)) >> >> >> >> >> > >> > I suppose you really want to break the computation in two and not write: >> > (deftemplate pageA-template path >> > [map] >> > [[:div (attr? :tiptree:replace)]] (fn [xml-node] >> > >> > (find-the-widget-html-file-that-corresponds-to-a-certain-attr-and-return-as-result)) >> > [[:div (attr? :tiptree:widget)]] (fn [xml] >> > (use-xml-attr-and-map-to-apply-and-return-a-snippet))) >> > >> > or: >> > (deftemplate pageA-template path >> > [map] >> > [[:div (attr? :tiptree:replace)]] >> > (do-> >> > (fn [xml-node] >> > >> > (find-the-widget-html-file-that-corresponds-to-a-certain-attr-and-return-as-result)) >> > (fn [xml] (use-xml-attr-and-map-to-apply-and-return-a-snippet >> > >> > (well, it would work if do-> has been ported to the new enlive) >> > >> > Keeping in mind the difference between a snippet and a template, you >> > will be able to do what you describe with the new enlive once I >> > implement 'attr? and add support for seq of nodes as a valid source >> > type. >> > >> > >> > hth, >> > >> > Christophe >> > >> > > >> > >> > >> >> >> -- >> Professional: http://cgrand.net/ (fr) >> On Clojure: http://clj-me.blogspot.com/ (en) >> >> >> >> > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Oracle and Clojure
There are some precedents - the acquisition of SleepyCat (berkeley db, et al) - still readily available under GPL compatible licenses. On Tue, Apr 21, 2009 at 7:47 AM, AlamedaMike wrote: > >>> I can see a lot of technologies that drive the open source world, and this >>> group, being compromised > > Nothing's going to happen, for the simple reason that the cost to > Oracle's reputation would far outweigh anything they might gain from > charging for open-source products. The ultimate effect would be to > simply route around any attempt to close the sources or to restrict > changes. > > Oracle didn't become the world's third largest software company by > being stupid. > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Enlive tutorial
I've uploaded a file http://groups.google.co.za/group/clojure/web/enlive-tut1.txt?hl=en which is a basic tutorial on getting started with Enlive (the html transformation library). Christophe, this is intended as a contribution to the Enlive project, so you're welcome to use it as part of the Enlive documentation, on the wiki, etc. Also, please feel free to enhance it and make any corrections. Enlive is an outstanding tool for web development. Thanks Christophe for your initiatives. Regards, Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Enlive tutorial
Nice enhancement! On Thu, Apr 23, 2009 at 6:43 PM, Christophe Grand wrote: > > I updated the tutorial to reflect a new behavior: enlive now precomputes > html output for untouched or partly untouched elements. > > ((template (java.io.StringReader. "untouched element class=foo>won't last") [] > [[:div last-child]] (content "new content"))) > > used to return: > ("<" "html" ">" "<" "body" ">" "<" "div" ">" "untouched element" " "div" ">" "<" "div" " " "class" "=\"" "foo" "\"" ">" "new content" " "div" ">" "" "") > > but now returns: > ("" "" "untouched element" "" > "new content" "" "" "") > > > Adrian Cuthbertson a écrit : >> I've uploaded a file >> http://groups.google.co.za/group/clojure/web/enlive-tut1.txt?hl=en >> which is a basic tutorial on getting started with Enlive (the html >> transformation library). >> >> Christophe, this is intended as a contribution to the Enlive project, >> so you're welcome to use it as part of the Enlive documentation, on >> the wiki, etc. Also, please feel free to enhance it and make any >> corrections. >> >> Enlive is an outstanding tool for web development. Thanks Christophe >> for your initiatives. >> >> Regards, Adrian. >> >> > >> >> > > > -- > Professional: http://cgrand.net/ (fr) > On Clojure: http://clj-me.blogspot.com/ (en) > > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to have one lib with source in multiple files
billh04, have a look at the compojure project (http://github.com/weavejester/compojure/tree/master). In that James uses an "immigrate" function which may be useful to you. Also the structure used is a good example of a reasonably large, quite complex project. Hth, Adrian. On Fri, Apr 24, 2009 at 7:23 AM, Laurent PETIT wrote: > > Hi, > > Please note that a convention (but it's really just one convention) > could also be to name file for partB : place_partB.clj (or even > place_part_b.clj since in clojure camel case notation is not the > preferred way to write things, hyphens and lower cases are -> but > hyphens must be replaces by underscores in package/namespace names, > and in file names). > > Your solution is acceptable I think (having the load at the end of the > root file). > You could also consider this one: > > place.clj === > (ns whale.achi.model.place > (:load "place/partA") > (:load "place/partB")) > == > > place/partA.clj === > (in-ns 'whale.achi.model.place) > partA > == > > place/partB.clj === > (in-ns 'whale.achi.model.place) > partB > == > > Or, to write it like it is done for clojure.core: > > place.clj === > (ns whale.achi.model.place > (:load "place_part_a") > (:load "place_part_b")) > == > > place_part_a.clj === > (in-ns 'whale.achi.model.place) > partA > == > > place_part_b.clj === > (in-ns 'whale.achi.model.place) > partB > == > > > HTH, > > -- > Laurent > > > 2009/4/24 billh04 : >> >> I don't think I explained my need clearly. >> >> I try to rephrase it. Suppose I have a source file named place.clj in >> a directory named whale/achi/model like the following: >> >> place.clj >> (ns whale.achi.model.place) >> partA >> partB >> == >> >> What I want to do is to keep the same namespace but break it into two >> files named place.clj as above and placeEvaluation.clj in a >> subdirectory place: >> >> place.clj === >> (ns whale.achi.model.place >> (:load "place/placeEvaluation")) >> partA >> == >> >> >> placeEvaluation.clj === >> partB >> == >> >> When, I do this, I get the error message: >> >> java.lang.Exception: Unable to resolve symbol: -boardPlaces- in this >> context (placeEvaluation.clj:19) >> >> since -boardPlaces- is defined in partA, but has not been loaded yet >> (I suspect). >> >> I believe the following will work since partA is loaded before partB: >> >> place.clj === >> (ns whale.achi.model.place) >> partA >> (load "place/placeEvaluation") >> == >> >> >> placeEvaluation.clj === >> partB >> == >> >> What I am seeking is how to split a file for one namespace into >> multiple files with the same namespace. >> >> Also, any source file that wants to use the namespace >> 'whale.achi.model.place would need only 'use 'whale.achi.model.place >> and would not have to worrry about placeEvaluation but get that loaded >> for free. >> >> On Apr 23, 9:29 pm, Drew Raines wrote: >>> billh04 wrote: >>> > Right now I have the two files "whale.achi.model.place.clj" and >>> > "whale.achi.model.placeEvaluation.clj" that make up one name space >>> > "whale.achi.model.place". >>> > The first file is the "root" of the namespace. >>> >>> I think you're confused with how Clojure looks for packages in the >>> filesystem. Perhaps you want: >>> >>> $ find whale >>> whale/achi/model/place.clj >>> whale/achi/model/place/evaluation.clj >>> $ head -2 whale/achi/model/place.clj >>> (ns whale.achi.model.place >>> (:require [whale.achi.model.place.evaluation :as eval])) >>> $ head -1 whale/achi/model/place/evaluation.clj >>> (ns whale.achi.model.place.evaluation) >>> >>> -Drew >> > >> > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: more vimclojure
Likewise a real fan! In the absence of an issue tracker at this time, could I mention the following relating to indenting; (defn xxx "Some stuff... (defmacro xxx "Some stuff... (defroutes xxx "Some stuf... That is, the indenting starts under the argument for "non-recognised" fn names - which tends to mess up auto alignment (=). Is there an easy way around this or if not could it be changed in vimclojure? Thanks Meikel, great work! Adrian. On Wed, Apr 29, 2009 at 4:42 AM, Johan Berntsson wrote: > > On Apr 29, 11:21 am, tmountain wrote: >> I just wanted to chime in and say I'm also a fan of vimclojure. I find >> it to be one of the more enjoyable dev environments I've worked in and >> the ability to send arbitrary expressions to the REPL is really >> convenient. I have found a few issues with it though, and I'm >> wondering what the appropriate chanel to report them is? > > I've been emailing directly to Meikel, but perhaps a issue tracker of > some kind would be good? It is of course up to Meikel, and VimClojure > is already good enough for me to use for all my Clojure hacking > (including some paid work). > > /Johan > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Help: Java code works, Clojure code doesn't
Perhaps you could try calling your java class directly from the repl... (TutorialConnect1.) That might highlight the problem - your java stack strace might give some clues. It does sound like a classpath problem of some sort. Rgds, Adrian. On Tue, May 5, 2009 at 6:04 PM, Sean Devlin wrote: > > That's a really good point, thanks for mentioning. Unfortunately, > after looking into this, it's not the culprit. The java code's > classpath is a _subset_ of the clojure code's classpath. Also, the > DsrIPassport class doesn't exist. It was depricated years ago... > > The Clojure code appears to be initialized differently from the Java > code. > > I'll try adding a dummy class, see if that works... > > On May 5, 11:41 am, David Chamberlin wrote: >> It sounds like you maybe haven't included all the necessary stuff in >> your classpath. >> >> If you are testing in REPL, then you need to include everything you >> need in the classpath the the invoked JVM, for example: >> >> java -classpath my-jar-file-containing-DsrlPassport.jar;clojure.jar >> clojure.main >> >> On 5 May, 15:54, Sean Devlin wrote: >> >> > Okay, I've got code that works in Java but I can't get working in >> > Clojure. Here's the code in Java >> >> > public class TutorialConnect1 extends Object { >> > JCO.Client mConnection; >> > public TutorialConnect1() { >> > try { >> > // Change the logon information to your own system/user >> > mConnection = JCO.createClient(...); //Connection parameters >> > mConnection.connect(); >> > System.out.println(mConnection.getAttributes()); >> > mConnection.disconnect(); >> > } >> > catch (Exception ex) { >> > ex.printStackTrace(); >> > System.exit(1); >> > } >> > } >> > public static void main (String args[]) { >> > TutorialConnect1 app = new TutorialConnect1(); >> > } >> >> > } >> >> > It simply prints some connection attributes about my system. Here's >> > the same code in Clojure >> >> > (let [sap-con (com.sap.mw.jco.JCO/createClient ... )] ;connection >> > attributes >> > (do >> > (. sap-con connect) >> > (println (. sap-con getAttributes)) >> > (. sap-con disconnect))) >> >> > I can successfully create the connection object in Clojure, but I get >> > an error in the following s-exp >> >> > (. sap-con connect) >> >> > The error I get is : >> >> > #> > writer/DsrIPassport (NO_SOURCE_FILE:0)> >> >> > The SAP library I'm using does rely on some native methods. The only >> > guess I have right now is that the native methods are being linked to >> > properly. >> >> > Can anyone give me a hand? >> >> > Sean > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Writer turned programmer seeks string processing advice
>2. Would it be better (or even possible) to learn about matching and >string processing in general, independent of the programming language? Hi Dirk, it's a pretty advanced topic and quite difficult to get one's head around (at least for me), but monads (both clojure and in general) may be of interest in your quest. Monads are functional techniques which can, among many other things, be used for easily creating recursive descent parsers. There are two excellent clojure tutorials on monads which would be good starting points; http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1 http://intensivesystems.net/tutorials/monads_101.html Also, take a look at the articles in general on clojure.org - there are many features of clojure which support "matching" or "selecting" in it's wider context. Hth, Adrian. On Wed, May 6, 2009 at 9:57 AM, dhs827 wrote: > > Thanks for your suggestion, Stuart, and yes, that's one obvious chice: > the AIML interpreter in question - Program D - is written in Java, so > why not just learn enough Java to fix the stack, and be done? In fact, > this was my first consideration. > > However, that would be myopic. The reason I have this problem is that > the original AIML pattern matching algorithm is not suited for what I > want to do (conversations with lots of state, and lots of references > to past states to compute present and future output), so I changed it, > using the language itself. While it was fun and amazing to learn that > I could do this - from what I've read, this seems like a quite "lispy" > thing to do -, I have reason to suspect that it's very inefficient (I > do about 30-40 recursions and 10 topic/context switches on an average > input, simply because recursion and one contextual extension of the > match path is all I have to work with). So I know that I can't "fake > it" by somewhat modifying an existing program, and I'm up for a lot of > learning. My current questions are: > > 1. What would be a good way to learn about how to do matching and > string processing in Clojure? > 2. Would it be better (or even possible) to learn about matching and > string processing in general, independent of the programming language? > > I know about regex, but that's not enough: I need to learn about > "matching in context", where "context" means "more matching", or even > something like "explicit non-matches" (hope you can divine my meaning > here). > > Dirk > > On 6 Mai, 03:29, Stuart Sierra wrote: >> Hi Dirk, welcome to Clojure! >> >> I don't know much about Scala, but I know that Lisp-like languages >> have long been popular for this sort of language manipulation, so >> Clojure may be a good one to look at. >> >> Some caveats: Clojure does not have a direct equivalent to the pattern/ >> template style of AIML. Clojure also does not support the structural >> pattern-matching style found in some other functional languages like >> Haskell and ML. Multimethods cannot dispatch on composite arguments >> like [* foo *], although this is an open research area. On the other >> hand, Clojure has good support for regular expressions, which might be >> an adequate alternative for text processing. Clojure does not support >> continuations natively, although Clojure code can still be written in >> a continuation-passing style. >> >> And don't forget Java! There are implementations of AIML (and >> doubtless other pattern-matching libraries) in Java that you could use >> from Clojure. >> >> -Stuart Sierra >> >> On May 5, 12:16 pm, dhs827 wrote: >> >> > Hi, >> >> > my name is Dirk Scheuring, I'm a writer based in Cologne, Germany, and >> > I want to write something about AI that can only be expressed by using >> > AI technology and technique. You could say that what I aim for is a >> > chatbot, but it's a bot that works quiet different from the norm; at >> > it's core, there is a functional program, and on the fringe, there's >> > lots of state information. >> >> > I have a working prototype, written in AIML, the language in which the >> > famous Alicebot was written. Most bots written in AIML use a simple >> > stimulus-response conception of dialogue, without using (sequences of) >> > state, self-reflection, or other advanced concepts. So some people who >> > have only cursory knowledge of this language think that it's too >> > simple to be doing anything with that might be computationally >> > interesting. I know this to be false. >> >> > AIML is sort of a micro-version of a Lisp, with String being the only >> > type, and recursion over everything (powerful and dangerous). You can >> > write serious functions with it [1], but you have to abuse it. And I >> > heavily abused the language to make it do what I want. I managed to >> > build a prototype that does something interesting, but only does it >> > for like ten conversational strokes, because then the interpreter's >> > stack overflows, causing an infinite loop. >> >> > I need to implement my ideas in a d
Re: Feedback on new persistentmatrix datatype
If you haven't seen it yet, the set module (clojure.set) provides a basic implementation of set relational algebra. May be useful for this work? See clojure.org data structures and the source for clojure/set.clj in the clojure source. Rgds, Adrian. On Wed, May 6, 2009 at 7:05 PM, Anand Patil wrote: > On Sat, May 2, 2009 at 11:19 PM, aperotte wrote: >> >> Hello everyone, >> >> I just uploaded some of my work on a new datatype for clojure to a git >> repository. >> >> http://github.com/aperotte/persistentmatrix >> >> A bit of the rationale and motivation for the datatype is described on >> the github page. I basically wanted to create a datastructure for >> manipulating large amounts of data efficiently and in a human friendly >> way in clojure. >> >> Its main features are: >> >> 1. Immutability >> 2. Primitive Support >> 3. N-Dimensional – Arbitrary number and size of dimensions (ie. >> ability to create a 4×3×5x6 datastructure) >> 4. N-Dimensional units (ie. ability to create a 10×10 matrix with >> 2×1 units to represent complex numbers) >> 5. Fast submatrix views via structural sharing (ie. constant time >> slicing, transposing, and other data manipulations) >> 6. Maintenance of both deep and superficial dimensionality (ie. >> slicing a 4×3×5x6 along the 3rd dimension will yield a datastructure >> with a superficial dimensionality of 3 and a deep dimensionality of 4) >> 7. Axis and element labeling and label indexing (ie. ability to >> label axes and elements of an axis with strings or any arbitrary >> object) >> 8. Implementing many of the clojure interfaces and thereby >> automatically inheriting much of the functionality of the standard >> library for data structures. >> >> I would welcome any feedback. Also, if anyone is interested in >> working together to accelerate its development, that would be welcome >> too! > > Great work! I'm glad to see some numerical advances in Clojure. > I've got a couple of suggestions: first, you might want to follow numpy and > call n-dimensional arrays 'arrays', and reserve 'matrix' for 2d arrays. Or > not... > Second, immutability is definitely the right default, but it would be nice > to be able to create nonstandard arrays from Clojure somehow. For example, > say I wanted to compute the matrix (f (- x y)) over the Cartesian product of > vectors x and y. > Anand > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: AIML pattern matcher design
I found that after a couple of months of working with Clojure, my whole perspective on thinking about the problem domain and its possible abstractions changed really significantly. An approach that might benefit you is to spend a while dabbling with some repl explorations of some of the key Clojure features. I would start with really getting to understand maps, vectors, map and reduce, sequences and lazy-seq. A good grasp of multi-methods would be helpful. Also check out cond and condp. I also found an understanding of using first order functions and closures invaluable (e.g storing a function closed over some arguments in a map entry for dynamic program composition). There are others, but those are good to start with. In the beginning avoid recur (leads to too much imperative thinking) and macros (I found for most things I thought a macro would be needed that they could be done easily in basic clojure). After the basics check out the clojure.core source and the source for the contrib libraries (xml, zip, etc) that you may be using. The source is a great learning resource. Also Mark Volkmann's guide (http://java.ociweb.com/mark/clojure/article.html), Stuart Halloway's book and clojure.org are great resources for getting into Clojure. Rgds, Adrian. On Fri, May 8, 2009 at 7:23 PM, Luke VanderHart wrote: > >> ; First thing to learn is XML parsing with Clojure. > > This is basically done. Use the xml library in core if you just need > to load XML into a map data structure. Use the zip library if you need > to navigate it. Use the xml library in contrib if you need to do xpath- > style navigation. > > For the rest of it... it looks very well thought out. I'm not familiar > enough with the problem domain to comment specifically, but obviously > you're putting a lot of thought into it, so I'm pretty sure you won't > have any problems. > > -Luke > > On May 8, 12:50 pm, dhs827 wrote: >> I'm stealing knowledge left and right (just ask me :-) to design me an >> AIML pattern matcher. I've compiled a draft list of objects and >> behaviors, which I would like to see reviewed for plausibility: >> >> startup >> - opens configuration file (e.g. startup.xml) >> - passes configuration file to bot-loader object >> bot-loader >> - loads general input substitutions (spelling, person) >> - loads sentence splitters (.;!?) >> - looks for enabled bot, takes first one it finds >> - reads bot-id; uses it as key (for saving/loading variables and >> chatlogs) >> - loads bot properties (global constants, e.g. name) >> - passes control to aiml-loader object >> aiml-loader >> - loads list of AIML files to load, and for each file >> - opens file >> - reads AIML categories (XML) one by one as they appear in >> the file >> - parses and stores the content of the match path >> (e.g."BOTID * >> INPUTPATTERN * CONTEXT1 * CONTEXT2 *") >> - when it reaches the end of the category - the >> template, or leaf >> of this branch of the tree >> - calls a method to store the elements of >> the match path, together >> with the template, in the >> pattern-matcher-tree >> >> ; First thing to learn is XML parsing with Clojure. >> >> ; Though it is probably the easiest thing to do, it is not necessary >> for the templates to be stored along with the paths in the tree. They >> might as well be left on disc or in a database. >> >> ; A function like parser/scan must advance the parse to the next part >> of the document (element - element content - processing >> instruction...) and tokenize it. I can then use case/switch/if (must >> look at what Clojure offers) to make decisions/set variables/call >> methods. >> >> ; The whole path, with all components, gets created at load time. The >> loader combines all elements of the path (e.g. INPUTPATTERN * CONTEXT1 >> * CONTEXT2 *) into one string, seperating the components using special >> context-id strings (e.g. , , ) >> >> ; The idea of the AIML graphmaster is: take this string, seperate it >> into words, then store these words as nodes in a tree. >> >> ; A variation of this idea: instead of keying the nodes by their >> values, key them first by context, then by value. >> >> ; Now that the bot is up and running, the user types something into >> the input box and hits Enter. The >> >> pre-processor >> - protects sentences >> - blocks common attack vectors, e.g. code injection, flooding >> - eliminates common spelling mistakes >> - for each loaded substitution >> - finds and replaces it in the input string >> - alternatively, uses a tree to search for them >> - removes redundant whitespace >> - splits input into sentences (everything that follows is for each >> sentence) >> pattern-matcher >> - combines INPUTPATTERN * CONTEXT1
Re: Launching apps
For production server systems running under Linux, I've used apache commons daemon to get java apps launched, for example under root to get port 80 and then su'd to run under the app (non-privileged) userid. The advantage is these can be automatically restarted when the server reboots, or services are restarted by operations, etc. Check Google for "jsvc" or "commons daemon" for details. I haven't yet used this for Clojure apps yet but intend to when deploying them for server production. Should be easy to do, but I'll post on that when I've tried it out. Regards, Adrian. On Sat, May 9, 2009 at 1:12 AM, André Thieme wrote: > > On 9 Mai, 00:30, Chris Dean wrote: >> How do folks launch their apps? >> >> For building (and maybe deploying) it seems that most people use the >> Java tools (ant, maven, ivy) or have a 10 line shell script. For pure >> Clojure code you don't even necessarily have to have a build step. >> >> But how do you launch your code in a production style setting? > > Depending on what kind of app it is. If it is a desktop application > then a .jar file that can be doubleclicked to run sounds like the > right thing. An alternative would be applets or Webstart. > > For server apps it could be a launch script. > The launch script could be run in a screen. > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: String.getBytes does not translate to byte[]?
Using a java nio ByteBuffer to simulate what you're doing, the following works ok for me; (defmulti t-str class) (defmethod t-str String [s] (java.nio.ByteBuffer/wrap (.getBytes s "us-ascii"))) (t-str "abcde") # (defmethod t-str String [s] (java.nio.ByteBuffer/wrap (.getBytes s "utf-8"))) (t-str "abcde") # Maybe there's something about the particular [ s ] object that you're passing in? Rgds, Adrian. On Tue, May 12, 2009 at 8:45 PM, tsuraan wrote: > > I'm trying to encode a java string into utf-8 for encapsulation within > an OtpErlangBinary > (http://erlang.org/doc/apps/jinterface/java/com/ericsson/otp/erlang/OtpErlangBinary.html). > When I try to construct an OtpErlangBinary from the results of > String.getBytes(encoding), I get bad data. A string (pure ascii) with > 20 characters becomes a 47-byte OtpErlangBinary, and none of the bytes > in that binary seem to correspond to the bytes of the string. The > simple function that I have looks like this: > > (defmethod to-otp String [ s ] > (new OtpErlangBinary (.getBytes s "utf-8"))) > > And the OtpErlangBinary gets 47 bytes of data for a 20 byte string. > However, if I change that code to read: > > (defmethod to-otp String [ s ] > (new OtpErlangBinary (.getBytes (str s) "utf-8"))) > > (notice the (str s)), the code works. It seems really strange to me > that this should happen, but I don't know clojure well enough to > determine what's going on under the hood. Is there some way to dump > the java code equivalent of those two functions, so I can compare > them? I've tried making a minimal test case for converting strings > into OtpErlangBinaries, but I can't get this bug to manifest in any > circumstances other than this one program. > > Any tips for debugging would be much appreciated. I'm running clojure > 1.0.0, with java 1.6.0, and erlang jinterface 1.4. > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: String.getBytes does not translate to byte[]?
Well, under the covers the str function applies the java "toString" method to any passed in object and hence the result could for some reason be different to the original String object passed in. I think this could occur if the object subclasses String, but has a different representation (i.e a different toString method). Are you able to post what s contains when this happens? You could try printing s in your calling function and then also in the defmethod, e.g; (defmethod t-str String [s] (prn "cls:" (class s) "s:" s "chars:" (vec s Maybe that'll shed some light? On Wed, May 13, 2009 at 4:59 AM, tsuraan wrote: > >> Maybe there's something about the particular [ s ] object that you're >> passing in? > > I believe that you're right; in general, the getBytes seems to work. > It is just in this one freakish case that it doesn't, but I have no > idea how to tell what's special about my string. I'm not exactly > proficient in Java, and I'm a complete clojure newbie, so I really > have no idea how to proceed with debugging this. > > Under what circumstances would (str s) give something different from > s, when (.getClass s) gives java.lang.String? > > Also, sorry for the horrible subject line; that was my initial guess, > and I had a big email written up about it, but then I started testing > my assumptions and they were all garbage. I rewrote the email, but > forgot about the subject... > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Speed up network transfers?
> But it turns out that this is rather slow. What would be some methods > to speed this up? You could also wrap your input and output stream's with java.util.zip.GZIPInputStream and GZIPOutputStream to compress/decompress the data either side. They allow you to specify buffer sizes, so you could experiment to find optimum buffer sizes. Check out the java.util.zip package in the javadocs. Rgds, Adrian. On Fri, May 15, 2009 at 5:10 PM, Christopher Wilson wrote: > > Hi there, > > I'm working on a project that involves transferring large files over > the network (100+MB) and wondering what would work better. I'm newer > to Java than I am to lisp, so I've just grabbed the most obvious > things from the API that I thought could possibly work: > > (ns misc-ports > (:import (java.io BufferedReader InputStreamReader BufferedOutputStream > PrintWriter FileInputStream BufferedOutputStream > FileOutputStream) > (java.net Socket ServerSocket))) > > (defn net-to-file > "Listen on a port, when accepted dump data to named incoming file." > [port filename] > (with-open [sock (.accept (ServerSocket. port)) > ins (BufferedReader. (InputStreamReader. (.getInputStream sock))) > outf (FileOutputStream. filename)] > (loop [c (.read ins)] > (when-not (== -1 c) > (.write outf c) > (recur (.read ins)) > > (defn file-to-net > "Take the name of a file and a waiting ip and port, send named file > on socket." > [filename ipaddr port] > (with-open [sock (Socket. ipaddr port) > outs (BufferedOutputStream. (.getOutputStream sock)) > ins (FileInputStream. filename)] > (loop [c (.read ins)] > (when-not (== -1 c) > (.write outs c) > (recur (.read ins)) > > But it turns out that this is rather slow. What would be some methods > to speed this up? > > Thanks! > > -- > Chris > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Override the + operator for a 'struct'
>Yes, the general consensus is that basic math needs to be as fast as >possible, even at the expense of some flexibility. It's worth noting here that one can also use binding to override other than arithmetic core functions; (defn ustr [s] (binding [clojure.core/str (fn [x] (.toUpperCase x))] (str s))) user=> (ustr "aaa") "AAA" As expected, that doesn't work with +; (defn xplus [a b] (binding [clojure.core/+ (fn [x y] (- x y))] (+ a b))) user=> (xplus 5 2) 7 Rgds, Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Question about building modular code in Clojure
Hi Mark, I've used the following macro to achieve something like what you're doing; In the file/namespace module (say eg_globs/fns.clj); (ns eg-globs.fns) (declare *gravity*) (defmacro with-grav [grav & body] `(let [gr# ~grav] (binding [*gravity* gr#] ~...@body))) (defn say-grav [] (prn "Gravity is:" *gravity*)) (defn halve-grav [] (/ *gravity* 2.0)) (defn mult-grav [x] (* *gravity* x)) Then in the calling module; (use 'eg-globs.fns) (with-grav 2.0 (say-grav) (prn "half:" (halve-grav)) (mult-grav 2.5)) "Gravity is:" 2.0 "half:" 1.0 5.0 (with-grav 1.5 (mult-grav 3.0)) 4.5 Hth, Adrian. On Sun, May 17, 2009 at 4:45 AM, Mark Engelberg wrote: > > So I've built a file/namespace with several functions. There are > several globals defined at the top of the file (for example, > *gravity*) which many of the functions refer to. I made them globals > precisely because it would have been a pain to thread them through > every single function that uses them. > > Now, I need to maintain two versions of this module. For example, > let's say I want one module where the *gravity* constant is defined to > be 1.0, and one where it is defined as 2.0. > > I know how to do this in other languages, especially OO ones, but I'm > scratching my head trying to think of a clean solution in Clojure for > this seemingly simple problem. I've tried various namespace trickery > with vars and bindings, but I haven't found a workable solution yet. > What am I missing? 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: Question about building modular code in Clojure
> ... signs a contributor agreement. If he wants to create his own > version of the module for his own personal use, in which he swaps out > my function for his faster one, there appears to be no good way to do > this, short of copying my entire file, commenting out my function, ... I think Stuart's idea (rather than binding) might be the recipe for a solution to this. Using the canonical gravity example; (use 'gravity) (alter-var-root (var say-grav) (fn [_] (fn [x] (prn "my-version-grav:" x (say-grav 3.0) "my-version-grav:" 3.0 The alter-var-root could be wrapped in one or more functions or macros to make the "overriding" a bit more friendly. Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Question about building modular code in Clojure
On Mon, May 18, 2009 at 11:29 AM, Mark Reid wrote: > ... > test=> (lcm 4 6) > 24 > > > Maybe a variant of ns could be written that allows the overriding of > specific functions? e.g., > I know I keep plugging this - sorry - but it just keeps surfacing as a solution; (lcm 4 6) 12 (binding [clojure.contrib.math/gcd (fn [a b] 1)] (lcm 4 6)) 24 Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Question about building modular code in Clojure
Aha! Thank you for clarifying that. Reinforces your point on monkey-patching :). I will read your blog post with careful attention. Adrian. On Mon, May 18, 2009 at 12:42 PM, Konrad Hinsen wrote: > > On May 18, 2009, at 11:58, Adrian Cuthbertson wrote: > >> I know I keep plugging this - sorry - but it just keeps surfacing >> as a solution; >> >> (lcm 4 6) >> 12 >> (binding [clojure.contrib.math/gcd (fn [a b] 1)] (lcm 4 6)) >> 24 > > Such a use of binding will lead to bad surprises as soon as you use > it with lazy sequences: > > (map #(lcm % 6) (range 6)) > -> (0 6 6 6 12 30) > > (binding [clojure.contrib.math/gcd (fn [a b] 1)] > (map #(lcm % 6) (range 6))) > -> (0 6 6 6 12 30) > > You have to use doall to get the result you expect: > > (binding [clojure.contrib.math/gcd (fn [a b] 1)] > (doall (map #(lcm % 6) (range 6 > -> (0 6 12 18 24 30) > > The reason is that the temporary binding remains active only while > map creates the lazy sequence that it returns, but it is no longer > active when the actual elements of the lazy sequence are evaluated. > > More details and examples in my blog post: > http://onclojure.com/2009/05/06/simulating-dynamic-scoping/ > > 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: Clojure as a Java lib documentation / examples?
Check out clojure.org - focus on java interop, compilation and class generation. Mark Volkmann's http://java.ociweb.com/mark/clojure/article.html has a good general clojure overview and nice examples. Gen-class and proxy are the main tools you'll need for exposing your clojure libraries as java api's. Rgds, Adrian. On Fri, May 22, 2009 at 2:23 AM, Brett Morgan wrote: > > Hi guys, > > I have some evil thoughts of using Clojure as a java library so that i > can use both the STM and the persistent data structures in projects > that my team of java developers can work with. > > As much as I'd like to get the team coding in Clojure properly, I have > enough trouble selling the idea of using immutable data structures. If > I hide the clojure magic behind interfaces, I can have the team coding > in plain java, and wrap what they do in clojure transactions and what > not. I'd like to do this in a way that the clojure repl can still be > used to interact with the running server. > > So where do I start reading? =) > > -- > > Brett Morgan http://brett.morgan.googlepages.com/ > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure for high-end game development
> Game developement? Some work has been done on using clojure with jogl (the java opengl library) Search this forum with "jogl" for details. > with the Android platform I'm pretty sure there is also an android implementation of clojure. Again, search this forum for "android". Rgds, Adrian. On Fri, May 22, 2009 at 4:29 AM, Mark Fayngersh wrote: > Game developement? > Definitely possible. I was even thinking of finding a way to bridge Clojure > with the Android platform > > Electronic Arts? > Most likely not. > > On Thu, May 21, 2009 at 2:35 PM, tcg wrote: >> >> You would think with Clojure's ability to make use of mutli cpu >> hardware it would be a good choice for high-end game development. >> >> Does anyone know if big game studios like Electronic Arts are using or >> looking into Clojure for this purpose? >> >> > > > > -- > ~phunny.pha...@gmail.com > ~mar...@archlinux.us > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure at JavaOne
>... impact part can be merged with the "business application" mindset by >generating a report that includes the data visualization (I think PDF >generation is built into processing). I've been doing some work with enlive and XHtmlRenderer - it's a pretty awesome way of generating (business, media, etc) PDF docs from html templates, css style sheets and clojure generated data. I could post some examples if there's any interest. Rgds, Adrian. On Thu, May 21, 2009 at 4:38 PM, Chas Emerick wrote: > > I'm guessing glitz and visual impact is what's going to wow the crowd, > especially in that environment, where it's likely that most people are > steeped in "business applications". > > Perhaps using one of the clojure-processing wrappers to do some > outrageously-slick data visualization, and then showing how little > code is required to do it and how much leverage the language provides > when addressing changes in requirements? Maybe the slick visual > impact part can be merged with the "business application" mindset by > generating a report that includes the data visualization (I think PDF > generation is built into processing). > > - Chas > > On May 18, 7:36 am, Rich Hickey wrote: > >> The audience is Java developers, many of whom will have never seen >> Clojure or any Lisp. >> >> I'd appreciate some suggestions *and help* preparing demos for the >> Script Bowl. What (that could be demonstrated in 4 minutes) would make >> you think - 'Clojure looks cool, I need to look into it'? What >> community contribution(s) should we showcase? > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: "run" macro for "executable namespaces"
Thanks Steve! That's very neat. Pretty much a "canonical" macro example. Adrian. On Tue, Jun 2, 2009 at 5:50 AM, Stephen C. Gilardi wrote: > Here's a macro I've found useful for loading and running Clojure programs > from the REPL: > > (defmacro run > "Loads the specified namespace and invokes its \"main\" > function with optional args. ns-name is not evaluated." > [ns-name & args] > `(do > (require '~ns-name :reload-all) > ((ns-resolve '~ns-name '~'main) ~...@args))) > > An example namespace that works with it (in hello.clj at a classpath root): > > (ns hello) > > (defn main > [& args] > (apply println "hi" args)) > > and a REPL session: > > user=> (run hello) > hi > nil > user=> (run hello :clojure "is" \# > (.gcd (bigint 1169687) (bigint 311791))) > hi :clojure is # 1 > nil > user=> > > I think the quoting on "main" in the ns-resolve call is quite interesting. > macroexpand-ing variations on it is a heap of educational Clojure macro-fu > fun! > > --Steve > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: You know you've been writing too much Clojure when...
> ... You know you've been writing too much Clojure when... You see a cartoon swearword @^#!>! and you think it's clojure meta-data! -Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Reading files with nio.
Thanks, these are useful posts. On Thu, Jun 11, 2009 at 4:49 AM, Nicolas Buduroi wrote: > > I've got an even faster version using memory-mapped file I/O. It also > simplify the code a little bit. > > (defn fast-read-file [#^String filename #^String charset] > (with-open [cin (. (new FileInputStream filename) getChannel)] > (let [size (. (new File filename) length) > char-buffer (. ByteBuffer (allocate size)) > decoder (. (. Charset (forName charset)) (newDecoder))] > (str > (. decoder > (decode > (.map cin (. FileChannel$MapMode READ_ONLY) 0 size))) > > On Windows I get these results: > > nio=> (time (dotimes [i 1000] (fast-read-file ".emacs" "ISO-8859-1"))) > "Elapsed time: 247.9453 msecs" > nio=> (time (dotimes [i 1000] (fast-read-file ".emacs" "ISO-8859-1"))) > "Elapsed time: 247.666881 msecs" > nio=> (time (dotimes [i 1000] (fast-read-file ".emacs" "ISO-8859-1"))) > "Elapsed time: 247.895424 msecs" > > Compared with the previous version with buffer size equal to the > length of the file: > > nio=> (time (dotimes [i 1000] (read-file ".emacs" "ISO-8859-1" (. (new > File ".emacs") length > "Elapsed time: 264.470276 msecs" > nio=> (time (dotimes [i 1000] (read-file ".emacs" "ISO-8859-1" (. (new > File ".emacs") length > "Elapsed time: 265.775947 msecs" > nio=> (time (dotimes [i 1000] (read-file ".emacs" "ISO-8859-1" (. (new > File ".emacs") length > "Elapsed time: 263.828204 msecs" > > The API documentation for the map method aren't very exhaustive, > there's not much information on its limits. A lot of details are > implementation dependent and left unspecified, most problems though > seems to be related to writing. > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple idiom in clojure, mutate a value
You could do something like; (let [updated-val (loop [updateable start-value line (.readline reader)] (if (or (empty? line) (> line-num max-num)) (+ updateable (somefunc)) (recur (.readLine reader)] (do-something with updated-val)) Rgds, Adrian. On Thu, Jun 11, 2009 at 8:34 PM, David Nolen wrote: > Why isn't the following satisfactory for your needs? get-value takes a value > returns a new value based on it. do-something can 'do something' to/with > this new value. > (defn get-value [start-value] > (loop [updateable start-value line (.readline reader)] > (if (or (empty? line) (> line-num max-num)) > (+ updateable (somefunc)) > (recur (.readLine reader) > (defn do-something [] > (let [updated-value (get-value 0)] > (println updated-value)) > On Thu, Jun 11, 2009 at 2:21 PM, Berlin Brown > wrote: >> >> >> >> On Jun 11, 12:16 pm, Daniel Lyons wrote: >> > On Jun 11, 2009, at 9:25 AM, BerlinBrown wrote: >> > >> > >> > >> > > I do this a lot but can't figure out to change the UPDATEABLE_VALUE, I >> > > am using some pseudo code because I don't have a clojure solution yet. >> > >> > > SET UPDATEABLE_VALUE = 0 >> > > (loop [line (.readLine reader)] >> > > (if (or (empty? line) (> line-num max-num)) >> > > SET UPDATEABLE_VALUE = UPDATEABLE_VALUE + (SOME_FUNC) >> > > (recur (.readLine reader >> > >> > In general it's going to be something like this: >> > >> > (loop [line (.readLine reader) UPDATEABLE_VALUE 0] >> > (if (or (empty? line) (> line-num max-num)) >> > (recur (.readLine reader) (+ UPDATEABLE_VALUE (SOME_FUNC) >> > >> > Whenever you would have modified a local variable before, in FP you >> > establish a new binding instead. >> > >> > — >> > Daniel Lyonshttp://www.storytotell.org-- Tell It! >> >> I can modify the value within the loop, but what is a good approach >> for accessing the value outside of the loop. For example (pseudo code >> with a mix of procedural logic). >> >> ;; Init updateable value outside of 'loop' >> SET UPDATEABLE_VALUE = 0 >> (loop [line (.readLine reader)] >> (if (or (empty? line) (> line-num max-num)) >> SET UPDATEABLE_VALUE = UPDATEABLE_VALUE + (SOME_FUNC) >> (recur (.readLine reader >> ;; Now outside of the loop, use UPDATEABLE_VALUE with the mutated >> value >> (println UPDATEABLE_VALUE) >> >> >> >> > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple idiom in clojure, mutate a value
Re-read your example - that should have been; (let [updated-val (loop [updateable 0 line (.readline reader)] (if (or (empty? line) (> line-num max-num)) (+ updateable (somefunc)) (recur (.readLine reader)] (do-something-with updated-val)) I.e initialising updateable to 0. On Thu, Jun 11, 2009 at 8:38 PM, Adrian Cuthbertson wrote: > You could do something like; > > (let [updated-val (loop [updateable start-value line (.readline reader)] > (if (or (empty? line) (> line-num max-num)) > (+ updateable (somefunc)) > (recur (.readLine reader)] > (do-something with updated-val)) > > Rgds, Adrian. > > On Thu, Jun 11, 2009 at 8:34 PM, David Nolen wrote: >> Why isn't the following satisfactory for your needs? get-value takes a value >> returns a new value based on it. do-something can 'do something' to/with >> this new value. >> (defn get-value [start-value] >> (loop [updateable start-value line (.readline reader)] >> (if (or (empty? line) (> line-num max-num)) >> (+ updateable (somefunc)) >> (recur (.readLine reader) >> (defn do-something [] >> (let [updated-value (get-value 0)] >> (println updated-value)) >> On Thu, Jun 11, 2009 at 2:21 PM, Berlin Brown >> wrote: >>> >>> >>> >>> On Jun 11, 12:16 pm, Daniel Lyons wrote: >>> > On Jun 11, 2009, at 9:25 AM, BerlinBrown wrote: >>> > >>> > >>> > >>> > > I do this a lot but can't figure out to change the UPDATEABLE_VALUE, I >>> > > am using some pseudo code because I don't have a clojure solution yet. >>> > >>> > > SET UPDATEABLE_VALUE = 0 >>> > > (loop [line (.readLine reader)] >>> > > (if (or (empty? line) (> line-num max-num)) >>> > > SET UPDATEABLE_VALUE = UPDATEABLE_VALUE + (SOME_FUNC) >>> > > (recur (.readLine reader >>> > >>> > In general it's going to be something like this: >>> > >>> > (loop [line (.readLine reader) UPDATEABLE_VALUE 0] >>> > (if (or (empty? line) (> line-num max-num)) >>> > (recur (.readLine reader) (+ UPDATEABLE_VALUE (SOME_FUNC) >>> > >>> > Whenever you would have modified a local variable before, in FP you >>> > establish a new binding instead. >>> > >>> > — >>> > Daniel Lyonshttp://www.storytotell.org-- Tell It! >>> >>> I can modify the value within the loop, but what is a good approach >>> for accessing the value outside of the loop. For example (pseudo code >>> with a mix of procedural logic). >>> >>> ;; Init updateable value outside of 'loop' >>> SET UPDATEABLE_VALUE = 0 >>> (loop [line (.readLine reader)] >>> (if (or (empty? line) (> line-num max-num)) >>> SET UPDATEABLE_VALUE = UPDATEABLE_VALUE + (SOME_FUNC) >>> (recur (.readLine reader >>> ;; Now outside of the loop, use UPDATEABLE_VALUE with the mutated >>> value >>> (println UPDATEABLE_VALUE) >>> >>> >>> >>> >> >> >> >> >> > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple idiom in clojure, mutate a value
Here's a fuller example of similar techniques extracted from a working program. It reads a file of lines and applies some transformations and accumulates a vector of records which it finally returns; (defn some-fn "Read a file and return a vector of its records." [fpath] (let [r (BufferedReader. (FileReader. (File. fpath)))] (try (let [line (.readLine r)] ; discard line 1 (loop [line (.readLine r) recs []] (if-not line recs (let [rec (do-something-with line) newrecs (conj recs rec)] (recur (.readLine r) newrec) (finally (.close r) On Thu, Jun 11, 2009 at 8:48 PM, Adrian Cuthbertson wrote: > Re-read your example - that should have been; > > (let [updated-val (loop [updateable 0 line (.readline reader)] > (if (or (empty? line) (> line-num max-num)) > (+ updateable (somefunc)) > (recur (.readLine reader)] > (do-something-with updated-val)) > > I.e initialising updateable to 0. > > > On Thu, Jun 11, 2009 at 8:38 PM, Adrian > Cuthbertson wrote: >> You could do something like; >> >> (let [updated-val (loop [updateable start-value line (.readline reader)] >> (if (or (empty? line) (> line-num max-num)) >> (+ updateable (somefunc)) >> (recur (.readLine reader)] >> (do-something with updated-val)) >> >> Rgds, Adrian. >> >> On Thu, Jun 11, 2009 at 8:34 PM, David Nolen wrote: >>> Why isn't the following satisfactory for your needs? get-value takes a value >>> returns a new value based on it. do-something can 'do something' to/with >>> this new value. >>> (defn get-value [start-value] >>> (loop [updateable start-value line (.readline reader)] >>> (if (or (empty? line) (> line-num max-num)) >>> (+ updateable (somefunc)) >>> (recur (.readLine reader) >>> (defn do-something [] >>> (let [updated-value (get-value 0)] >>> (println updated-value)) >>> On Thu, Jun 11, 2009 at 2:21 PM, Berlin Brown >>> wrote: >>>> >>>> >>>> >>>> On Jun 11, 12:16 pm, Daniel Lyons wrote: >>>> > On Jun 11, 2009, at 9:25 AM, BerlinBrown wrote: >>>> > >>>> > >>>> > >>>> > > I do this a lot but can't figure out to change the UPDATEABLE_VALUE, I >>>> > > am using some pseudo code because I don't have a clojure solution yet. >>>> > >>>> > > SET UPDATEABLE_VALUE = 0 >>>> > > (loop [line (.readLine reader)] >>>> > > (if (or (empty? line) (> line-num max-num)) >>>> > > SET UPDATEABLE_VALUE = UPDATEABLE_VALUE + (SOME_FUNC) >>>> > > (recur (.readLine reader >>>> > >>>> > In general it's going to be something like this: >>>> > >>>> > (loop [line (.readLine reader) UPDATEABLE_VALUE 0] >>>> > (if (or (empty? line) (> line-num max-num)) >>>> > (recur (.readLine reader) (+ UPDATEABLE_VALUE (SOME_FUNC) >>>> > >>>> > Whenever you would have modified a local variable before, in FP you >>>> > establish a new binding instead. >>>> > >>>> > — >>>> > Daniel Lyonshttp://www.storytotell.org-- Tell It! >>>> >>>> I can modify the value within the loop, but what is a good approach >>>> for accessing the value outside of the loop. For example (pseudo code >>>> with a mix of procedural logic). >>>> >>>> ;; Init updateable value outside of 'loop' >>>> SET UPDATEABLE_VALUE = 0 >>>> (loop [line (.readLine reader)] >>>> (if (or (empty? line) (> line-num max-num)) >>>> SET UPDATEABLE_VALUE = UPDATEABLE_VALUE + (SOME_FUNC) >>>> (recur (.readLine reader >>>> ;; Now outside of the loop, use UPDATEABLE_VALUE with the mutated >>>> value >>>> (println UPDATEABLE_VALUE) >>>> >>>> >>>> >>>> >>> >>> >>> >>> >>> >> > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Mnesia like?
There's also Berkeley DB Java Edition, now owned by Oracle (it has a GPL compatible license). It's an excellent, robust, embedded, fully transactional key-store db. See http://www.oracle.com/database/berkeley-db/je/index.html On Tue, Jun 16, 2009 at 3:26 PM, Jonah Benton wrote: > > Another schemaless db is mongo: > > http://www.mongodb.org > > It's written in c++, so it's out of process, but using the java driver > is pretty natural: > > http://www.mongodb.org/display/DOCS/Java+Tutorial > > > > On Tue, Jun 16, 2009 at 3:24 AM, Wilson MacGyver wrote: >> >> Sorry I wasn't very clear. What I meant was I didn't know if there >> was something that's tightly integrated and feels very >> native language-ish like Mnesia and erlang, but for clojure. >> >> It doesn't sound like such thing exist yet... >> >> On Tue, Jun 16, 2009 at 3:13 AM, rb wrote: >>> >>> On Jun 15, 6:02 pm, Wilson MacGyver wrote: Does clojure have anything like erlang's Mnesia? or is anyone working on such project? I know I can fall back to using JDBC+ various RDBMS, but I was curious if there is something that works like Mnesia. >>> >>> Depending on what you mean by "works like Mnesia", you might be >>> interested to look at >>> http://hadoop.apache.org/hbase/ >>> >>> Cheers >>> >>> Raph >>> Thanks, Mac -- Omnem crede diem tibi diluxisse supremum. >>> > >>> >> >> >> >> -- >> Omnem crede diem tibi diluxisse supremum. >> >> > >> > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: the inverse function of load or load-file
You can use the following; (defn frm-save "Save a clojure form to file." [#^java.io.File file form] (with-open [w (java.io.FileWriter. file)] (binding [*out* w *print-dup* true] (prn frm (defn frm-load "Load a clojure form from file." [#^java.io.File file] (with-open [r (java.io.PushbackReader. (java.io.FileReader. file))] (let [rec (read r)] rec))) Have a look at clojure.core_print.clj in the clojure source for details on print-dup. Rgds, Adrian. On Tue, Jun 23, 2009 at 4:11 PM, ogcraft wrote: > > Dear all, > Is there an inverse function of load or load-file. > I mean the "save" function which writes the clojure variables or > entire workspace context (in textual form) to the file? > That we can load-file on such file and get the same variables as when > "save" was originally invoked. > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: the inverse function of load or load-file
Sorry, (prn frm) should have been (prn form). On Wed, Jun 24, 2009 at 5:33 AM, Adrian Cuthbertson < adrian.cuthbert...@gmail.com> wrote: > You can use the following; > > (defn frm-save > "Save a clojure form to file." > [#^java.io.File file form] > (with-open [w (java.io.FileWriter. file)] > (binding [*out* w *print-dup* true] (prn frm > > (defn frm-load > "Load a clojure form from file." > [#^java.io.File file] > (with-open [r (java.io.PushbackReader. > (java.io.FileReader. file))] > (let [rec (read r)] > rec))) > > Have a look at clojure.core_print.clj in the clojure source for details on > print-dup. > > Rgds, Adrian. > > > On Tue, Jun 23, 2009 at 4:11 PM, ogcraft wrote: > >> >> Dear all, >> Is there an inverse function of load or load-file. >> I mean the "save" function which writes the clojure variables or >> entire workspace context (in textual form) to the file? >> That we can load-file on such file and get the same variables as when >> "save" was originally invoked. >> >> >> >> > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: I must be blind. No matching method found?
There was a post a few days ago about a StringBuilder problem on MacOs Java 1.5. I think this is the same problem (i.e Java not Clojure). Rgds, Adrian. On Thu, Jun 25, 2009 at 4:52 AM, Cosmin Stejerean wrote: > > > On Wed, Jun 24, 2009 at 8:59 PM, CuppoJava wrote: > >> >> Hi guys, >> I'm having the hardest time figuring out why this won't run. I've been >> staring at it for the last half hour, and it's only a single line. >> Another pair of eyes would be beneficial I think. >> >> (.substring (StringBuilder. "i must be blind") 4) >> (.substring (StringBuilder. "i must be blind") (int 4)) >> >> Both give me: >> >> java.lang.IllegalArgumentException: No matching method found: >> substring for class java.lang.StringBuilder >> > > Odd, I get the same error running against Clojure 1.0 > > Clojure 1.0.0- > user=> (.substring (StringBuilder. "i must be blind") 4) > java.lang.IllegalArgumentException: No matching method found: substring for > class java.lang.StringBuilder (NO_SOURCE_FILE:0) > user=> (.substring (StringBuilder. "i must be blind") (int 4)) > java.lang.IllegalArgumentException: No matching method found: substring for > class java.lang.StringBuilder (NO_SOURCE_FILE:0) > > -- > Cosmin Stejerean > http://offbytwo.com > > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: [OT] Convincing others about Clojure
> I need some pointers on this. This is a really crucial thing for me and > any help will be appreciated. Here's one - better warn them not to let on what the startup is. Someone here will get it to market an order of magnitude quicker than they will on some other platform :-). On Thu, Jun 25, 2009 at 7:59 AM, Baishampayan Ghose wrote: > Hello, > > So I have been a Common Lisp user for quite sometime and at my earlier > work we managed to build a state-of-the-art Travel portal in CL with a > very small team of CL programmers. > > This was all fine except one thing. The management never really believed > in Lisp and they eventually replaced the whole Lisp team with 3x Java > programmers and are now rewriting the perfectly fine system in Java. > > That was my earlier job. > > Now I am at the moment doing a startup and I was thinking of using > Clojure because it has the best of both the worlds. It can use Java > libs, is a Lisp and is heavily geared towards concurrent programming; > making it one of the most modern and pragmatic programming languages at > the moment. > > This decision was based purely on the merit of Clojure and not because I > just wanted to do some Lisp programming. I seriously believe that > Clojure can really help us in building the kind of concurrent > application we want to build. > > But then, there is another problem. The advisors of the current startup > (who were techies in their time, but now are highly successful people in > the Silicon Valley) reacted strongly to the word "Lisp" (it apparently > brought back old memories of their AI class in college) and are not > "convinced enough" about Clojure. > > I tried explaining that Clojure runs on the JVM and thus won't have any > problem with libs or integrating with existing Java apps but they are > not happy. > > Their concerns are thus: > > 1. How do you get Clojure programmers? Lisp is not for the faint hearted. > > 2. What about the performance of Clojure? Is it fast? > > 3. People who want to use this are more academically inclined and are > not practical. This will make the whole project fail. > > I need some pointers on this. This is a really crucial thing for me and > any help will be appreciated. > > Regards, > BG > > -- > Baishampayan Ghose > oCricket.com > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Speedy accessors for the trees of clojure.xml
As a matter of interest, one can get the keys keys in an unknown struct by allocating an empty struct; (def st (create-struct :a :b :c)) (keys (struct st)) (:a :b :c) -Adrian. On Tue, Jun 30, 2009 at 12:14 AM, samppi wrote: > > Wonderful. Thanks for the answer. > > On Jun 29, 2:47 pm, Rich Hickey wrote: > > On Jun 29, 4:59 pm, samppi wrote: > > > > > clojure.xml/parse returns a PersistentStructMap. Is there a way to > > > refer to its struct template? I wish to create accessors for its keys, > > > such as :tag, :attrs, and :content, with the accessor function for > > > speed. > > > > If you look at the top of xml.clj you'll see they already exist. > > > > 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Speedy accessors for the trees of clojure.xml
How about; (defn get-accessors "Given a struct definition, return a map of its keys and generated accessors for each key." [the-struct] (let [st-kys (keys (struct the-struct))] (reduce (fn [accsrs ky] (assoc accsrs ky (accessor the-struct ky))) {} st-kys))) (defstruct test-s :a :b :c) (def acc (get-accessors test-s)) ((acc :a) (struct test-s 5 3 2)) 5 Obviously looking up the accessor to look up the value defeats the performance objective, but not if you get the accessors once, "let" the needed ones and then use them in a loop processing lots of strucs say. On Tue, Jun 30, 2009 at 6:14 AM, samppi wrote: > > Yes, but I'm not so sure that you can get usable accessors with those > keys: > Clojure 1.0.0- > user=> (defstruct test-s :a :b :c) > #'user/test-s > user=> (defstruct test-2-s :a :b :c) > #'user/test-2-s > user=> (def accessor-a (accessor test-s :a)) > #'user/accessor-a > user=> (accessor-a (struct test-2-s 5 3 2)) > java.lang.Exception: Accessor/struct mismatch (NO_SOURCE_FILE:0) > > But thanks for the tip anyway! > > On Jun 29, 6:47 pm, Adrian Cuthbertson > wrote: > > As a matter of interest, one can get the keys keys in an unknown struct > by > > allocating an empty struct; > > > > (def st (create-struct :a :b :c)) > > (keys (struct st)) > > (:a :b :c) > > > > -Adrian. > > > > > > > > On Tue, Jun 30, 2009 at 12:14 AM, samppi wrote: > > > > > Wonderful. Thanks for the answer. > > > > > On Jun 29, 2:47 pm, Rich Hickey wrote: > > > > On Jun 29, 4:59 pm, samppi wrote: > > > > > > > clojure.xml/parse returns a PersistentStructMap. Is there a way to > > > > > refer to its struct template? I wish to create accessors for its > keys, > > > > > such as :tag, :attrs, and :content, with the accessor function for > > > > > speed. > > > > > > If you look at the top of xml.clj you'll see they already exist. > > > > > > 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: adding a member to a set in a map in a map in a map in a ref
You could use assoc-in... (def rms (ref {:key1 {:key2 {:key3 #{)) (dosync (alter rms assoc-in [:key1 :key2 :key3] "foo")) {:key1 {:key2 {:key3 "foo"}}} Rgds, Adrian. On Sun, Jul 5, 2009 at 6:07 AM, Rowdy Rednose wrote: > > Say I have a data structure like this > > (def ref-map-map-map-set (ref {:key1 {:key2 {:key3 #{)) > > If I want to add a new member to the set which is the value of :key3, > I currently do this: > > (dosync > (let [key1 (:key1 @ref-map-map-map-set) > key2 (:key2 key1) > key3 (:key3 key2)] > (ref-set ref-map-map-map-set (assoc @ref-map-map-map-set :key1 > (assoc key1 :key2 (assoc key2 :key3 (conj key3 new-member))) > > Do I really have to assoc all the way through to the inner map? Isn't > there a more succinct way to write this? In Common Lisp there's (setf > (getf ...)) > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Calling static methods on a variable holding a class
You can call the static method directly on the class name; (java.nio.ByteBuffer/allocate 1024) or just (ByteBuffer/allocat 1024) if it's imported. Rgds, Adrian. On Tue, Jul 7, 2009 at 2:16 AM, Nicolas Buduroi wrote: > > I've just figured out that the macro version in the allocate example > can't be used with local variables. > > (let [foo ByteBuffer] > (allocate1 foo 1024)) > > throws java.lang.UnsupportedOperationException: Can't eval locals > (NO_SOURCE_FILE:94) > > On Jul 6, 6:59 pm, Nicolas Buduroi wrote: > > Hi, I needed to call a static method on a class stored in a var > > yesterday and found that it was a little bit trickier than I initially > > thought. There's three way of doing it, the two first are quite > > straightforward and working ;-) e.g.: > > > > (import '(java.nio ByteBuffer FloatBuffer)) > > > > (def foo ByteBuffer) > > > > (. foo (allocate 1024)) ; throw an exception as intended. > > > > (defmacro allocate1 [buffer-type size] > > `(. ~(eval buffer-type) (allocate ~size))) > > > > (defn allocate2 [buffer-type size] > > (eval `(. ~buffer-type (allocate ~size > > > > (allocate1 foo 1024) > > (allocate2 foo 1024) > > > > Both works fine, but I'm still not sure which one is the best. The > > third way is to call a static method from the class object, I've tried > > something but wasn't able to get it working. It throws some weird > > exception, here's the code: > > > > (defn to-primitive [class] > > (try > > (let [type (.getField (identity class) "TYPE")] > >(.get type Object)) > > (catch NoSuchFieldException _ class))) > > > > (defmacro call-static [class name & args] > > (let [arg-types (into-array > > (map (comp to-primitive #(.getClass %)) args)) > > method (.getMethod (eval class) name arg-types)] > > `(.invoke ~method ~class ~...@args))) > > > > When calling this macro (call-static foo "allocate" 1024) it throws: > > java.lang.RuntimeException: Can't embed object in code, maybe print- > > dup not defined: public static java.nio.ByteBuffer > > java.nio.ByteBuffer.allocate(int) (NO_SOURCE_FILE:0) > > > > This error message is quite puzzling isn't it? > > > > Is there any other way? > > > > Thanks > > > > - budu > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Calling static methods on a variable holding a class
Hi Nicolas, sorry, that last post missed the second part, I meant to add; If you know the method you wish to call, do you not know the class and can thus call the static method directly? -Adrian. On Tue, Jul 7, 2009 at 5:21 AM, Adrian Cuthbertson < adrian.cuthbert...@gmail.com> wrote: > You can call the static method directly on the class name; > > (java.nio.ByteBuffer/allocate 1024) > > or just (ByteBuffer/allocat 1024) > if it's imported. > > Rgds, Adrian. > > > On Tue, Jul 7, 2009 at 2:16 AM, Nicolas Buduroi wrote: > >> >> I've just figured out that the macro version in the allocate example >> can't be used with local variables. >> >> (let [foo ByteBuffer] >> (allocate1 foo 1024)) >> >> throws java.lang.UnsupportedOperationException: Can't eval locals >> (NO_SOURCE_FILE:94) >> >> On Jul 6, 6:59 pm, Nicolas Buduroi wrote: >> > Hi, I needed to call a static method on a class stored in a var >> > yesterday and found that it was a little bit trickier than I initially >> > thought. There's three way of doing it, the two first are quite >> > straightforward and working ;-) e.g.: >> > >> > (import '(java.nio ByteBuffer FloatBuffer)) >> > >> > (def foo ByteBuffer) >> > >> > (. foo (allocate 1024)) ; throw an exception as intended. >> > >> > (defmacro allocate1 [buffer-type size] >> > `(. ~(eval buffer-type) (allocate ~size))) >> > >> > (defn allocate2 [buffer-type size] >> > (eval `(. ~buffer-type (allocate ~size >> > >> > (allocate1 foo 1024) >> > (allocate2 foo 1024) >> > >> > Both works fine, but I'm still not sure which one is the best. The >> > third way is to call a static method from the class object, I've tried >> > something but wasn't able to get it working. It throws some weird >> > exception, here's the code: >> > >> > (defn to-primitive [class] >> > (try >> > (let [type (.getField (identity class) "TYPE")] >> >(.get type Object)) >> > (catch NoSuchFieldException _ class))) >> > >> > (defmacro call-static [class name & args] >> > (let [arg-types (into-array >> > (map (comp to-primitive #(.getClass %)) args)) >> > method (.getMethod (eval class) name arg-types)] >> > `(.invoke ~method ~class ~...@args))) >> > >> > When calling this macro (call-static foo "allocate" 1024) it throws: >> > java.lang.RuntimeException: Can't embed object in code, maybe print- >> > dup not defined: public static java.nio.ByteBuffer >> > java.nio.ByteBuffer.allocate(int) (NO_SOURCE_FILE:0) >> > >> > This error message is quite puzzling isn't it? >> > >> > Is there any other way? >> > >> > Thanks >> > >> > - budu >> >> >> > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Performance question (newbie)
It's also worth searching this group for 'performance' and checking out the discussions over the past few months. There've been lots of queries about many different aspects of performance and some really good advice dispensed. - Adrian. On Wed, Jul 15, 2009 at 3:39 PM, Frantisek Sodomka wrote: > > PS: Read tips on: > http://clojure.org/java_interop > > > On Jul 15, 1:51 pm, Dragan wrote: >> Hi, >> >> I am trying to compare the performance of java loops to clojure reduce >> function. Noting special, Since I am just learning. >> Java code is something like: >> >> [code] >> long sum = 0; >> for (int i = 1; i < 100; i++ ){ >> sum = sum + i;} >> >> [/code] >> >> while in Clojure I used: >> >> [code] >> (reduce + (range 1 i)) >> [/code] >> >> Execution time for the Java version is 7 ms, while Clojure needs 60 - >> 160 ms. >> Now, that is expected, since Clojure runs in REPL. >> Next, I tried the gen-class of the Clojure, and called that Class from >> Java (so no REPL involved), but the code haven't speed up at all! >> Am I missing something or such 10x performance penalty is usual for >> such operations? > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to achieve indirection?
You can also pass functions (and closures) around in a map; (defn my-app-uses-do-something [map-with-cfg-stuff] ... ((:do-something map-with-cfg-stuff) 13 19)) ) (defn do-something-quickly [x y] ... (defn do-something-elegantly [x y] ... (my-app-uses-do-something {:do-something do-something-quickly :some-other-cfg-stuff [...whatever] } ) Another little example to drive home the point; (defn uses-f [mp x y] ((:f mp) x y)) (defn f [x y] (+ x y)) (uses-f {:f f} 3 4) 7 uses-f {:f -} 3 4) -1 (uses-f {:f #(+ (* %1 %2) 3)} 3 4) 15 It's really worthwhile getting one's head around higher order functions and closures. It allows you to totally think out of the (imperative) box. Don't pass the data to a function - pass the function to some data! Rgds, Adrian. On Thu, Jul 16, 2009 at 10:33 PM, John Harrop wrote: > On Thu, Jul 16, 2009 at 11:34 AM, Dragan wrote: >> >> Thanks for the tip, I meant something else. >> Let's say that I want to write a function do-something. There could be >> 2 implementations: do-something-quickly and do-something-elegantly. >> The parameters are the same and there are no differences in their >> "interface". I would like to be able to call it by writing (do- >> something arg) in my code and specify which implementation I want to >> use somewhere else (in the configuration part of the code). > > Functions are values you can pass around, so: > (defn do-something-quickly [x y] ... ) > (defn do-something-elegantly [x y] ... ) > (defn do-various-things [do-something x y z w] > (let [z (do-something x y)] > ... )) > user=> (do-various-things do-something-quickly 13 19 3 23) > some-sort-of-output > user=> (do-various-things do-something-elegantly 13 19 3 23) > some-sort-of-output > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Can (genclass) be changed to operate when not compiling?
I get around this for servlets by combining gen-class and proxy in my servlet file; (ns my-servlets.MyServlet (:import (javax.servlet.http HttpServlet HttpServletRequest HttpServletResponse)) (:gen-class :extends HttpServlet) ) (defn req-do [#^HttpServlet svlt #^HttpServletRequest req #^HttpServletResponse rsp] (do-stuff)) (defn -service [#^HttpServlet svlt #^HttpServletRequest req #^HttpServletResponse rsp] (req-do svlt req rsp) ) (def my-servlet (proxy [HttpServlet] [] (service [req rsp] (req-do this req rsp Then for production (tomcat), an ant build compiles and deploys the war with web.xml referring to myservlets.MyServlet and in my dev environment, I launch a jetty instance with my-servlet in a jetty servlet holder. I haven't done this with Filters yet, but I'm pretty sure you could use a similar approach? Hth, Adrian. On Wed, Jul 22, 2009 at 4:40 AM, Chouser wrote: > > On Tue, Jul 21, 2009 at 8:04 PM, Howard Lewis Ship wrote: >> >> Basically, what I want is for AOT to be an optional optimization, not >> a requirement. Currently if your code relies on gen-class, AOT >> becomes necessary for operation, period. > > This is how gen-class used to behave. Unfortunately, it > causes problems because named classes can't be changed once > they're loaded in the JVM. I think there are also > classloader issues that I don't yet fully understand. > > Named classes and named interfaces must be created before > the JVM is started. > > --Chouser > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: the point of next vs rest?
Hi Rob, have a look at http://clojure.org/sequences and then on that page there's a reference to http://clojure.org/lazy, which explains the evolution of the lazy/eager sequences. Next is used for eager cases (e.g loop/recur) and rest for lazy-seq. Should make sense if you check out those references. Hth, Adrian. On Sun, Aug 9, 2009 at 5:41 PM, Rob wrote: > > Hi all, > > I'm trying to understand the next vs rest functions. I don't see why > you want/need both. Is it because null is in the picture? It seems > like the interface to a good old lisp list is 3 functions (car/first/ > head, cdr/rest/tail, null?/empty?). I can imagine making this into an > abstract immutable sequence with a java interface like: > > public interface FunctionalListyThing > { > Object first(); > FunctionalListyThing rest(); > boolean isEmpty(); > } > > Why does one need the 4th method, "next()" ? > > thanks, > Rob > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Request for Discussion: user created reader macros
Hmm, not so sure this is related, but I've often thought it would be great to have some way of having "embedded" source of other types as a "special" string defined as normal in the clojure source but marked in such as way that the editor (vim, emacs, etc) could recognise this and do formatting, syntax highlighting, etc on that text. Similarly to say editing HTML with embedded javascript/css/jsp. This could presumably be done by using some meta-data convention rather than a reader macro, but this thread brought up the idea. Any thoughts? On Fri, Aug 14, 2009 at 5:55 AM, Scott wrote: > > > On Aug 13, 5:47 pm, Chas Emerick wrote: >> >> A good thought, but #"foo" is reader syntax for defining a regular >> expression with the pattern "foo". :-/ >> > > Sorry about that, I'm not experienced at Clojure, but I should have > been more clear. The first important part isn't which character > triggers the arbitrary string literal (as you point out, #" is already > taken), but that you get to choose the terminating delimiter such that > it doesn't interfere with your DSL. The second part is that once you > can cleanly express arbitrary string literals, a regular macro can > substitute for a reader macro and avoids the namespace issues. > >> >> Double-quoted strings are decent for stuff like this. (Triple-quotes >> in python always appealed to me, though triple-quoting things can get >> tiring.) >> > > I use Python's triple quotes too, but you may want to create a DSL > that can contain both ''' (triple single quote) and """ (triple double > quote) in it. (For instance if you were embedding Python source. :-) > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Jwt from Clojure?
Hi Raphaël, If you're going to drive your app (and server) from clojure, then you can use Compojure's jetty.clj module. This allows you to create a servlet holder (in which you can add an instantiated Jwt servlet on a jetty url path). Compojure also supports the Ring protocol, so you can also then use it for other webapp functionality. You could also use the Ring library, but (afaik) it uses a Jetty AbstractHander (which is a higher abstraction of the Http connection than a servlet). You would need to add some logic to create a Jetty ServletHolder class yourself (check out the Jetty api). If you're hooking into an existing server, then you can just create a webapp/war with the Jwt servlet and add your clojure (comporure/ring) apps in their own servlet using gen-class. There is an example of doing this on the compojure wiki. There are also some other frameworks that have been announced in this group - perhaps others will chip in, or search the group for previous posts on web frameworks. (Jwt looks interesting, I'm going to take a good look at it as well.) Hth, Adrian. On Mon, Aug 17, 2009 at 5:07 PM, rb wrote: > > HI, > > Jwt (http://www.webtoolkit.eu/jwt ) is a java translation of the C++ > web toolkit (http://www.webtoolkit.eu/wt ) > I'd like to develop a web app in clojure based on Jwt, but Jwt apps > need to run in a servlet container. > > What's the best path to follow in that case? Is developing a Ring > adapter which would then allow me to run the app with Jetty the way to > go? > > Every pointer will be welcome! :-) > > Thanks > > Raphaël > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to generate a hash map from a list
For completeness we should include a loop/recur pattern; (defn fzipmap [f col] "Takes a col, applies f to each element and generates a hash map keyed on each element of col." (loop [col (seq col) mp {}] (if col (recur (next col) (assoc mp (first col) (f (first col mp))) user=> (fzipmap #(+ % 3) [1 2 3]) {3 6, 2 5, 1 4} Regards, Adrian. On Mon, Aug 24, 2009 at 6:43 PM, samppi wrote: > > Wonderful; I totally didn't know about zipmap. I've been using into > and map this whole time. Was it added right before Clojure 1.0? It > seems to be a lot faster than using into: > > Clojure 1.0.0- > user=> (time (into {} (for [i [1 2 3]] [i (+ 3 i)])) ) > "Elapsed time: 0.705 msecs" > {3 6, 2 5, 1 4} > user=> (time (zipmap [1 2 3] (map #(+ 3 %) [1 2 3]))) > "Elapsed time: 0.25 msecs" > {3 6, 2 5, 1 4} > > On Aug 24, 9:15 am, Dragan Djuric wrote: >> (zipmap coll1 coll2) should be faster than (apply hash-map (interleave >> coll1 coll2)) and the doc description hints that's what it was made >> for. >> >> On Aug 24, 8:25 am, Garth Sheldon-Coulson wrote: >> >> >> >> > Welcome again. >> >> > Here's another way. Not sure if it's any more or less efficient, but it's >> > the way my brain works. >> >> > => (defn map-hashmap [coll f] >> > (apply hash-map (interleave coll (map f coll >> > #'user/map-hashmap >> >> > => (map-hashmap [1 2 3] #(+ % 3)) >> > {1 4, 2 5, 3 6} >> >> > On Mon, Aug 24, 2009 at 2:18 AM, Stephen C. Gilardi >> > wrote: >> >> > > On Aug 23, 2009, at 8:21 PM, Stan Dyck wrote: >> >> > > I'm still new to this so bear with me. >> >> > > Welcome. >> >> > > I'm trying to apply a function to a seq-able thing to produce a hashmap. >> > >> So for instance say the function is (inc 3). >> > >> I'd like to write a function that does >> >> > >> [1 2 3] --> {1 4, 2 5, 3 6} >> >> > >> Can someone help me? >> >> > > Here's one way: >> >> > > user=> (into {} (for [i [1 2 3]] [i (+ 3 i)])) >> > > {1 4, 2 5, 3 6} >> >> > > --Steve > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: A little discovery: abbreviated-namespace-qualified keywords
Also just what I needed - thanks! On Mon, Aug 24, 2009 at 8:05 PM, Dragan Djuric wrote: > > It may look silly, but that's just what I need AND the last time I > checked > it didn't work! > Now it does :) > > Thanks! > >> On Aug 24, 7:14 pm, samppi wrote: >> I just discovered something cool that might seem obvious to some >> people but is, as as I can tell, undocumented and caught me totally by >> surprise. It's well known that the reader resolves ::something >> into :the-current-namespace/something. But what I found out is that if >> you use require to alias a namespace, you can use that abbreviation >> with the double colon and a slash: >> >> Clojure 1.0.0- >> user=> (require '[clojure.contrib.test-is :as t]) >> nil >> user=> :t/a >> :t/a >> user=> ::a >> :user/a >> user=> ::t/a >> :clojure.contrib.test-is/a >> >> I had no idea, and I think it's an awesome feature. > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to generate a hash map from a list
> (defn fzipmap [f col] > "Takes a col, applies f to each element and generates a Note that the args should have come after the doc string! On Tue, Aug 25, 2009 at 6:20 AM, Adrian Cuthbertson wrote: > For completeness we should include a loop/recur pattern; > > (defn fzipmap [f col] > "Takes a col, applies f to each element and generates a > hash map keyed on each element of col." > (loop [col (seq col) mp {}] > (if col (recur (next col) (assoc mp (first col) (f (first col > mp))) > > user=> (fzipmap #(+ % 3) [1 2 3]) > {3 6, 2 5, 1 4} > > Regards, Adrian. > > On Mon, Aug 24, 2009 at 6:43 PM, samppi wrote: >> >> Wonderful; I totally didn't know about zipmap. I've been using into >> and map this whole time. Was it added right before Clojure 1.0? It >> seems to be a lot faster than using into: >> >> Clojure 1.0.0- >> user=> (time (into {} (for [i [1 2 3]] [i (+ 3 i)])) ) >> "Elapsed time: 0.705 msecs" >> {3 6, 2 5, 1 4} >> user=> (time (zipmap [1 2 3] (map #(+ 3 %) [1 2 3]))) >> "Elapsed time: 0.25 msecs" >> {3 6, 2 5, 1 4} >> >> On Aug 24, 9:15 am, Dragan Djuric wrote: >>> (zipmap coll1 coll2) should be faster than (apply hash-map (interleave >>> coll1 coll2)) and the doc description hints that's what it was made >>> for. >>> >>> On Aug 24, 8:25 am, Garth Sheldon-Coulson wrote: >>> >>> >>> >>> > Welcome again. >>> >>> > Here's another way. Not sure if it's any more or less efficient, but it's >>> > the way my brain works. >>> >>> > => (defn map-hashmap [coll f] >>> > (apply hash-map (interleave coll (map f coll >>> > #'user/map-hashmap >>> >>> > => (map-hashmap [1 2 3] #(+ % 3)) >>> > {1 4, 2 5, 3 6} >>> >>> > On Mon, Aug 24, 2009 at 2:18 AM, Stephen C. Gilardi >>> > wrote: >>> >>> > > On Aug 23, 2009, at 8:21 PM, Stan Dyck wrote: >>> >>> > > I'm still new to this so bear with me. >>> >>> > > Welcome. >>> >>> > > I'm trying to apply a function to a seq-able thing to produce a >>> > > hashmap. >>> > >> So for instance say the function is (inc 3). >>> > >> I'd like to write a function that does >>> >>> > >> [1 2 3] --> {1 4, 2 5, 3 6} >>> >>> > >> Can someone help me? >>> >>> > > Here's one way: >>> >>> > > user=> (into {} (for [i [1 2 3]] [i (+ 3 i)])) >>> > > {1 4, 2 5, 3 6} >>> >>> > > --Steve >> >> >> > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to migrate definitions to another namespace ?
> Is there a way to unregister some names from a namespace without reloading it > ? This is a bit trickier than one might think. An example illustrates this; Given two files, a.clj... (ns a) (defn stuff-a [] :stuff-a) (defn hello [] :hello) And b.clj... (ns b) (defn stuff-b [] :stuff-b) Say we have an ns 'x which is our running ns which uses 'a and 'b and we wish to move the 'hello function into 'b in the files and then dynamically reload so that 'x now has the correct mapping to 'hello (i.e in 'b) So in the Repl we'll create an empty ns 'x and change to it... user=>(create-ns 'x) # user=> (in-ns 'x) # And load the two files with clojure.core/use ('x does not refer to clojure.core so we can see all the ns mapping more clearly)... x=> (clojure.core/use 'a) nil x=> (clojure.core/use 'b) ni So, 'x now sees... (clojure.core/ns-refers 'x) {hello #'a/hello, stuff-a #'a/stuff-a, stuff-b #'b/stuff-b} And 'a and 'b contain... x=> (clojure.core/ns-publics 'a) {hello #'a/hello, stuff-a #'a/stuff-a} x=> (clojure.core/ns-publics 'b) {stuff-b #'b/stuff-b} You've probably guessed it by now - to move 'hello from 'a to 'b we have to; 1.) Move it from file a.clj to b.clj 2.) Re-require and reload 'b 3.) Unmap it in the "refers" of 'x 4.) Re-refer 'b so 'x now sees it in 'b 5.) Unmap it in the "publics" of 'a Here's the "dynamic reload" after 1.)... 2.) Reload 'b... (clojure.core/require 'b :reload) nil x=> (clojure.core/ns-publics 'b) {hello #'b/hello, stuff-b #'b/stuff-b} x=> (clojure.core/ns-publics 'a) {hello #'a/hello, stuff-a #'a/stuff-a} Note that both 'a and 'b now have 'hello loaded but that's ok as 'x still only knows about the version in 'a. 3, 4 and 5.)... x=> (clojure.core/ns-unmap 'x 'hello) nil x=> (clojure.core/refer 'b) nil x=> (clojure.core/ns-unmap 'a 'hello) nil And so finally we have... (clojure.core/ns-publics 'a) {stuff-a #'a/stuff-a} x=> (clojure.core/ns-publics 'b) {hello #'b/hello, stuff-b #'b/stuff-b} x=> (clojure.core/ns-publics 'x) {} x=> (clojure.core/ns-refers 'x) {hello #'b/hello, stuff-a #'a/stuff-a, stuff-b #'b/stuff-b} There still is a problem with this technique - 3.) and 4.) are not atomic, so if 'hello is called between those two steps (which is likely in a busy web server), that invocation will fail. Note that the (ns-remove technique has the same problem, but at a coarser grain level). I think it's worth looking at encapsulating this whole reload procedure into a properly atomically protected transaction as it will be very useful in many server scenarios. This would probably require changes to the namespace functions in core. Any thoughts? Regards, Adrian. On Sat, Aug 29, 2009 at 8:24 AM, Laurent PETIT wrote: > Could some kind of :force true flag be generally interesting for the def > special form ? (:force true would force an unmap first, if necessary) > > 2009/8/29 Vagif Verdi >> >> Thx to all. ns-unmap and remove-ns are what i need. >> >> From my CL experience i was looking for something like unitern. >> > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to represents a Big text file using sequence?
I mostly revert to good ole loop/recur for these large file processing exercises. Here's a template you could use (includes a try/catch so you can see errors as you go); (import '(java.io BufferedReader FileReader PrintWriter File)) (defn process-log-file "Read a log file tracting lines matching regx." [in-fp out-fp regx] (with-open [rdr (BufferedReader. (FileReader. (File. in-fp))) wtr (PrintWriter. (File. out-fp))] (loop [line (.readLine rdr) i 0] (if line (try (let [fnd (re-matches regx line)] (when-not (nil? fnd) (.println wtr line))) ; or whatever (recur (.readLine rdr) (inc i)) (catch Exception e (prn line e))) Regards, Adrian. On Mon, Aug 31, 2009 at 4:44 PM, wangzx wrote: > > I just want to learn clojure by using it to parse log file and > generate reports. and one question is: for a large text file, can we > use it as a sequence effectively? for example, for a 100M log file, we > need to check each line for some pattern match. > > I just using the (line-seq rdr) but it will cause > OutOfMemoryException. > > demo code > > (defn buffered-reader [file] > (new java.io.BufferedReader > (new java.io.InputStreamReader > (new java.io.FileInputStream file > > (def -reader (buffered-reader "test.txt")) > (filter #(= "some" %) -reader) > > even there is no lines match "some", the filter operation will cause > OutOfMemoryException. > > Is there other APIs like the Sequence but provide stream-like API? > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: minor grievance with arithmetic on characters
Clojure's compare; (compare \a \b) -1 user=> (doc compare) - clojure.core/compare ([x y]) Comparator. Returns 0 if x equals y, -1 if x is logically 'less than' y, else 1. Same as Java x.compareTo(y) except it also works for nil, and compares numbers and collections in a type-independent manner. x must implement Comparable Rgds, Adrian. On Tue, Sep 8, 2009 at 5:50 AM, Timothy Pratley wrote: > > Is there a way to deal with this: > user=> (> \a \b) > java.lang.ClassCastException: java.lang.Character cannot be cast to > java.lang.Number (NO_SOURCE_FILE:0) > > So far the only things I know are to coerce or use interop eg: > user=> (.compareTo \a \b) > -1 > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Content negotiation?
> Could you put it on GitHub anyway? It would be a good way to evaluate > it. +1 - I'd be interested in using it. - Adrian. On Thu, Sep 10, 2009 at 6:40 AM, Sean Devlin wrote: > > Could you put it on GitHub anyway? It would be a good way to evaluate > it. > > On Sep 10, 12:36 am, Richard Newman wrote: >> Would anyone have any interest in a content negotiation library making >> its way into contrib? >> >> That is, a library with a public function that takes an Accept: header >> from an HTTP request, and your server-side preferences, and spits out >> which Content-Type you should produce. >> >> This is important for "proper REST" apps. (I don't see any >> functionality like this in Compojure.) >> >> I have one about 80% done (compared to one I wrote in Python). Pure >> Clojure; the only dependency is on str-utils. >> >> If there's no interest in it getting into contrib, I'll just stick it >> on GitHub. > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure Golf – Episode 2: Largest Prime Factor
What about a golf competition on the golf competition scorer? Then we can evaluate that using; (defmacro score-scorer [scorer] ... ) :) - Adrian On Thu, Sep 10, 2009 at 8:12 AM, Christophe Grand wrote: > > I propose to compute the score of a golf competition entry using this > function: > (defn score [expr] (count (tree-seq coll? #(if (map? %) (apply concat > %) (seq %)) expr))) > > Thus, shorter names and literal anonymous closures won't change the score. > > On Thu, Sep 10, 2009 at 1:50 AM, Timothy > Pratley wrote: >> >>> (zero? (rem % d)) >> (= 0 (rem % d)) >> >>> (- d 1) >> presumably you chose this instead of (dec d) because it converts one >> real character into whitespace >> >> so if you make this: >>> (inc d >> (+ d 1) >> You can convert another whitespace! [arguably its a meaningful >> whitespace but lets ignore that for now] >> >> Oh and you could call your function l instead of lpf :) >> Ok so I don't have any useful suggestion sorry... but interesting to >> read your post, That recur inside a lambda was cute! >> > >> > > > > -- > Professional: http://cgrand.net/ (fr) > On Clojure: http://clj-me.blogspot.com/ (en) > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Class function alwayrs returns java.lang.class??
You need to pass the object to (class, e.g... user=> (class "a") java.lang.String user=> (class String) java.lang.Class user=> (class 1) java.lang.Integer (So String is actually a Class object). Rgds, Adrian. On Thu, Sep 10, 2009 at 5:00 PM, Gorsal wrote: > > Hello. I'm trying to use (class String) to get the class object for > the String class. However, nomatter what class typ ei pass, i always > get java.lang.Class back. Is this the way its supposed to work? > > Thx! > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Issue with casting integers with clojure.lang.ifn's
Hi Jeff, you're using defn which defines a function instead of def which defines a var; (def vect1 [1 2 3 4]) #'user/vect1 user=> (* (count vect1) 5) 20 Rgds, Adrian. On Mon, Sep 14, 2009 at 8:05 AM, Jeff Gross wrote: > > I have a vector that I need to count the size of and do a simple math > calculation with. > Say for example: > (defn vect1 [1 2 3 4]) > > Typing (count vect1) returns the size of 4 that I need. I thought that > I could simply use (count vect1) in an a simple infix expression, ie: > (* (count vect1) 5) however, I get a class cast exception error > that the java.lang.integer cannot be cast to clojure.lang.ifn. How > would I go about doing this correctly? > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Issue with casting integers with clojure.lang.ifn's
Alternatively, if really meant to use defn then it should have been; (defn vect1 [] [1 2 3 4]) #'user/vect1 user=> (* (count (vect1)) 5) 20 On Mon, Sep 14, 2009 at 2:28 PM, Adrian Cuthbertson wrote: > Hi Jeff, you're using defn which defines a function instead of def > which defines a var; > > (def vect1 [1 2 3 4]) > #'user/vect1 > user=> (* (count vect1) 5) > 20 > > Rgds, Adrian. > > On Mon, Sep 14, 2009 at 8:05 AM, Jeff Gross wrote: >> >> I have a vector that I need to count the size of and do a simple math >> calculation with. >> Say for example: >> (defn vect1 [1 2 3 4]) >> >> Typing (count vect1) returns the size of 4 that I need. I thought that >> I could simply use (count vect1) in an a simple infix expression, ie: >> (* (count vect1) 5) however, I get a class cast exception error >> that the java.lang.integer cannot be cast to clojure.lang.ifn. How >> would I go about doing this correctly? >> >> >> >> > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: loop-recur for string handling
There's also re-split in str-utils in clojure.contrib; (use 'clojure.contrib.str-utils) (re-split #"\s" "The quick brown fox") => ("The" "quick" "brown" "fox") You can then use all the good clojure collection functions; (def words (re-split #"\s" "The quick brown fox")) (some #{"brown"} words) => "brown" (some #{"foo"} words) => nil (nth words 2) => "brown" (str-join "," words) => "The,quick,brown,fox" ..., etc. (There's also some good stuff in str-utils2 worth looking at). The "some" function above needs some explanation; It takes a predicate, applies it to each element of the collection and returns the first logical true (not nil) value if found otherwise nil. The #{"brown"} is a set containing "brown", but sets, like maps are a function of their elements, e.g; (#{"a" "b"} "b") => "b" and hence acts as a predicate for testing each element in words in the some function. There are also endless things you can do with map and reduce; (map (fn [w] (.toUpperCase w)) words) => ("THE" "QUICK" "BROWN" "FOX") same as; (map #(.toUpperCase %) words) => ("THE" "QUICK" "BROWN" "FOX") Say you wanted to encode a "record" of stems from a map of word/stem's; (let [stems {"the" :th "quick" :qk "brown" :br "fox" :fx}] (reduce (fn [rec x] (conj rec (stems (.toLowerCase x [] words)) => [:th :qk :br :fx] So then given that background and that you're looking for a clojure approach rather than a specific solution to your "brown" split example, lets elaborate on a possible approach; You could "abstract" the requirement to something like; "Given a collection and a predicate to find an element in that collection, return two collections - up to the split element and the remaining elements (including the split element)." (defn split-coll "Doc as above." [coll pred] (reduce (fn [[l r] x] (if-not (empty? r) [l (conj r x)] (if (pred x) [l [x]] [(conj l x) r]))) [[][]] coll)) (split-coll '(:a :b :c) #(= % :b)) => [:a] [:b :c]] (split-coll '(:a :b :c) #(= % :x)) => [[:a :b :c] []] (split-coll '(:a :b :c) #(= % :a)) => [[] [:a :b :c]] and of course; (split-coll words #(= % "brown")) => [["The" "quick"] ["brown" "fox"]] finally, you could create the specific sentence function; (defn split-sentence [sentence word] (split-coll (re-split #"\s" sentence) #{word})) (split-sentence "The quick brown fox" "brown") => [["The" "quick"] ["brown" "fox"]] and you can also use de-structuring to get exactly what you were originally looking for; (let [[l r] (split-sentence "The quick brown fox" "brown")] r) => ["brown" "fox"] To explain the above reduce function ; we start with two empty vectors in a vector [[][]] and then looping through the collection on each iteration that vector is passed to the fn as the first arg. We de-structure that into l and r for the left and right vectors. If r is not empty we've already found the element, so conj x into the r vector. Otherwise if x satisfies the pred, conj it to the r vector, else we haven't got there yet, so conj it to the l vector. For completeness, I should show a loop/recur alternative as this is a totally idiomatic clojure technique, but should be used for functional goals, not just trying to emulate imperative ways. (defn split-coll [coll pred] (loop [c coll [l r] [[][]]] (if (nil? (seq c)) [l r] (recur (next c) (let [x (first c)] (if (nil? c) [l r] (if-not (empty? r) [l (conj r x)] (if (pred x) [l [x]] [(conj l x) r] (split-coll words #(= % "brown")) => [["The" "quick"] ["brown" "fox"]] It is also important to master loop/recur as you can use this more easily than reduce for complex looping constructs, nested loops, performant techniques, etc. I hope that gives you a feel of the kinds of things you can do with functional idioms and clojure and also a general approach to functional programming. Takes a while to pickup all these tips but you'll never look back. Rgds, Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: java/scala oneliner
If y're Sco'ish... -> 59 (dotimes[i 4](println"Appy Birthdy"({2"D'r XXX"}i"To Ye"))) Appy Birthdy To Ye Appy Birthdy To Ye Appy Birthdy D'r XXX Appy Birthdy To Ye On Fri, Sep 18, 2009 at 6:35 AM, David Nolen wrote: > hiredman in the lead! > (dotimes[i 4](println"Happy Birthday"({2"Dear XXX"}i"To You"))) -> 63 > > On Fri, Sep 18, 2009 at 12:32 AM, Kevin Downey wrote: >> >> :( >> >> map is lazy, so you'll need to wrap it in doall >> >> (dotimes [i 4] (println "Happy Birthday" ({2 "Dear XXX"} i "To You"))) >> >> On Thu, Sep 17, 2009 at 9:17 PM, David Nolen >> wrote: >> > Actually to be fair, here's a Clojure version that uses as little >> > whitespace >> > as the Scala and Java ones do. >> > (map #(str"Happy Birthday "%)(assoc (vec (replicate 4"To You"))2"Dear >> > XXX")) >> > ; -> 76 chars >> > >> > On Fri, Sep 18, 2009 at 12:14 AM, David Nolen >> > wrote: >> >> >> >> Your basic approach seems sound: >> >> (map #(str "Happy Birthday " %) (assoc (vec (replicate 4 "To You")) 2 >> >> "Dear XXX") -> 81 chars including white space >> >> for(int i=0;i<4;i++){System.out.println("Happy Birthday "+(i==2?"Dear >> >> XXX":"To You"));}) -> 88 chars >> >> (1 to 4).map{i=>"Happy Birthday %s".format(if(i==3)"Dear XXX"else"To >> >> You")}.foreach{println(_)} -> 95 chars >> >> Anyone have a shorter version? :) >> >> On Thu, Sep 17, 2009 at 11:53 PM, Wilson MacGyver >> >> wrote: >> >>> >> >>> This blog post got me thinking. >> >>> http://www.artima.com/weblogs/viewpost.jsp?thread=268561 >> >>> >> >>> Basically it contains both a Java one liner and Scala one liner. >> >>> >> >>> Java: >> >>> for(int i=0; i<4; i++) { System.out.println("Happy Birthday " + (i==2 >> >>> ? "Dear XXX" : "To You")); } >> >>> >> >>> Scala: >> >>> (1 to 4).map { i => "Happy Birthday %s".format(if (i == 3) "Dear XXX" >> >>> else "To You") }.foreach { println(_) } >> >>> >> >>> the goal is to generate >> >>> >> >>> Happy Birthday To You >> >>> Happy Birthday To You >> >>> Happy Birthday Dear XXX >> >>> Happy Birthday To You >> >>> >> >>> >> >>> I started thinking about how to do this in clojure. My first reaction >> >>> was >> >>> to >> >>> think of the sentences as two sequences. Uses replicate to generate >> >>> them, and map str to join them from two collections. >> >>> >> >>> ie, (map str (replicate 4 "Happy Birthday ")... >> >>> >> >>> Is there a more "clojure" way to do it? >> >>> because using replicate to generate the 2nd sequence seem like >> >>> cheating. >> >>> ie, replicate 2 "To You", 1 "Dear XXX", and then "To You" again. >> >>> >> >>> >> >>> >> >>> -- >> >>> Omnem crede diem tibi diluxisse supremum. >> >>> >> >>> >> >> >> > >> > >> > > >> > >> >> >> >> -- >> And what is good, Phaedrus, >> And what is not good— >> Need we ask anyone to tell us these things? >> >> > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: "If you wish to have a version for off-line use...
Generally I use the source code for clojure and contrib documentation. I open an instance of Jedit on the source directory and use it's search/grep facilities to find what I'm looking for. It also helps in familiarising with the clojure and contrib implementations and learning the techniques used. It's also always available. (I use vim/vimclojure separately as my ide and jedit only for source/doc browsing). Rgds, Adrian. On Mon, Sep 21, 2009 at 12:37 AM, MarkSwanson wrote: > > Personally, that's not what I want. > > I want to download the clojure.org web page - one level deep so the > files api, special_forms, macros, etc. are all available on my laptop > offline. > I tried a couple of programs (wget and httrack) to get this but there > is some strange combobulation of redirects and cookie sessions going > on that prevented these from working (for me). > > If anyone knows an easy way to get this documentation available > offline please contribute. > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: re-sub / re-gsub with back-reference?
I was just trying out str-utils2 when Stuart posted. Here's an example; (require '[clojure.contrib.str-utils2 :as s]) (s/replace "hello Jung" #"hello (\S+)" #(str "hello, how are you "(% 1))) "hello, how are you Jung" Rgds, Adrian. On Tue, Sep 29, 2009 at 4:58 PM, Stuart Sierra wrote: > > Hi Jung, > > Look at clojure.contrib.str-utils2/replace -- you can pass a function > as the replacement parameter and make any substitutions you want. > > -SS > > > On Sep 28, 6:51 pm, Jung Ko wrote: >> Does anyone know how I can replace a string with back-reference? I'd >> like something like this: >> >> (use clojure.contrib.str-utils) >> (re-sub #"hello (\S+)" ", how are you \1?" "hello Jung") >> => "hello, how are you Jung?" >> >> Basically I need the back reference \1 to evaluate to "Jung" in the >> above case. Is there an easy way to do this? >> >> Thanks, >> Jung > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Using 'future' ?
The following seems to do it; (defmacro with-thread [nm & body] `(let [thread# (Thread. (fn [] (do ~...@body)))] (if ~nm (.setName thread# ~nm)) (.start thread#) thread#)) (with-thread "foo" (println "HasdfasdfasdfasdfasdfasdfasdfasdfI")) # user=> HasdfasdfasdfasdfasdfasdfasdfasdfI Also, macroexpand-1 really helps when writing macros. You can see exactly how it's being expanded and it's then somewhat easier to debug; (macroexpand-1 '(with-thread nil (println "HasdfasdfasdfasdfasdfasdfasdfasdfI")) (clojure.core/let [thread__112__auto__ (java.lang.Thread. (clojure.core/fn [] (do (println "HasdfasdfasdfasdfasdfasdfasdfasdfI"] (if nil (.setName thread__112__auto__ nil)) (.start thread__112__auto__) thread__112__auto__) Regards, Adrian. On Mon, Oct 19, 2009 at 6:39 AM, Gorsal wrote: > > So now that the future is working, I'm attempting to print from an > actual java thread. Like this > > (defmacro with-thread [nm & body] > `(let [thread# (Thread. #(fn [] (do ~...@body)))] > ~@(if nm `((.setName thread# ~nm))) > (.start thread#) > thread#)) > > (with-thread nil (println "HasdfasdfasdfasdfasdfasdfasdfasdfI")) > > Except no output! Eeek!!! What am i doing wrong? > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Using 'future' ?
Just an addendum to my last post - without the .start you can test it better; (defmacro with-thread [nm & body] `(let [thread# (Thread. (fn [] (do ~...@body)))] (if ~nm (.setName thread# ~nm)) ;(.start thread#) thread#)) (def th (with-thread "foo" (println "HasdfasdfasdfasdfasdfasdfasdfasdfI"))) (.start th) nil HasdfasdfasdfasdfasdfasdfasdfasdfI (.getName th) "foo" - Adrian. On Mon, Oct 19, 2009 at 7:18 AM, Adrian Cuthbertson wrote: > The following seems to do it; > > (defmacro with-thread [nm & body] > `(let [thread# (Thread. (fn [] (do ~...@body)))] > (if ~nm (.setName thread# ~nm)) > (.start thread#) > thread#)) > > (with-thread "foo" (println "HasdfasdfasdfasdfasdfasdfasdfasdfI")) > # > user=> HasdfasdfasdfasdfasdfasdfasdfasdfI > > Also, macroexpand-1 really helps when writing macros. You can see > exactly how it's being expanded and it's then somewhat easier to > debug; > > (macroexpand-1 '(with-thread nil (println > "HasdfasdfasdfasdfasdfasdfasdfasdfI")) > (clojure.core/let [thread__112__auto__ (java.lang.Thread. > (clojure.core/fn [] (do (println > "HasdfasdfasdfasdfasdfasdfasdfasdfI"] (if nil (.setName > thread__112__auto__ nil)) (.start thread__112__auto__) > thread__112__auto__) > > Regards, Adrian. > > On Mon, Oct 19, 2009 at 6:39 AM, Gorsal wrote: >> >> So now that the future is working, I'm attempting to print from an >> actual java thread. Like this >> >> (defmacro with-thread [nm & body] >> `(let [thread# (Thread. #(fn [] (do ~...@body)))] >> ~@(if nm `((.setName thread# ~nm))) >> (.start thread#) >> thread#)) >> >> (with-thread nil (println "HasdfasdfasdfasdfasdfasdfasdfasdfI")) >> >> Except no output! Eeek!!! What am i doing wrong? >> >> >> > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: idiom questions
> (let [x nil] > ;; do something and modify 'x' > ) > >how does one modify the value of 'x' ? Hi Chick, there's nothing stopping you re-binding x within the let construct, eg; (defn myfn [x] (let [x (if (or (nil? x) (< x 0.2)) 0.0 x) x (if (>= x 0.8) 1.0 x)] (do-something-with x))) That technique helps a lot of the times you think you need mutable variables. Nested lets are also useful. -Rgds, Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Another "closure" available
Hmm, someone else has made another "closure" available :). http://googlecode.blogspot.com/2009/11/introducing-closure-tools.html -Adrian. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: roll call of production use?
For a data analysis/reporting application, I use colt for some matrix processing, joda time for period calculations, jfreechart to generate charts, an adaptation clj-html to create some dynamic html, also now some StringTemplate templates to bring in and manipulate static content and finally all this (as html) gets fed into XhtmlRenderer to emit some beautiful css stylized PDF reports. Sounds like a mish-mash and it is, but clojure has allowed me to create all the right abstractions, manage the processing flows and build a complex application leveraging many powerful java libraries that would have just been too much effort (for me) to do in plain old java. The other spin-off of this is that using the repl, one is able to really explore the api's of these big libraries dynamically and get to know them much more intimately than when doing static compilation/run cycles as in the past. So, a major benefit for me of learning clojure has also been a substantial increase in my depth of knowledge of the workings of some of the excellent java libraries out there. - Adrian. On Tue, Nov 24, 2009 at 8:52 PM, RandyHudson wrote: > > > On Nov 24, 11:30 am, John Harrop wrote: > >> There's a Clojure or a Java library for generating pdf? > > Apache FOP is an XSL-FO processor than can generate PDF documents. > I've heard good things about iText, a Java library for generating or > modifying PDF docs. > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Clojure as a first programming language?
Hi Towle, Judging by the articulateness of your post, I would say that Clojure would definitely be an ideal language for what you are looking for. It is not "handed to you on a plate" and you will have to engage deeply to achieve your goals, but if you do so, along with the increasingly prolific documentation available, the archives of this forum and the on-going posts here, you will be able to learn and apply just about any technique that has ever been addressed regarding advanced programming, best computer science practices and very practical applications. - Regards, Adrian. On Tue, Dec 1, 2009 at 7:38 AM, Towle wrote: > Hi all, > > Thanks for taking the time to read my post. I'm interested to get some > opinions from experienced Clojure programmers on whether the language > would be a good first language to learn, or rather to learn in-depth. > I have minimal experienced with more common languages like Java, HTML, > and C++, but having the personality I do, felt compelled to shop > around a bit before choosing a first language to learn seriously on a > deep and intuitive level-- perhaps my odd notion of there being a > connection between a programmer and the first language s/he > understands on that high of a level. So after shopping around > thoroughly and picking up bits about on theoretical computer science > and the history of programming languages, I decided to pick up a Lisp; > I'm intrigued by the greater concept/idea behind the Lisp family of > languages. > > After a long while trying to figure out which of the Lisps would be a > good first choice, I stumbled across Clojure and immediately thought > it a brilliant idea, conceding of course that at my current level of > knowledge, I likely have no idea what a brilliant idea in computer > programming looks like. Regardless, it still feels brilliant. > > As I see it, among other features of the language, the idea of a Lisp > designed to be a capable choice for "real-world" code applications, > that is a Lisp which embodies the spirit of that family of languages > yet one which resolves many of the "practicality" complaints which > stand as hurdles on a Lisp's path to real-world use. For my situation, > that of a student who wants both a) to learn a first language I can > have a real, intellectual appreciation for and b) to begin the journey > to "expertise" in a language it would be practical to code web > applications in. > > So, Clojure programmers, am I wrong? Should I pass on Clojure in favor > of another langauge? Or learn Common Lisp or Scheme first, then try my > hand at Clojure? Am I mistaken for a different reason? Or perhaps > there are some criteria I should consider before diving in? > > Thanks in advance, and again for taking the time to read. > --Towle > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en