Re: ANN: clojure.contrib.error-kit
So far this is fantastic! And I haven't even got around to playing with the restart mechanism :) I'm using it in Spinoza to provide contextual errors (malformed slot list, missing base class etc.). I notice the contrib libraries in general are very good at throwing exceptions so that consumers have some idea of what is going on. error-kit one ups this practice by providing a standardized way to define your errors up front and presents a definition system that removes the need to instantiate ugly Java Exceptions inline with your code. (defn protocol-fn [protocol-name fn-name] (let [protocol-keyword (symbol-to-keyword protocol-name) dispatch (partial protocol-dispatch protocol-keyword)] `(do (defmulti ~fn-name ~dispatch) (defmethod ~fn-name [:spinoza/object nil] [~'obj] (raise *missing-protocol-method-error* ~'obj ~(str protocol-name) ~(str fn-name)) Where the error is defined as you've described: (deferror *missing-protocol-method-error* [*spinoza-error*] [obj protocol-name method-name] {:msg (str (:tag obj) class does not implement method-name from protocol protocol-name)}) Sweet! That said I do have one minor annoyance and that is the need to leave an empty bracket if you want to create a new error without inheriting from a previously defined error. Very minor. Will provide feedback on restarts when I get there. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Generic functions: things, models, and protocols revisited
Neat! You've removed the need to even define a dispatch-fn. I'll need to chew on this for a bit (I'm a little slow :) I'm still working on my attempt at implementing protocols, but I'm not totally clear on where it will go or how useful it will be. Seems like this kind of dispatch and the Datalog project might meet up soon? Or am I totally wrong? On Thu, Feb 12, 2009 at 12:02 PM, mikel mev...@mac.com wrote: David Nolen and I were recently discussing CLOS and method dispatch. I implemented such a scheme for my own use. This post is an FYI for David and anyone else who might be interested in generic functions and predicate dispatch. Here's a transcript of a sample session in which I exercise the dispatch cases: (def $gf (make-generic-function)) (add-gf-method $gf [nil] (fn [x] (str found value: (.toString x) of type: (.toString (class x) (add-gf-method $gf [java.lang.Number] (fn [x] (+ x 1))) (add-gf-method $gf [java.lang.String] (fn [x] (str Found string: x))) (add-gf-method $gf [{:equals 5}] (fn [x] (str Found 5!))) (add-gf-method $gf [{:model {:name nil}}] (fn [x] (str Found a thing whose name is (:name x (add-gf-method $gf [java.lang.Number java.lang.Number] (fn [x y] (+ x y))) (add-gf-method $gf [java.lang.String java.lang.String] (fn [x y] (str x y))) (add-gf-method $gf [java.lang.String java.lang.Integer] (fn [s i] (apply str (take i (cycle [s]) (add-gf-method $gf [{:test (fn [x] (= x swordfish))}] (fn [s] (str You said the secret word, you win a hundred dollars!))) user ($gf hello world) hello world user ($gf 2 3) 5 user ($gf {:name Barney}) Found a thing whose name is Barney user ($gf 5) Found 5! user ($gf bananas) Found string: bananas user ($gf 100) 101 user ($gf 'some-symbol) found value: some-symbol of type: class clojure.lang.Symbol user ($gf foo 5) foofoofoofoofoo user ($gf swordfish) You said the secret word, you win a hundred dollars! It works well enough to produce that transcript, but is very preliminary. I'm sure there are bugs I haven't noticed yet, and no doubt it's terribly slow. For one thing, I know it's doing a lot of redundant comparisons at the moment. It's missing a number of amenities and at least one important feature: next-method is not yet implemented. When called, a generic function matches the arguments it received against formal parameters in its dispatch table. Matching of a formal parameter works like so: nil: match any value passed in this position a Java class: match any value that is an instance of the class (or of a subclass of it) a Map of the form: {:model m}: match any value v for which (model? v m) returns true a Map of the form {:equals x}: match any value v for which (= v x) returns true a Map of the form {:test f}: match any value for which (f x) returns true Calling ($gf 2 3) or whatever works because the object in $gf is a closure: (defn make-generic-function [ [dispatch-table]] (let [dt-ref (or dispatch-table (ref {}))] (fn [ args] (apply-generic-function dt-ref args There's a little trickery with sentinel values and metadata to enable me to provide an API for adding and removing methods, which are stored in the dispatch-table created in make-generic-function. It would be nice to make that code a little less clever, but that would require a convenient way to create a new kind of callable object; I'd need to be able to define what happens when it's applied. Now we'll see if this thing is useful enough to make it better. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Newbie at macros: Manipulating a vector of bindings
You can pretty much call anything outside of the quote, in fact all runtime information is available (you have access to anything that was previously read). The main thing to understand is that all parameters passed to your macro are unevaluated. On Sat, Feb 14, 2009 at 10:45 AM, samppi rbysam...@gmail.com wrote: Thank you so much. I'm confused, however, about what functions you're allowed to call inside a macro outside of a quote. I read once that runtime information was unavailable during the macro phase. But it seems that one is still allowed to call array-map, apply, take-nth, and vec during the macro phase. What is the pattern for what is allowed or prohibited in macros? On Feb 13, 10:52 pm, Chouser chou...@gmail.com wrote: On Fri, Feb 13, 2009 at 11:17 PM, samppi rbysam...@gmail.com wrote: I'm trying to write a macro that expands from this: (product-context [n rule0, m rule1)] (rule-maker2 (+ n m)) rule3)) Into this (assume that conc-fn and conc-products are functions): (fn [tokens] (if-let [[remainder# n m] (conc-products [rule0 rule1] tokens)] (conc-fn [(rule-maker2 (+ n m)) rule3] remainder#))) ...but I can't figure out how to change [n rule0 m rule1] to (if-let [[remainder# n m] (conc-products [rule0 rule1] tokens)] ...). Try working it out outside of the macro context. (def bindvec '[n rule0, m rule1]) Now you've got something to work with. There are plenty of acceptible answers. Maybe you want to think of the vector as key/value pairs: (apply array-map bindvec) == {n rule0, m rule1} (keys (apply array-map bindvec)) == (n m) (vals (apply array-map bindvec)) == (rule0 rule1) Or just use some seq function: (take-nth 2 bindvec) == (n m) (take-nth 2 (rest bindvec)) == (rule0 rule1) Once you've got the pieces you need, try sticking them into a syntax-quote: user= `(if-let [[r# ~(take-nth 2 bindvec)] (cp ~(take-nth 2 (rest bindvec)))] ...) (clojure.core/if-let [[r__215__auto__ (n m)] (user/cp (rule0 rule1))] ...) Well, that's close by there are extra parens around (n m) and you want a vector not a list for the rules. So play with it until it looks right: user= `(if-let [[r# ~@(take-nth 2 bindvec)] (cp ~(vec (take-nth 2 (rest bindvec] ...) (clojure.core/if-let [[r__219__auto__ n m] (user/cp [rule0 rule1])] ...) Then you're ready to build the macro: (defmacro product-context [bindvec body] `(fn [tokens#] (if-let [[remainder# ~@(take-nth 2 bindvec)] (conc-products [~@(take-nth 2 (rest bindvec))] tokens#)] (conc-fn [...@body] remainder# --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Newbie: Separating and grouping the elements in a bunch of vectors
(map (fn [ rest] (apply vector rest)) [1 2 3] ['a 'b 'c] [cat dog bird]) On Sun, Feb 15, 2009 at 7:16 PM, samppi rbysam...@gmail.com wrote: What would I do if I wanted this: [[a0 a1 a2] [b0 b1 b2] ...] - [[a0 b0 ...] [a1 b1 ...] [a2 b2 ...]] I could write a loop, I guess, but is there a nice, idiomatic, functional way of doing this? I didn't spot a way in clojure.contrib.seq-utils 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: Newbie: Separating and grouping the elements in a bunch of vectors
Actually something closer to your exact expression is this: (apply (partial map (fn [ rest] (apply vector rest))) [[1 2 3] ['a 'b 'c] [cat dog bird]]) On Sun, Feb 15, 2009 at 7:42 PM, David Nolen dnolen.li...@gmail.com wrote: (map (fn [ rest] (apply vector rest)) [1 2 3] ['a 'b 'c] [cat dog bird]) On Sun, Feb 15, 2009 at 7:16 PM, samppi rbysam...@gmail.com wrote: What would I do if I wanted this: [[a0 a1 a2] [b0 b1 b2] ...] - [[a0 b0 ...] [a1 b1 ...] [a2 b2 ...]] I could write a loop, I guess, but is there a nice, idiomatic, functional way of doing this? I didn't spot a way in clojure.contrib.seq-utils 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: ANN: clojure.contrib.error-kit
Would it be possible to make the arguments to handle be optional? Is this a good or bad idea? It seems to me, in the case of setting up test fixtures that check for raised errors, often you don't care what arguments the error takes. David On Fri, Feb 6, 2009 at 9:10 PM, Chouser chou...@gmail.com wrote: (kit/with-handler (vec (map int-half [2 4 5 8])) (kit/handle *odd-number-error* [n] (throw (Exception. (format Odd number %d in vector. n) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Newbie: Separating and grouping the elements in a bunch of vectors
I'm sure it can be done, but it's not clear to me if you have a vector of vectors how Stuart's solution would work: 1:15 user= (map vector vecs) ([[:a0 :a1 :a2]] [[:b0 :b1 :b2]]) (apply (partial map vector) [[1 2 3] ['a 'b 'c] [cat dog bird]]) works on a vector of vectors. The OP wanted a vector of vectors as a result where the subvector length is the same as the number of vectors originally passed in. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: error-kit + test-is
(defmethod assert-expr 'raised? [msg form] (let [error-type (second form) error-meta (meta (find-var (qualify-sym error-type))) error-str (str (ns-name (:ns error-meta)) / (:name error-meta)) body (rrest form)] `(with-handler (do ~...@body (report :fail ~msg '~form (str ~error-str not raised.))) (handle ~error-type {:as err#} (if (= (:tag err#) (symbol ~error-str)) (report :pass ~msg '~form nil) (report :fail ~msg '~form (str ~error-str was raised. (handle *error* {:as err#} (report :fail ~msg '~form (:tag err#)) Here is the macro that seems to work, any improvements much appreciated ;) This fails when no error is raised, when the wrong error type is raised, and I believe it's captures errors which are derived but not the exact error (is this a weird behavior?). Your previous post about error-kit got me on the right track. I can now define test cases like so: (deftest test-verify-slots (is (verify-slots [[:origin [0 0]] :width :height])) (is (raised? *malformed-slots-error* (verify-slots [[:origin] :width :height]))) (is (raised? *malformed-slots-error* (verify-slots [[:origin 0 0] :width :height]))) Much nicer than those ugly Java Exceptions, no? ;) On a last note, I've found your qualify-sym fn quite handy and have been using it elsewhere ;) On Sun, Feb 15, 2009 at 11:52 PM, Chouser chou...@gmail.com wrote: On Sun, Feb 15, 2009 at 10:06 PM, David Nolen dnolen.li...@gmail.com wrote: I've been attempting to combine error-kit and test-is, but getting the relation between assert-expr form in test-is and the handle form in error-kit is a bit tricky. Looking at the test-is thrown? example and Chouser's error-kit post on the mailing list I tried something like the following: (defmethod assert-expr 'raised? [msg form] (let [error-type (second form) body (rrest form)] `(with-handler (do ~...@body (report :fail ~msg '~form nil)) (handle {:keys [ rest#]} (let [tag# (last rest#)] (println raised! rest# ~error-type) (if (= ~error-type tag#) (report :pass ~msg '~form nil) (report :fail ~msg '~form nil))) The assert-expr seems OK, but I can't seem to get the error-type tag from handle. So here's the promised feedback on handle Chouser ;) Thanks! You're a brave man for trying such a thing, when error-kit has such thin documentation. I think there are a couple problems. One is your attempt at using in a :keys destructuring expression. It amounts to something like: (let [{:keys [ etc]} {:a 1, :b 2}] etc) - nil You may want to use {:as err-map#} instead, and then pick out the :tag from the err-map# later. Or perhaps simply insert the ~error-type there directly. Another issue is that what is stored in the err-map's :tag value is the fully-qualified symbol of the error, not the value of that symbol (which happens to be the fn used to construct it) which is what your ~error-type would evaluate to. I know it's confusing, but it's how it had to be, since I need the name and functions don't really have names. To make things worse, getting the fully-qualified name from the macro argument, which is likely a symbol with a nil namespace, is a bit of a trick. error-kit/qualify-sym does this, but it's currently private. It may make sense to make that public for just the kind of shenanigans you're trying to pull. If this has been to dense or sketchy, let me know and I'll see if I can help you further. This is exactly the kind of thing error-kit needs to be able to do. --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: error-kit + test-is
Heh not macro, I meant multimethod. Here is the macro that seems to work, any improvements much appreciated ;) This fails when no error is raised, when the wrong error type is raised, and I believe it's captures errors which are derived but not the exact error (is this a weird behavior?). Your previous post about error-kit got me on the right track. I can now define test cases like so: --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: error-kit + test-is
I don't quite understand why you got through all that work to get error-str -- isn't it just (str (qualify-sym error-type))? ...and since you then use it only as an arg to 'symbol' or 'str', you could just use the symbol itself instead of converting it to a string and back. If I bring the symbol back directly, it gets evaluated to the actual error object and not the symbol. I want to compare symbols. Or maybe I don't, comparing symbols in general seems simpler for meta-hacky stuff like this. This fails when no error is raised, when the wrong error type is raised, and I believe it's captures errors which are derived but not the exact error (is this a weird behavior?). I'm not sure, but I think you'd want to allow an implementation to change to a derived error type without breaking the tests. But I could be wrong -- it should probably behave the same as the 'throws?' method, since Java Exceptions also do inheritance. Good point. Easy enuf. Much nicer than those ugly Java Exceptions, no? ;) Sure, looks good to me. Would it ever be useful to test that the error has a particular set of arguments? I guess that may be more detailed than any test would want to get. Possibly, but I can't think of a really goo reason for this yet. It would also be interesting to try to test for the existence and behavior of any 'continue' forms. Very interesting, I haven't got to continue yet, baby steps here. Really!? I'd never needed it before error-kit, and I'm pretty suspicious of needing it even there. I think I'd rather just use Vars for error tags, but they're not currently allowed in the Clojure inheritance hierarchies. If Vars were Named, I think it would work, and it's not at all clear to me why they aren't, since they have a namespace and a name just like symbols and keywords do. Rich is probably too busy with lazier just now, but I intend to be annoying about this at some later date. That's the proper solution. Until then for really wacky stuff, I don't know how to do certain things without qualify-sym. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Fully lazy sequences are coming - feedback wanted!
butlast, doall, dorun, doseq, dosync, dotimes, doto, fnseq, gensym, macroexpand, macroexpand-1, mapcat, nthrest -1 Because they are similar to other Lisps I assume. The same reason for println vs print-line. Changing these are a bad idea in IMHO. Breaking the meaning of rest with Common Lisp is a consideration to take seriously. However as long as the documentation clearly states (highlights in big bold colors ;) this difference (and the fact the operation is support by next) then I think this is a change people can live with. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: compiling a GUI app and also: interference of Java's built-in architechture
On Mon, Feb 16, 2009 at 10:27 AM, rob levy r.p.l...@gmail.com wrote: So if I am right about these two facts, it seems like Clojure should include a native way of making applets/applications that both enables the truly functional style that Clojure is built on, and doesn't require writing Java to call it (it seems like Clojure should replace Java, not perpetuate it, other than to build on its vast libraries, IMHO). What do you think (and is there something I'm understanding wrong here)? Someone correct me if I'm way off, but User Interfaces are by definition very mutation heavy. It has come up before that Clojure's emphasis on immutability is a tool not a religious decree. Mutation is fine, just don't mindlessly sprinkle it all over your program. Even a language like Haskell (which I know very little about) needs special constructs for IO. But this is exactly what your example illustrates! mouse - I, screen - O. Mutability sneaks in ;) Of course it would be interesting to see a UI framework that is more functional, but having done a considerable amount of UI programming this seems to me like mostly a waste of time. Instead of dictating, Clojure simply encourages you to reflect on whether you really need mutation. If you absolutely need mutation, Clojure isn't going to stop you. And that's a great thing. David --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: error-kit + test-is
(defmethod assert-expr 'raised? [msg [_ error-type body :as form]] (let [error-name (qualify-sym error-type)] `(with-handler (do ~...@body (report :fail ~msg '~form ~(str error-name not raised.))) (handle ~error-type {:as err#} (report :pass ~msg '~form nil)) (handle *error* {:as err#} (report :fail ~msg '~form (:tag err#)) You're right I think the entire first handle statement was wrong. I believe handle does the isa? check on the error type, correct? If so then this will allow inherited error types to pass the test. Many, many thanks for the feedback. test-is + error-kit is a great combo. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 Way to Write the Following:
Is using subvec for something like this a bad idea? On Wed, Feb 18, 2009 at 12:38 AM, CuppoJava patrickli_2...@hotmail.comwrote: Hi, I'm wondering if there's a terser more idiomatic way to write the following. I want to get a new vector with the specified indexes removed. I found myself doing this often enough to warrant writing my own function for this but I would be much happier if there's some terse way of expressing this using the standard clojure functions. (defn remove_at [coll indexes] (map second (remove #(some #{(first %)} indexes) (map vector (iterate inc 0) coll Thanks a lot -Patrick --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 of (fn [] ...)?
new MBP 2.53ghz (defn create-fn [] (fn [] (println hi))) (time (dotimes [x 4000] (create-fn))) Elapsed time: 1034.409 msecs Hopefully you don't need 40,000,000 functions in less than a second ;) On Wed, Feb 18, 2009 at 1:16 AM, CuppoJava patrickli_2...@hotmail.comwrote: (defn create_fn [] (fn [] (println hi))) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 Way to Write the Following:
My point was that you could use subvec to do vector splicing and build your remove function off of that. I'm sure the more experienced Clojurians can chime in on what is the most idiomatic form. On Wed, Feb 18, 2009 at 1:10 AM, CuppoJava patrickli_2...@hotmail.comwrote: Mmm, subvec doesn't quite seem to do the same thing. I want a function that removes certain indexes of a vector: eg. (remove_at [1 2 3 4 5 6] 0 3) = [2 3 5 6] --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 learn clojure ?
Practical Common Lisp is also online and free. Though there are significant differences between the two languages many of the strange and beautiful concepts that Clojure embraces are covered there. Especially dynamic variables, macros, destructuring bind, and multiple dispatch. On Wed, Feb 18, 2009 at 7:53 AM, MarisO maris.orbid...@gmail.com wrote: All documentation I've seen about clojure assumes knowledge of lisp which I dont have. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: bug affecting clojure.core/bean?
If I've been following things correct: rest _used_ to force the seq, it does no longer. next forces the seq In my own mind i'm thinking next to mean (return the seq with the next value computed), rest now means just give me the uncomputed remaining values of the seq. On Wed, Feb 18, 2009 at 12:00 PM, Laurent PETIT laurent.pe...@gmail.comwrote: 2009/2/18 Mark Volkmann r.mark.volkm...@gmail.com On Wed, Feb 18, 2009 at 10:27 AM, Rich Hickey richhic...@gmail.com wrote: On Feb 18, 11:04 am, Chouser chou...@gmail.com wrote: On Wed, Feb 18, 2009 at 12:35 AM, Rob rob.nikan...@gmail.com wrote: I'm wondering if I found a bug. I have the latest source from svn (r1291). user= (bean 1) java.lang.IllegalArgumentException: Wrong number of args passed to: core$bean--5161$fn--5179$thisfn You sure did. The conversion to lazy-seq code appears to introduce a paren typo and an incorrect nil pun. Patch attached. Patch applied, svn 1293 - thanks! Rich, I think it'd be pretty useful to have as you mentioned in IRC a variant of destructuring that provided an unforced lazy-seq. It seems pretty common to want, in the body of a lazy-seq, a destructured 'first' but an unforced 'rest'. This is already the third or fourth time I've wanted to be able to do something like: (fn thisfn [plseq] (lazy-seq (when-let [[pkey rest etc] plseq] (cons (new clojure.lang.MapEntry pkey (v pkey)) (thisfn etc) Yes, sure. It just comes down to the name: rest others? Of those I prefer rest because its meaning is more explicit. Maybe I miss the point totally, but didn't the recent change give the function 'next the meaning of not forcing the seq ? So next instead of rest ? ... and maybe either rest or next , and not just anymore ? -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: how to learn clojure ?
Of course I beg to differ. The Stuart Halloway's book is fantastic of course, I have it myself. It's absolutely required reading. Stuart does his best to describe the ins and outs of the language while giving a crash course on the Lisp philosophy. And yes Clojure is syntactically different from Scheme and Common Lisp, however many of the non-Clojure texts suggested do a better job explaining the deeper why's of Lisp programming, concepts that go beyond the particular implementation. In fact I would probably recommend the Structure and Interpretation of Computer Programs as the indispensable Lisp text above all others. But thats just MHO. David On Thu, Feb 19, 2009 at 8:46 AM, Rayne disciplera...@gmail.com wrote: Telling someone to read a book that isn't even focused on the language he's trying to learn isn't a great way to help them. Tell him to read Programming Clojure or something, anything but Common Lisp and Scheme books, he isn't learning those languages he's learning Clojure. There is enough information around on Clojure that someone shouldn't be forced to read a book on a completely different language. No offense guys. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 learn clojure ?
No offense here to Lispers but when I learn a new language, I try to learn it as it is and I make parallels and connections with what I know at the moment. Otherwise you end up learning more than one thing at the same time and it can get quite confusing. If your experience is made mostly of conventional languages this path should be easier. After that if you are curious you can give a closer look to the Lisp heritage. Luc No arguments with most of what you say of course. However I'm not sure what I used to know from conventional languages helps much with concepts like macros or dynamic vars or multimethods. In fact most of my time learning Lisp has been like Holy ! If only I had this tool/concept 4 years ago! I've been swindled! ;) David --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: how to learn clojure ?
Great list. On Thu, Feb 19, 2009 at 11:39 AM, Stuart Halloway stuart.hallo...@gmail.com wrote: Thanks for the kind words, David. I hope many people will like Programming Clojure and find it useful. Clojure has a *ton* of goodness in it. I think many of the chapters in Programming Clojure book could usefully be followed with an entire book. Here is a partial list of recommendations for companion reading: For Java Interop: * The JVM spec (free online). Know your platform. :-) For Functional Programming: * Real World Haskell (free online) For Concurrency: * Java Concurrency in Practice For Macros: * On Lisp (free online) For Lisp in General: * Practical Common Lisp (free online) * Paradigms of AI Programming For Multimethods: * The Art of the Metaobject Protocol Just Because: * Structure and Interpretation of Computer Programs Cheers, Stuart Of course I beg to differ. The Stuart Halloway's book is fantastic of course, I have it myself. It's absolutely required reading. Stuart does his best to describe the ins and outs of the language while giving a crash course on the Lisp philosophy. And yes Clojure is syntactically different from Scheme and Common Lisp, however many of the non-Clojure texts suggested do a better job explaining the deeper why's of Lisp programming, concepts that go beyond the particular implementation. In fact I would probably recommend the Structure and Interpretation of Computer Programs as the indispensable Lisp text above all others. But thats just MHO. David On Thu, Feb 19, 2009 at 8:46 AM, Rayne disciplera...@gmail.com wrote: Telling someone to read a book that isn't even focused on the language he's trying to learn isn't a great way to help them. Tell him to read Programming Clojure or something, anything but Common Lisp and Scheme books, he isn't learning those languages he's learning Clojure. There is enough information around on Clojure that someone shouldn't be forced to read a book on a completely different language. No offense guys. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Error Handling paradigms in Clojure
Check out Chouser's error-kit in clojure-contrib. It borrows from the condition/restart system of Common Lisp. On Thu, Feb 19, 2009 at 5:25 PM, levand luke.vanderh...@gmail.com wrote: So, my project is reaching a sufficient level of complexity where I really need good error tracking - when something goes wrong, I need to know exactly what it was. I have programmed in Java for a long time, and my first instinct is to simply use the try and throw special forms more or less as I would in Java, even though the code in question is mostly pure Clojure without directly utilizing any Java classes. I would simply throw whenever I have an unexpected condition, and somewhere higher up the stack, where it is easy to deal with it, I would log it and either try to recover or present an error message. However, in most other areas, once I've finally grokked the functional practice for just about anything, I much prefer it to the Java way of life. So, I guess my question is, is using try/throw this way in Clojure considered good Clojure code, or are they there mostly for Java interop? Is there a more Lispy/functional way to do it? Many thanks, -Luke --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: structmap instance test
This not hard to implement. This exactly what Spinoza does. Feel free to lift any of my code. On Sat, Feb 21, 2009 at 9:08 AM, Mark Volkmann r.mark.volkm...@gmail.comwrote: Is there a way to test whether a given object is an instance of a given structmap? For example, (defstruct dog-struct :name :breed) (def my-dog (struct dog-struct Dasher whippet)) (when (some-function my-dog dog-struct) (println It's a dog!)) -- 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: structmap instance test
For example, with Spinoza: (def my-circle (make-instance circle)) (instance-of? my-circle circle) ; true circle is just a struct. On Sat, Feb 21, 2009 at 2:09 PM, David Nolen dnolen.li...@gmail.com wrote: This not hard to implement. This exactly what Spinoza does. Feel free to lift any of my code. On Sat, Feb 21, 2009 at 9:08 AM, Mark Volkmann r.mark.volkm...@gmail.comwrote: Is there a way to test whether a given object is an instance of a given structmap? For example, (defstruct dog-struct :name :breed) (def my-dog (struct dog-struct Dasher whippet)) (when (some-function my-dog dog-struct) (println It's a dog!)) -- 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: generic functions update
I'm interested as well. On Sat, Feb 21, 2009 at 3:03 PM, Dan Larkin d...@danlarkin.org wrote: On Feb 21, 2009, at 2:23 PM, mikel wrote: If there's interest in having models and generic functions in contrib, I'll get a contributor agreement to Rich. Aye there is, from me at least. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 Naming Conventions
+name+ is also in line with Common Lisp patterns http://www.cliki.net/Naming%20conventions On Sat, Feb 21, 2009 at 4:07 PM, Luc Prefontaine lprefonta...@softaddicts.ca wrote: In our software, we use uppercase or +name+ as constant names. Both Java and RUBY use uppercase, I think it's more a matter of taste what you decide to use. Ideally it should be obvious by looking at the name that some name is a constant name. Both of the above satisfy this criteria. Luc On Sat, 2009-02-21 at 12:47 -0800, Howard Lewis Ship wrote: I'm kind of used to Java nowadays, where CONSTANTS_ARE_UPPERCASE. I'mtrying to figure out if Clojure has equivalent conventions. What I've seen: names-with-dashes instead of CamelCase*global* for global variables (?)Parameter name conventions (from Stu's book): val, coll, a, etc. What are the accepted conventions? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 Naming Conventions
The fact that the Clojure data structures are immutable and that some of those data structures might be used logically constants are two separate concerns. When reading Clojure code, we've already internalized the fact that the data structures are immutable. Using a naming convention for a constant just simply marks clearly the intended use. On Sat, Feb 21, 2009 at 4:29 PM, Phil Hagelberg p...@hagelb.org wrote: Mark Volkmann r.mark.volkm...@gmail.com writes: As best I can tell Clojure doesn't have a convention for constant names. Everything that's not expected to be rebound at runtime (*special-variables*) is by definition a constant (with the exception of refs, agents, and atoms). You don't need a special constant naming convention. Perhaps some kind of convention for naming non-constants would be more appropriate since they're the exception rather than the rule, but I don't know of any such convention. The fact that those identifiers are always prefixed with @ for deref'ing them may be enough. -Phil --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: dotimes suggestion
(defmacro again [n body] `(dotimes [~'_ ~n] ~...@body)) (again 3 (println Ho)) On Sat, Feb 21, 2009 at 5:51 PM, samppi rbysam...@gmail.com wrote: For now, I do: (dotimes [_ 3] (print Ho)) But I also think it would be a nice, natural addition. On Feb 21, 3:07 pm, Timothy Pratley timothyprat...@gmail.com wrote: +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 To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: arguments to dissoc and select-keys
dissoc is like assoc. If you want to use collections with dissoc you can always use apply. It's not too much to type: (def my-map {:first Bob, :middle Joe, :last Smith}) (apply dissoc my-map [:first :middle]) On Sat, Feb 21, 2009 at 5:58 PM, samppi rbysam...@gmail.com wrote: Allowing dissoc and select-keys to accept both keys as arguments and as a collection would be nice, and backwards compatible. In any case, ostensibly it should be consistent; otherwise, it's just an idiosyncrasy in the language that people will have to deal with. I wonder what the reasoning is behind it, or if it was completely arbitrary. On Feb 21, 1:28 pm, Mark Volkmann r.mark.volkm...@gmail.com wrote: (def popsicle-map {:red :cherry, :green :apple, :purple :grape}) ; Note how the keys passed to dissoc are individual arguments. (dissoc popsicle-map :green :blue) ; - {:red :cherry, :purple :grape} ; Note how the keys passed to select-keys are in a vector, not individual arguments. (select-keys popsicle-map [:red :green :blue]) ; - {:green :apple, :red :cherry} I wonder why these were implemented differently. Maybe both dissoc and select-keys should accept both individual key arguments and a sequence of keys. -- 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: arguments to dissoc and select-keys
Oops, sorry. It seems weird to me that a function called select-keys would take a single parameter and not a vector. Also, as you said, this does seem like it would require some kind of check which would probably not worth the tradeoff. Why not write a function called select-key that does what you want? On Sat, Feb 21, 2009 at 6:24 PM, Mark Volkmann r.mark.volkm...@gmail.comwrote: On Sat, Feb 21, 2009 at 5:07 PM, David Nolen dnolen.li...@gmail.com wrote: dissoc is like assoc. If you want to use collections with dissoc you can always use apply. It's not too much to type: (def my-map {:first Bob, :middle Joe, :last Smith}) (apply dissoc my-map [:first :middle]) I think you misunderstood what I want. I want to be able to pass individual keys to select-keys. I'm not looking for a way to pass collections of keys to dissoc and assoc. My guess is that this inconsistency was purely accidental and could be fixed so select-keys also accepts individual key arguments. On Sat, Feb 21, 2009 at 5:58 PM, samppi rbysam...@gmail.com wrote: Allowing dissoc and select-keys to accept both keys as arguments and as a collection would be nice, and backwards compatible. In any case, ostensibly it should be consistent; otherwise, it's just an idiosyncrasy in the language that people will have to deal with. I wonder what the reasoning is behind it, or if it was completely arbitrary. On Feb 21, 1:28 pm, Mark Volkmann r.mark.volkm...@gmail.com wrote: (def popsicle-map {:red :cherry, :green :apple, :purple :grape}) ; Note how the keys passed to dissoc are individual arguments. (dissoc popsicle-map :green :blue) ; - {:red :cherry, :purple :grape} ; Note how the keys passed to select-keys are in a vector, not individual arguments. (select-keys popsicle-map [:red :green :blue]) ; - {:green :apple, :red :cherry} I wonder why these were implemented differently. Maybe both dissoc and select-keys should accept both individual key arguments and a sequence of keys. -- 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: arguments to dissoc and select-keys
On Feb 21, 5:58 pm, samppi rbysam...@gmail.com wrote: Allowing dissoc and select-keys to accept both keys as arguments and as a collection would be nice, and backwards compatible. Nope - Collections can be keys. Ah the power of Clojure ;) The fact that (almost?) anything can be a key is a pretty liberating thing. David --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure Naming Conventions
Thanks for the points. What I was thinking, was that for things like π, in Clojure (as in CL), perhaps it makes to sense to mark it like so: +pi+ On Sat, Feb 21, 2009 at 8:59 PM, Chouser chou...@gmail.com wrote: On Sat, Feb 21, 2009 at 5:36 PM, David Nolen dnolen.li...@gmail.com wrote: My point is simply that whether something is immutable or not has nothing to do with how that data structure is being used in the program. Naming conventions signify usage. You could write a pure Java program and make it pretty darn functional. You would still want to mark values that are logically treated as constants as such. Most named Vars are given a single value and this is never changed at all. They are created with 'def' or some variation thereof, and then examined in various ways, but not given new values. They are constant and they are named in the normal Clojure way: lowercase with dashes. Sometimes these Vars are changed later with another 'def', but this is meant to be a development or debugging technique, not something that should be incorporated into normal program logic. Anticipating this kind of change (or not) shouldn't influence the name of the Var. Some named Vars are expected to be given a thread-local value with 'binding', and in even more rare cases then adjusted using 'set!'. This usage is unusual enough that the names of such Vars warrant the *earmuffs*. Even less commonly than any of the above is changing a Var's root value with 'alter-var-root'. This is perhaps unusual enough that it warrants a naming convention to indicate that this particular Var will actually be non-constant at its root. Is there some other distinction that needs to be made? Does logically constant mean something different from what I've described above? --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: dotimes suggestion
In general, I find that multiple arguments types for a function confusing. If dotimes is going to take multiple types it should be a multifn. That seems to imply a performance hit. I think Clojure wisely does not (or rarely does not?) allow for multiple types to be passed into a function. On top of that it's trivial to produce a macro on top of dotimes that does what you want that doesn't spend time checking the type of it's argument. On Sat, Feb 21, 2009 at 11:10 PM, Mark Volkmann r.mark.volkm...@gmail.comwrote: On Sat, Feb 21, 2009 at 8:53 PM, André Thieme splendidl...@googlemail.com wrote: On 21 Feb., 18:24, Mark Volkmann r.mark.volkm...@gmail.com wrote: Currently the dotimes macro requires its first argument to be a vector for binding a variable to the number of times the body should be executed. Inside the body, that variable is bound to the values from 0 to that number minus 1. How about changing this macro to also accept an integer as the first argument instead of a binding vector for cases where the number isn't needed in the body. I don't find this very interesting. There several variants of how dotimes could be, but the one that we currently have is the one that is used since a few decades in Lisp, and it is the one that makes very much sense. For example, (print Santa says) (dotimes 3 (print Ho)) (.flush *out*) (print Santa saysHoHoHo) How often do you really want to repeat the same side effect many times in a row? Why does it hurt to just say (dotimes [i 100] ...)? This will not reduce readability dramatically, but is a consistant use of dotimes. It also does not reduce productivity. Why make a breaking change for this? Why do you say it would be a breaking change? I just got the following to work with minimal changes to the dotimes macro. (dotimes 3 (println Ho)) (dotimes [n 4] (println n)) So both forms work with a single macro definition. Here's what I did. 1) Wrap the body of the macro inside the following: (let [new-bindings (if (integer? bindings) ['n bindings] bindings)] ... ) This creates the required binding when only an integer is passed and using the supplied value for bindings otherwise. 2) Change every occurrence of bindings in the body to new-bindings. 3) Move the (defmacro dotimes ... ) to just before (defn make-array ...). That's the first time it's used in core.clj and it will not be after the definition of integer?. Is there a reason to not make this change? -- 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: dotimes suggestion
I agree that this is initially confusion, but I think that if you spend more than a couple of days with Clojure you will understand the ubiquitous and liberal use of binding forms. On Sun, Feb 22, 2009 at 2:42 PM, Mark Volkmann r.mark.volkm...@gmail.comwrote: On Sun, Feb 22, 2009 at 1:34 PM, David Nolen dnolen.li...@gmail.com wrote: In general, I find that multiple arguments types for a function confusing. If dotimes is going to take multiple types it should be a multifn. That seems to imply a performance hit. I think Clojure wisely does not (or rarely does not?) allow for multiple types to be passed into a function. On top of that it's trivial to produce a macro on top of dotimes that does what you want that doesn't spend time checking the type of it's argument. Really my main goal is to make Clojure code as easy to read as possible. In this particular case, I think code like this: (dotimes [n 3] (println knock)) leaves the reader wondering What is the n for?. Someone suggested this: (dotimes [_ 3] (println knock)) That still seems like too much to read for what I'm getting. OTOH, (dotimes 3 (println knock)) isn't likely to confuse anybody. Sure, I could get what I want by writing my own macro. The problem I have with that is that I don't want to litter my code with calls to custom macros that readers of my code have to figure out. I prefer to use functions that readers will already be familiar with unless introducing my own macros is going to significantly shorten the code. On Sat, Feb 21, 2009 at 11:10 PM, Mark Volkmann r.mark.volkm...@gmail.com wrote: On Sat, Feb 21, 2009 at 8:53 PM, André Thieme splendidl...@googlemail.com wrote: On 21 Feb., 18:24, Mark Volkmann r.mark.volkm...@gmail.com wrote: Currently the dotimes macro requires its first argument to be a vector for binding a variable to the number of times the body should be executed. Inside the body, that variable is bound to the values from 0 to that number minus 1. How about changing this macro to also accept an integer as the first argument instead of a binding vector for cases where the number isn't needed in the body. I don't find this very interesting. There several variants of how dotimes could be, but the one that we currently have is the one that is used since a few decades in Lisp, and it is the one that makes very much sense. For example, (print Santa says) (dotimes 3 (print Ho)) (.flush *out*) (print Santa saysHoHoHo) How often do you really want to repeat the same side effect many times in a row? Why does it hurt to just say (dotimes [i 100] ...)? This will not reduce readability dramatically, but is a consistant use of dotimes. It also does not reduce productivity. Why make a breaking change for this? Why do you say it would be a breaking change? I just got the following to work with minimal changes to the dotimes macro. (dotimes 3 (println Ho)) (dotimes [n 4] (println n)) So both forms work with a single macro definition. Here's what I did. 1) Wrap the body of the macro inside the following: (let [new-bindings (if (integer? bindings) ['n bindings] bindings)] ... ) This creates the required binding when only an integer is passed and using the supplied value for bindings otherwise. 2) Change every occurrence of bindings in the body to new-bindings. 3) Move the (defmacro dotimes ... ) to just before (defn make-array ...). That's the first time it's used in core.clj and it will not be after the definition of integer?. Is there a reason to not make this change? -- 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: alternate syntax
Interesting thread on LtU on this subject: http://lambda-the-ultimate.org/node/1646 On Mon, Feb 23, 2009 at 10:42 AM, Mark Volkmann r.mark.volkm...@gmail.comwrote: I have an idea I'd like to float to see if there are reasons why it's a bad idea. What if Clojure had an alternate surface syntax that was translated into standard Clojure syntax by a kind of preprocessor? Many people that don't like Lisp dialects don't like them because of the parentheses. I'm trying to address that. Here's a simple example of valid Clojure code. (defn pig-latin [word] (let [first-letter (first word)] (if (.contains aeiou (str first-letter)) (str word ay) (str (subs word 1) first-letter ay (println (pig-latin red)) (println (pig-latin orange)) Here's what that same code would look like in my alternate syntax. defn pig-latin [word] let [first-letter (first word)] if .contains aeiou (str first-letter) str word ay str (subs word 1) first-letter ay println (pig-latin red) println (pig-latin orange) The rules for turning this into standard Clojure syntax are pretty simple. 1) If a line is indented farther than the previous one, it is part of the previous line. 2) If a line doesn't start with a (, then add one. 3) If the next line is indented less than this one, add the appropriate number of )'s at the end. 4) If the first token on a line is if and the first non-whitespace character after it is not ( then assume the rest of the line is the condition and wrap it in ( ). A translation from standard Clojure syntax to this alternate form should also be possible. Is this a bad idea? -- 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 -~--~~~~--~~--~--~---
Clojure Slime, how to jump to a def/defn?
Is this supported yet? M-. is supposed to handle this, but I get an error when I try. David --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Operating on multidimensional primitive arrays without reflection?
(time (let [arr (make-array Float/TYPE 1 1)] (dotimes [_ 10] (let [#^floats sub-arr (aget arr 0)] (aset-float sub-arr 0 0.0) Seems to work? Looks an eligible candidate for a macro. On Mon, Feb 23, 2009 at 9:04 PM, Jason Wolfe jawo...@berkeley.edu wrote: I'm trying to call some third-party code that expects a two- dimensional double array, and I can't figure out how to create and fill this in Clojure without a huge perf hit (which profiling shows to be coming from reflection): user (time (let [arr (make-array Double/TYPE 1)] (dotimes [_ 10] (aset-double arr 0 0.0 Elapsed time: 28.408 msecs nil user (time (let [arr (make-array Double/TYPE 1 1)] (dotimes [_ 10] (aset-double arr 0 0 0.0 Elapsed time: 3634.136 msecs nil I've tried adding type hints like #^[[D to no avail. What am I missing here? BTW, I'm still on the pre-lazy SVN, waiting for the dust to settle. Thanks, Jason --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure Slime, how to jump to a def/defn?
You're right, works perfectly on clojure sources, but not the instances you've described. It would be great if this would work again. I don't understand swank/slime well enough to try it myself. On Mon, Feb 23, 2009 at 9:23 PM, Alec Berryman a...@thened.net wrote: David Nolen on 2009-02-23 16:58:40 -0500: Is this supported yet? M-. is supposed to handle this, but I get an error when I try. It works for me with Clojure sources (for example, M-. on rest), even if they're in jars, but not with applications I've compiled through load-file, slime-compile-defun, or slime-compile-region. I think I remember this working a while ago. The backtrace I get is very reproducable: (:emacs-rex (swank:find-definitions-for-emacs bar) foo :repl-thread 19) (:return (:abort) 19) (:debug 2 1 (java.lang.StringIndexOutOfBoundsException: String index out of range: -1 (NO_SOURCE_FILE:0) [Thrown class clojure.lang.Compiler$CompilerException] nil) ((ABORT Return to SLIME's top level.) (CAUSE Throw cause of this exception)) ((0 clojure.lang.Compiler.eval(Compiler.java:4235) (:restartable nil)) (1 clojure.core$eval__3894.invoke(core.clj:1711) (:restartable nil)) (2 swank.core$eval_in_emacs_package__275.invoke(core.clj:55) (:restartable nil)) (3 swank.core$eval_for_emacs__350.invoke(core.clj:123) (:restartable nil)) (4 clojure.lang.Var.invoke(Var.java:348) (:restartable nil)) (5 clojure.lang.AFn.applyToHelper(AFn.java:179) (:restartable nil)) (6 clojure.lang.Var.applyTo(Var.java:457) (:restartable nil)) (7 clojure.core$apply__3162.doInvoke(core.clj:408) (:restartable nil)) (8 clojure.lang.RestFn.invoke(RestFn.java:428) (:restartable nil)) (9 swank.core$eval_from_control__278.invoke(core.clj:62) (:restartable nil)) (10 swank.core$eval_loop__281.invoke(core.clj:67) (:restartable nil)) (11 swank.core$spawn_repl_thread__409$fn__438$fn__440.invoke(core.clj:168) (:restartable nil)) (12 clojure.lang.AFn.applyToHelper(AFn.java:171) (:restartable nil)) (13 clojure.lang.AFn.applyTo(AFn.java:164) (:restartable nil)) (14 clojure.core$apply__3162.doInvoke(core.clj:408) (:restartable nil)) (15 clojure.lang.RestFn.invoke(RestFn.java:428) (:restartable nil)) (16 swank.core$spawn_repl_thread__409$fn__438.doInvoke(core.clj:165) (:restartable nil)) (17 clojure.lang.RestFn.invoke(RestFn.java:402) (:restartable nil)) (18 clojure.lang.AFn.run(AFn.java:37) (:restartable nil)) (19 java.lang.Thread.run(Thread.java:636) (:restartable nil))) (19)) (:emacs-rex (swank:throw-to-toplevel) nil 2 20) (:debug-activate 2 1 true) (:return (:abort) 20) (:debug-return 2 1 nil) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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
1) User-friendly printing. I implement the multimethods print-method and print-dup for my classes, which allows me to specify how objects are printed. print- method and print-dup dispatch on class, so my types need to be classes or at least derive from a class that is distinct from the standard Clojure data structures. Should print and println be multimethods? It seems the ability to custom print a data structure would be generally useful. 2) Usability in multimethods The above argument illustrates a more general problem: multimethods meant for use with a wide range of data structures can in practice only use class as a selector, as that is the only one that will work for the built-in data structures. Look at fmap in clojure.contrib.types.examples, for instance. It would make sense to add an implementation for maps that applys f to the value of each map entry. But I can't have that plus a type system based on maps with special tags - it's one or the other. Not totally following here, looking at your code... Pardon my slowness but why not dispatch on :tag first, and class if no :tag? 4) Modularity There are bound to be several type or class systems for Clojure, as for other Lisps. We already have Spinoza, for example. If all these systems use maps with type tags, there are bound to be tag conflicts sooner or later. For example, someone will create a Spinoza class with a slot whose name interferes with my special type tag. This can't happen with my closure-based implementation. It creates objects that are distinct by the very nature of their classes, so it doesn't interfere with whatever someone else may come up with. Tags of course should be namespaced so is this really that much of an issue in practice? Since tags are keywords they don't have the interning conflict problem that symbols of the same name generally do, right? I've been thinking about the slot conflict issue and am considering namespacing a class's keys against the class name and providing macros set-slot get-slot that transform into assoc and get respectively. If there are multiple slots with the same name the slot furthest down the inheritance chain is used. Perhaps also provide a function called prefer-slot which controls the behavior of the set-slot and get-slot macros. Dunno, starting to ramble, anyways, interesting stuff... --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Multimethods in other namespaces
That should work fine as far as I can tell. On Wed, Feb 25, 2009 at 3:36 PM, Jeffrey Straszheim straszheimjeff...@gmail.com wrote: If in namespace one I define (defmulti fred dispatch-fred) and have imported that ns into another, can I just do (defmethod fred ::val [x] ), or do I need to scope the method 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: Algebraic data types in clojure.contrib
This is nothing short of amazing for those who want to build ad-hoc type systems. (defstruct #^{:type ::my-struct} my-struct :a :b) (type #'my-struct) ; - :user/my-struct! I have a lot of code fixing to do now :) Also Konrad's point that using multimethods for dispatch-fns would be ugly, but actually I think this actually works out well! (defmulti multi-dispatch type) (defmethod multi-dispatch ::my-type [x] (:tag x)) (defmethod multi-dispatch ::another-type [x] (:protocol x)) (defmulti my-multifn multi-dispatch) (defmethod my-multifn ::some-tag [x] (print An object!)) (defmethod my-multifn ::some-protocol [x] (print A protocol)) (my-multifn #^{:type ::my-type} {:tag ::some-tag}) ; - An object! (my-multifn #^{:type ::another-type} {:protocol ::some-protocol}) ; - A protocol! Amazing. On Wed, Feb 25, 2009 at 7:51 PM, Rich Hickey richhic...@gmail.com wrote: On Feb 25, 12:19 pm, Konrad Hinsen konrad.hin...@laposte.net wrote: On Feb 25, 2009, at 17:40, David Nolen wrote: Should print and println be multimethods? It seems the ability to custom print a data structure would be generally useful. It's already there, just not documented as far as I know. All the printing routines end up calling clojure.core/print-method and clojure.core/print-dup, which are multimethods dispatching on class. Not totally following here, looking at your code... Pardon my slowness but why not dispatch on :tag first, and class if no :tag? That's possible, of course, but the result is a multimethod that works for (a) class-based types and (b) one specific type hierarchy hard-wired into the selector, such as your :tag. If I write some other type system, it won't fit in. That makes it impossible to define truly general interfaces that are open for anyone to implement. Take print-method in clojure.core as an example: How would you implement its selector, such that anyone could plug in their type system based on some tagging scheme? Perhaps one could come up with a scheme in which the selector function is itself a multimethod, but that would probably be quite messy. Tags of course should be namespaced so is this really that much of an issue in practice? Since tags are keywords they don't have the interning conflict problem that symbols of the same name generally do, right? Right. Namespaced tags go a long way to avoid name clashes. However, they are still not the private property of any one library module. Your namespaced tag is an object that can end up in any data structure, intentionally or by error. Only time will tell if this is a problem in practice. Anyway, my two main arguments in this issue are printing and open-to- anyone interfaces with multimethods. These are the problems that I had in my own code and that I wanted to solve. Printing is important for complex nested data structures and interactive use. Generic interfaces are a very nice feature to have. I came across this problem twice: 1) In clojure.contrib.accumulators. Ideally, it should be possible to implement additional accumulator types elsewhere, using the same interface. With the current implementation based on meta-data, that is possible, but only for data types that allow meta-data. It is thus not possible to build accumulators based on Java classes, at least not without wrapping them in a map or vector. Moreover, the selector function, based on meta-data with a fallback to classes, is neither elegant nor efficient, and much of the code in the library deals with the meta-data tagging scheme rather than with its real job. 2) In clojure.contrib.streams-utils. Again, I wanted to define a generic interface to data streams. At the moment, it uses a multimethod dispatching on class, but that doesn't leave much room to define different data stream sources. That was in fact what prompted me to write the types library. You raise interesting issues and I'd like to explore them further. I'm not sure the issues you have with type-tag-or-class dispatch are all that prohibitive. In any case, I've added a type function that returns the :type metadata or the class if none: user= (type #^{:type ::Fred} [1 2 3]) :user/Fred user= (type foo) java.lang.String which should help people standardize. If you want to multiplex multimethods for your ADT type, you can just define a single :type ::ADT, and then sub-dispatch on e.g. :adt-type. I'm not sure the mechanism you are using (actual Class types) allows for any more overloading - Class is a single slot too, after all. Interfaces offer some mixin potential, but they can't be superimposed on existing classes. The same mixin capabilities of interfaces are available for type tags, just say; (derive ::my-type :freds/interface) (derive ::my-type :ethels/interface) etc. The trick here is that you *can* superimpose such tags on existing classes: (derive String :freds
Re: Mathy operations on non-numerics
What about something like: (defn gt [str1 str2] (first (sort [str1 str2]))) (gt Zoe Bob) ; - Bob On Fri, Feb 27, 2009 at 12:03 PM, Phil Hagelberg p...@hagelb.org wrote: Christian Vest Hansen karmazi...@gmail.com writes: Are you referring to using , , =, with objects that implement java.lang.Comparable? i.e. given x.compareTo(y) == -1 ( x y) = true I would find that useful. I think having , , =, = be based on Comparable has been discussed before. And the conclusion was that it was a bad idea, because in Java: user= (.compareTo (Integer. 10) (Long. 10)) java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer (NO_SOURCE_FILE:0) And: user= (.equals (Integer. 10) (Long. 10)) false Curses, Java! Foiled again. Given these consequences, I think the current behavior is the best compromise. Agreed. Am curious as to what the idiomatic way to check to see if one string is alphabetically greater than another is though. -Phil --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Laziness madness
Remember that you can force lazy sequences if you need to as you are with doseq with doall (retains head) and dorun (does not) as well. You probably want (dorun (map #(add-watch % watcher callback-fn) all-agents)) I think it's pretty clear here what's going on. Your code needs side-effects. In Clojure side-effect code tends to stands out. I sympathize with your frustration, I remember getting excited about Lisp macros but spending many many long hours trying to understand how to write even a simple one. Similarly I think lazy sequences are worth the initial frustration ;) On Mon, Mar 2, 2009 at 12:06 AM, max3000 maxime.lar...@gmail.com wrote: Hi, I find the laziness in clojure very hard to wrap my head around. I understand the idea and it's probably nice in theory. However, in real life it doesn't seem really useful beyond hardcore mathematical problems. Case in point, I just spent 2 hours debugging a piece of code (shown below) that seemed simple enough. This is the 3rd time this week that I've lost substantial time to laziness. I'm pretty pissed to tell the truth and I find myself wrapping things in doseq more and more just to be sure. I rarely use 'for' anymore, what's the point? Here is the code that gave me trouble: (map #(add-watch % watcher callback-fn) all-agents) This was not executing. I had to change it to the below expression: (doseq [agent all-labor-agents] (add-watch agent total-labor-agent callback-fn)) This second expression seems less elegant than the map above. Why doesn't clojure realize that an add-watch really should actually loop over all-agents? Why is it that Java calls are not made in similar expressions? Is laziness so useful that we should waste time investigating and fixing errors like this? Sure, there could be special constructs for laziness when we really need it. However, clojure shouldn't default to it IMO. At this point, laziness is a nice concept but it feels somewhat removed from reality to tell the truth. Of course I want to iterate over my collection when I'm doing an add-watch! What am I missing? Thanks, Max --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 on names of errors in error-kit
I appreciate that they stand out. Again, this is similar to the constants conversation earlier, visually marking the intended use is a good habit, IMHO. Of course this doesn't mean that error-kit should define the base error this way, but I intend to keep on wrapping my errors in earmuffs :) David On Tue, Mar 3, 2009 at 10:27 PM, Chouser chou...@gmail.com wrote: On Tue, Mar 3, 2009 at 2:10 PM, samppi rbysam...@gmail.com wrote: Small questions on error-kit—which I love and think that all clojure- contrib libraries should use—why do defined errors such as *error*, *number-error*, etc. have names surrounded by asterisks? Thanks for the endorsement! Have you used continue or bind-continue yet? These are the features I'm less certain about. Your question is a very good one. Early versions actually rebound the error Vars, so I named them appropriately. Of course that's not exactly how it works anymore, but I grew accustomed to how they look with earmuffs, and didn't change them. I'm hesitant to remove them because I like how they stand out in the code. Perhaps it's not really necessary, or perhaps there's a better naming convention we could use? Any thoughts? --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Question on names of errors in error-kit
capitals seems pretty weird for a Lisp. Now that I think about it, perhaps foo-error isn't so bad. David On Tue, Mar 3, 2009 at 10:54 PM, Chouser chou...@gmail.com wrote: On Tue, Mar 3, 2009 at 10:36 PM, David Nolen dnolen.li...@gmail.com wrote: I appreciate that they stand out. Again, this is similar to the constants conversation earlier, visually marking the intended use is a good habit, IMHO. Of course this doesn't mean that error-kit should define the base error this way, but I intend to keep on wrapping my errors in earmuffs :) Since earmuffs already mean something different, perhaps there's something else that would work? Maybe capitals, because they're a kind of type name? Error, Odd-Number-Error? --Chouser --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: hash-map based on identity
Depending on what you are doing perhaps you could use (hash x). This might not be very helpful if you need to update keys frequently. However if you're mostly doing lookups, then this would help quite a bit. On Sat, Mar 7, 2009 at 3:44 PM, Mark Engelberg mark.engelb...@gmail.comwrote: Here's why it would be useful to have the option of hash maps that use identity... Let's say my keys are rather long lists. Equality comparison will be slow. But if I know that the keys are always the exact same long lists (perhaps because I traversed the key sequence to find a key with a certain property, and then am updating with that precise key as one example), then I can save lots of time by using an identity comparison. FWIW, the Scheme I usually use (PLT Scheme) supports both eq? and equal? based hash tables, and I have found both to be useful (although I prefer equal? based hash tables as the default). On Sat, Mar 7, 2009 at 7:57 AM, David Powell djpow...@djpowell.net wrote: What objects are you trying to store? The ideal in the Clojure world, is that most objects are immutable. Immutable objects will implement value equality in .equals() ('=' in Clojure), and you shouldn't care about whether two objects are identical? because it won't affect anything. It's an efficiency issue. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: On the importance of recognizing and using maps
Structs are maps with shared keys and positional constructors as Rich mentions in the original post. I think Rich is saying that maps should indeed be abused ;) By building all higher level structures on top of them, consumers are guaranteed not only your custom functionality, but all the functionality guaranteed by the language itself. On Sun, Mar 8, 2009 at 3:47 PM, Dan redalas...@gmail.com wrote: I guess I want to advocate - don't merely replicate the things with which you are familiar. Try to do things in the Clojure way. If your logical structure is a mapping of names to values, please use a map. I tend to replace every instance of creating classes with creating structs which, if I understood correctly, are maps too. Good habit or should structs not be abused? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: macros
It does. Also Practical Common Lisp and On Lisp cover this in depth as well, though you'll need to convert commas into tildes as well as use ~' for each level of backquote depth that you don't want Clojure to namespace free symbols. On Tue, Mar 10, 2009 at 6:05 PM, .Bill Smith william.m.sm...@gmail.comwrote: Does the Clojure book contain much conceptual material on macros? I keep finding places where I think a macro might be useful, and then the macro doesn't work and it's hard to understand why. 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: macros
Practical Common Lisp and On Lisp are available online and free. On Tue, Mar 10, 2009 at 6:16 PM, David Nolen dnolen.li...@gmail.com wrote: It does. Also Practical Common Lisp and On Lisp cover this in depth as well, though you'll need to convert commas into tildes as well as use ~' for each level of backquote depth that you don't want Clojure to namespace free symbols. On Tue, Mar 10, 2009 at 6:05 PM, .Bill Smith william.m.sm...@gmail.comwrote: Does the Clojure book contain much conceptual material on macros? I keep finding places where I think a macro might be useful, and then the macro doesn't work and it's hard to understand why. 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: Question about throwing errors
Doesn't error-kit do this? On Wed, Mar 11, 2009 at 10:15 PM, Mark Engelberg mark.engelb...@gmail.comwrote: I'm thinking about implementing a backtracking mechanism that throws errors as a way to escape out of the current computation and try another possibility. I'd want to create a specific error to escape, and the backtracking mechanism should only catch this very specific error. Now, I vaguely recall some thread on here a while ago about how this is very hard to do in Clojure, because Clojure wraps the errors inside of other errors as they work their way outwards, so you can't just catch a very specific error. I think there was some sort of workaround involving catching every error, and looking deep inside the stack of errors to find the specific error, and if not found, pass it on up the chain. Am I remembering this gotcha correctly? If so, can someone please spell out the workaround for me again? 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: ANN: A pretty printer for Clojure
Amazing stuff. In particular this finally makes debugging macros sane. For those of you that are using swank-clojure you only need to make minor modifications to swank-clojure to pretty-print your macro expansions to the macro expansion buffer. Even better you can move the cursor to subform macros and expand those inline as well. For example here is an example from Paul Graham's continuations chapter from On Lisp that I expanded, I did not do this by hand promise ;) (do (clojure.core/defmacro dft2 [tree] (clojure.core/seq (clojure.core/concat (clojure.core/list '=dft2) (clojure.core/list '*cont*) (clojure.core/list tree (clojure.core/defn =dft2 [*cont* tree] (reset! *saved* nil) (clojure.core/let [*cont* (clojure.core/fn [node] (cond (= node 'done) (*cont* nil) :else (do (print node) (restart] (=dft-node *cont* tree For you swank-clojure users, all you need to do to get this feature right now is to include the cl-format library in basic.clj (swank-clojure/swank/commands/basic.clj) and change apply-macroexpander to look like the following: (defn- apply-macro-expander [expander string] (let [astr (with-out-str (with-pprint-dispatch *code-dispatch* (pprint (expander (read-from-string string)] (subs astr 0 (dec (count astr) Of course once cl-format makes into clojure-contrib this should just be the default behavior (or setq-able option) for swank-clojure ;) David On Thu, Mar 12, 2009 at 3:05 AM, Tom Faulhaber tomfaulha...@gmail.comwrote: I have now released the first version of my pretty printer as part of my cl-format library. It is released under the EPL. The pretty printer has two functions that you probably care about: (pprint obj) will pretty print the given object, and (pp) at the REPL will pretty print the last result output, i.e. the value in *1. The pretty printer currently supports two modes: simple and code. Simple mode prints structure in a standard way that's good for data. Code mode understands lots of Clojure forms (defn, binding vectors, condp, etc.) and attempts to print them in an idiomatic way. Cl-format is on github at http://github.com/tomfaulhaber/cl-format. There is a Readme there with instructions, examples, limitations and futures. I won't even try to put examples here, because google groups wreaks havoc on formatting. The simplest way to get some pretty printing happiness: 1) Download the jar: http://github.com/tomfaulhaber/cl-format/raw/master/release/cl-format.jar 2) Put it in your classpath. 3) Fire up your REPL 4) (use 'com.infolace.format) 5) Use pprint and pp as described above. This is definitely a first release and there are sure to be bugs. And I know there are things missing. So let me know if you're having problems and I'll try to get things fixed up ASAP. 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: ANN: A pretty printer for Clojure
So that people can copy and paste the change in basic.clj (defn- apply-macro-expander [expander string] (binding [*print-suppress-namespaces* true] (let [astr (with-out-str (with-pprint-dispatch *code-dispatch* (pprint (expander (read-from-string string)] (subs astr 0 (dec (count astr)) Fantastic. On Thu, Mar 12, 2009 at 12:53 PM, Tom Faulhaber tomfaulha...@gmail.comwrote: Expanding on David's earlier example of pretty printing, we can set the dispatch to *code-dispatch* and bind *print-suppress-namespaces* to true and get the following (apologies for google messing up my formatting): (do (defmacro dft2 [tree] (seq (concat (list '=dft2) (list '*cont*) (list tree (defn =dft2 [*cont* tree] (reset! *saved* nil) (let [*cont* (fn [node] (cond (= node 'done) (*cont* nil) :else (do (print node) (restart] (=dft-node *cont* tree Which is not always what you want, since it loses the namespace info that backquote adds, but for me it's usually what I want because it looks like the code I would have written. A couple of notes for the detail-oriented: You can see the special code formats for defmacro, defn, binding vectors, and cond in operation here. You can also see that fn needs special treatment and doesn't have it yet. (But it will, real soon now.) On Mar 12, 9:28 am, Tom Faulhaber tomfaulha...@gmail.com wrote: Rich, I would be happy to make it a contribution (it's the least I can do!). I've had a CA sitting on my desk unread and unsigned for about 3 weeks. It is now read, signed, and in an envelope. I'll send it off this morning. Everyone, Thanks for the kind words. I'm glad you like it. David's use case in slime/swank was one of the motivators for me writing this. Thanks for showing us how to do the integration, David! I hope we see a lot of other use cases like that. Upcoming is the ability to create custom dispatch tables which will open the door to an even broader set of use cases. On Mar 12, 1:56 am, Rich Hickey richhic...@gmail.com wrote: On Mar 12, 2009, at 3:05 AM, Tom Faulhaber wrote: I have now released the first version of my pretty printer as part of my cl-format library. It is released under the EPL. The pretty printer has two functions that you probably care about: (pprint obj) will pretty print the given object, and (pp) at the REPL will pretty print the last result output, i.e. the value in *1. The pretty printer currently supports two modes: simple and code. Simple mode prints structure in a standard way that's good for data. Code mode understands lots of Clojure forms (defn, binding vectors, condp, etc.) and attempts to print them in an idiomatic way. Cl-format is on github athttp://github.com/tomfaulhaber/cl-format. There is a Readme there with instructions, examples, limitations and futures. I won't even try to put examples here, because google groups wreaks havoc on formatting. The simplest way to get some pretty printing happiness: 1) Download the jar: http://github.com/tomfaulhaber/cl-format/raw/master/release/cl-format... 2) Put it in your classpath. 3) Fire up your REPL 4) (use 'com.infolace.format) 5) Use pprint and pp as described above. This is definitely a first release and there are sure to be bugs. And I know there are things missing. So let me know if you're having problems and I'll try to get things fixed up ASAP. Enjoy! Tom This looks very useful Tom. Would you consider contributing it to Clojure? Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: ANN: A pretty printer for Clojure
I suppose the following is more idiomatic: (defn- apply-macro-expander [expander string] (let [astr (with-out-str (binding [*print-suppress-namespaces* true] (with-pprint-dispatch *code-dispatch* (pprint (expander (read-from-string string))] (subs astr 0 (dec (count astr) On Thu, Mar 12, 2009 at 12:53 PM, Tom Faulhaber tomfaulha...@gmail.comwrote: Expanding on David's earlier example of pretty printing, we can set the dispatch to *code-dispatch* and bind *print-suppress-namespaces* to true and get the following (apologies for google messing up my formatting): (do (defmacro dft2 [tree] (seq (concat (list '=dft2) (list '*cont*) (list tree (defn =dft2 [*cont* tree] (reset! *saved* nil) (let [*cont* (fn [node] (cond (= node 'done) (*cont* nil) :else (do (print node) (restart] (=dft-node *cont* tree Which is not always what you want, since it loses the namespace info that backquote adds, but for me it's usually what I want because it looks like the code I would have written. A couple of notes for the detail-oriented: You can see the special code formats for defmacro, defn, binding vectors, and cond in operation here. You can also see that fn needs special treatment and doesn't have it yet. (But it will, real soon now.) On Mar 12, 9:28 am, Tom Faulhaber tomfaulha...@gmail.com wrote: Rich, I would be happy to make it a contribution (it's the least I can do!). I've had a CA sitting on my desk unread and unsigned for about 3 weeks. It is now read, signed, and in an envelope. I'll send it off this morning. Everyone, Thanks for the kind words. I'm glad you like it. David's use case in slime/swank was one of the motivators for me writing this. Thanks for showing us how to do the integration, David! I hope we see a lot of other use cases like that. Upcoming is the ability to create custom dispatch tables which will open the door to an even broader set of use cases. On Mar 12, 1:56 am, Rich Hickey richhic...@gmail.com wrote: On Mar 12, 2009, at 3:05 AM, Tom Faulhaber wrote: I have now released the first version of my pretty printer as part of my cl-format library. It is released under the EPL. The pretty printer has two functions that you probably care about: (pprint obj) will pretty print the given object, and (pp) at the REPL will pretty print the last result output, i.e. the value in *1. The pretty printer currently supports two modes: simple and code. Simple mode prints structure in a standard way that's good for data. Code mode understands lots of Clojure forms (defn, binding vectors, condp, etc.) and attempts to print them in an idiomatic way. Cl-format is on github athttp://github.com/tomfaulhaber/cl-format. There is a Readme there with instructions, examples, limitations and futures. I won't even try to put examples here, because google groups wreaks havoc on formatting. The simplest way to get some pretty printing happiness: 1) Download the jar: http://github.com/tomfaulhaber/cl-format/raw/master/release/cl-format... 2) Put it in your classpath. 3) Fire up your REPL 4) (use 'com.infolace.format) 5) Use pprint and pp as described above. This is definitely a first release and there are sure to be bugs. And I know there are things missing. So let me know if you're having problems and I'll try to get things fixed up ASAP. Enjoy! Tom This looks very useful Tom. Would you consider contributing it to Clojure? Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: ANN: A pretty printer for Clojure
Works great. On Thu, Mar 12, 2009 at 3:30 PM, Tom Faulhaber tomfaulha...@gmail.comwrote: Write can produce pretty output directly to a string and without the trailing newline, making this a little shorter: (defn- apply-macro-expander [expander string] (binding [*print-suppress-namespaces* true] (with-pprint-dispatch *code-dispatch* (write (expander (read-from-string string)) :pretty true :stream nil Completely untested! :-) Tom On Mar 12, 11:07 am, David Nolen dnolen.li...@gmail.com wrote: I suppose the following is more idiomatic: (defn- apply-macro-expander [expander string] (let [astr (with-out-str (binding [*print-suppress-namespaces* true] (with-pprint-dispatch *code-dispatch* (pprint (expander (read-from-string string))] (subs astr 0 (dec (count astr) On Thu, Mar 12, 2009 at 12:53 PM, Tom Faulhaber tomfaulha...@gmail.comwrote: Expanding on David's earlier example of pretty printing, we can set the dispatch to *code-dispatch* and bind *print-suppress-namespaces* to true and get the following (apologies for google messing up my formatting): (do (defmacro dft2 [tree] (seq (concat (list '=dft2) (list '*cont*) (list tree (defn =dft2 [*cont* tree] (reset! *saved* nil) (let [*cont* (fn [node] (cond (= node 'done) (*cont* nil) :else (do (print node) (restart] (=dft-node *cont* tree Which is not always what you want, since it loses the namespace info that backquote adds, but for me it's usually what I want because it looks like the code I would have written. A couple of notes for the detail-oriented: You can see the special code formats for defmacro, defn, binding vectors, and cond in operation here. You can also see that fn needs special treatment and doesn't have it yet. (But it will, real soon now.) On Mar 12, 9:28 am, Tom Faulhaber tomfaulha...@gmail.com wrote: Rich, I would be happy to make it a contribution (it's the least I can do!). I've had a CA sitting on my desk unread and unsigned for about 3 weeks. It is now read, signed, and in an envelope. I'll send it off this morning. Everyone, Thanks for the kind words. I'm glad you like it. David's use case in slime/swank was one of the motivators for me writing this. Thanks for showing us how to do the integration, David! I hope we see a lot of other use cases like that. Upcoming is the ability to create custom dispatch tables which will open the door to an even broader set of use cases. On Mar 12, 1:56 am, Rich Hickey richhic...@gmail.com wrote: On Mar 12, 2009, at 3:05 AM, Tom Faulhaber wrote: I have now released the first version of my pretty printer as part of my cl-format library. It is released under the EPL. The pretty printer has two functions that you probably care about: (pprint obj) will pretty print the given object, and (pp) at the REPL will pretty print the last result output, i.e. the value in *1. The pretty printer currently supports two modes: simple and code. Simple mode prints structure in a standard way that's good for data. Code mode understands lots of Clojure forms (defn, binding vectors, condp, etc.) and attempts to print them in an idiomatic way. Cl-format is on github athttp:// github.com/tomfaulhaber/cl-format. There is a Readme there with instructions, examples, limitations and futures. I won't even try to put examples here, because google groups wreaks havoc on formatting. The simplest way to get some pretty printing happiness: 1) Download the jar: http://github.com/tomfaulhaber/cl-format/raw/master/release/cl-format. .. 2) Put it in your classpath. 3) Fire up your REPL 4) (use 'com.infolace.format) 5) Use pprint and pp as described above. This is definitely a first release and there are sure to be bugs. And I know there are things missing. So let me know if you're having problems and I'll try to get things fixed up ASAP. Enjoy! Tom This looks very useful Tom. Would you consider contributing it to Clojure? Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: swank-clojure: swank-clojure-init-files not used
On Mon, Mar 16, 2009 at 3:42 AM, Tassilo Horn tass...@member.fsf.orgwrote: When adding ~/.clojure/ to `swank-clojure-extra-classpaths' and starting SLIME, htop shows that this directory is not in the -cp java option. Sending a SIGINT kills the clojure process and doesn't interrupt the current Thread only... I've noted that you cannot interactively change that variable. If you change it you must restart your emacs session for it to take effect. If you haven't already checked this of course. David --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Symbols evaluated at compile time?
This has come up before. You can actually work around this (search the mailing list for declare) I think that when not hacking against the REPL that the default behavior is a good one. Having to use declare bugged me a little at first, but I now consider it a very minor annoyance compared to the advantages I get from programming interactively with Clojure. Should the REPL have an interactive mode where it won't fire an exception on undefined symbols and instead issue compiler warnings? If compiler warnings were issued this would be a nice hook for Emacs and other IDEs. David On Mon, Mar 16, 2009 at 3:32 PM, Elena egarr...@gmail.com wrote: On 16 Mar, 20:14, Jeffrey Straszheim straszheimjeff...@gmail.com wrote: It does effect humans reading the code, however. Often when looking at unfamiliar Clojure code, I find myself scrolling to the bottom first. That's exactly my point: why should I scroll to the bottom? That's not the way I read a written page or report. Can you imagine a report which starts with the details instead of the more general picture? I think sometimes we warp ourselves to compensate for our tools deficiencies, whilst it should be the other way around. It is much easier for the compiler/interpreter to look ahead, isn't it? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Symbols evaluated at compile time?
On Mon, Mar 16, 2009 at 4:08 PM, Paul Stadig p...@stadig.name wrote: I may be missing something, but how does having to (declare) vars fix typos? I don't think anyone is suggesting *creating* a var that is referenced before it is defined. What people are asking for is that the compiler looks-ahead to verify that the var will eventually be defined, and then go on its merry way. Typos would still be discovered, and people wouldn't have to stop and (declare). Yeah I wasn't suggesting that vars should be created, sorry if it sounded like I was (I mentioned declare because this came up in another thread about declare and someone had hacked the reader to not bail immediately on undefined symbols). In CL, if you have definitions out of order in the compiler will issue warnings. I'm not saying it's an easy change... Paul On Mon, Mar 16, 2009 at 3:45 PM, David Nolen dnolen.li...@gmail.comwrote: This has come up before. You can actually work around this (search the mailing list for declare) I think that when not hacking against the REPL that the default behavior is a good one. Having to use declare bugged me a little at first, but I now consider it a very minor annoyance compared to the advantages I get from programming interactively with Clojure. Should the REPL have an interactive mode where it won't fire an exception on undefined symbols and instead issue compiler warnings? If compiler warnings were issued this would be a nice hook for Emacs and other IDEs. David --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure Web Framework, what I want to add
I'm mostly a front-end UI person with crazy amounts of JS experience so most of my input will be from that stand point. 1. I agree with Sean on this one. No need to bring in middleware that can't be expressed in 10X-20X less code in pure Clojure. 2. The framework should allow for any backend (even if it means in memory). I'm currently interested in CouchDB. 3. Sure. 4. Yup. Compojure handles this nicely. If I never have to look at an Apache httpd.conf file again I won't shed a tear. 5.1 Hmm I hate templates pages, I think Enlive is a very good start to a real future. Template with CSS selectors. Mixing language into HTML is an atrocity which much be eliminated once and for all. Good HTML fragment manipulation is a must. I see pure HTML+CSS fragments created by a designer. The coder draws up a template which targets where values will go in the HTML via CSS3 selectors. Voila! Synchronizing design and code becomes trivial overnight. 5.2. Compojure 6. This is going to be big, it will demolish what other people are doing. 7. See below. 8. Yup. 9. Agreed. I've been seriously investigating porting cl-cont which is the basis for weblocks (working on it right now fingers crossed). The only truly serious continuation based framework is Seaside and its developers have been able to accomplish truly amazing things. With continuations you can define arbitrarily complex UIs. However, I think Seaside overemphasizes the continuation part. The framework should allow for restful delivery as well as stateful interactions. Also, weblocks got it wrong by auto-generating HTML- designers need to be be able create markup and CSS, not just CSS. Seaside also gets this wrong. JS integration with existing JS Frameworks is a must. The recently uploaded parenscript clone looks like a good start for allowing developers to code JS against widgets using such a continuation based framework. Calling JS suddenly becomes like calling Java from Clojure code. Clojure also has something going for which is BIG that you don't get from many frameworks. You can ssh tunnel into the running application server and debug a live instance. For example, currently I have compojure running on the server, I connect to it from my local emacs and can manipulate the server via the remote REPL. I can recompile functions on the server on the fly. Imagine this whole system hooked up with a Comet server (SymbolicWeb did this first). As you modify the server, changes can be propagated back to the client without refreshing (godsend for debugging). Then imagine this entire UI system hooked up to a robust backend of your choosing ;) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 Clojure simulate Class?Lisp can do it!
Doesn't On Lisp talk about simulating CLOS with closures? It's free online. I would like to add as the creator that I would not use Spinoza yet ;) And I've put it on hold as I'm currently obsessed with trying to port cl-cont. Spinoza still needs quite a bit of work, I started on that before a few things changed in Clojure. I will get back to it. Having now played with Clojure for a bit I'm not sure how useful Spinoza will turn out to be for anything beyond supporting widgets in a web framework. With Clojure's flexibility it's really tough to come up with reasons to resort to an object system. That said, it at least shows that building a more traditional class system is not very difficult in Clojure. David On Thu, Mar 19, 2009 at 8:01 AM, e evier...@gmail.com wrote: On Thu, Mar 19, 2009 at 6:34 AM, Konrad Hinsen konrad.hin...@laposte.netwrote: On 19.03.2009, at 07:54, Edward Shen wrote: Can Clojure simulate Class?Lisp can do it! Anyone know it? Clojure can do it as well. Look here for a library that does it: http://github.com/swannodette/spinoza/tree/master Konrad. That library looks very useful, but if this is intended to be a repeat of the question asked one message ago, maybe ... is the question, how do you use closures to simulate a class? That library looks like it uses maps, which is nice, too. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
ANN: Delimited Continuations for Clojure
You can get it here: http://github.com/swannodette/clj-cont/tree/master So over the past week I've been porting cl-cont ( http://common-lisp.net/project/cl-cont/) originally written by Slava Akhmechet to Clojure. I've now ported most of the functionality that's translatable from Common Lisp though it would be great to hear if something blatant seems to be missing. You can now do things like the following: (let [cc (atom nil)] [(with-call-cc (letfn [(a [i j] (+ i j)) (b [i j] (* (a i j) 3))] (+ (b 1 2) (let-cc k (reset! cc k) (k 0) (@cc 1)]) - [9 10] Currently these forms are supported: quote do if let letfn apply cl-cont also defines defn/cc (defn-cc) for creating functions to be used from within a with-call/cc (with-call-cc) form. It also has without-call/cc (without-call-cc) to prevent CPS transformation. These have also been ported. There are 61 tests as of now (all taken from cl-cont's test suite). Again this port only supports the shared functionality between Common Lisp and Clojure, support for Clojure specific forms is mostly missing and this is what people can help on if they like. The big questions are which Clojure special forms should be supported and how (if possible). Clearly trying to support lazy sequences isn't a goal, but supporting the STM forms (dosync, commute) as well the forms that don't rely on side-effects is just a matter of time. forks and feedback appreciated. David --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: New release 20090320
Congrats! It's been said many a time, but it bears being said again, Clojure makes hacking fun again. It's great working with a language that is very production ready, yet still evolving at a quick clip. It's also fascinating that a language supports so many different usage patterns- the diversity and friendliness of the community is amazing. All built on top of the JVM, whodathunk? David On Fri, Mar 20, 2009 at 10:15 AM, Rich Hickey richhic...@gmail.com wrote: New release 20090320 - http://clojure.googlecode.com/files/clojure_20090320.zip Incorporates all the recent additions - fully lazy seqs, :let option for doseq/for, letfn for mutually recursive local fns, synchronous watches, multi-arg set/union/difference/intersection, counted?, per- defmulti hierarchies, #_ ignore form reader macro, future-calls, future and pcalls/pvalues, defmulti docstrings and metadata, methods/ prefers for multimethod reflection, uniform metadata handling for atoms/refs/agents/vars/namespaces, condp, release-pending-sends, AOT tweaks to support applets and Android, etc. All this in addition to many fixes and enhancements. The API docs page is now current - changes to the rest of the site will come soon. This release includes many patches from contributors, and input and reports from many users - thanks all! Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Help with the dot operator special form
I'm wondering if it's possible to create a Clojure function that does what the dot operator does. It seems like this would be possible with definline but I'm unable to get this to work or figure it out. For example I want to be able write something like the following: (dot Hello world (list 'substring 1 2)) Trying to use definline like this: (definline dot [obj member-exp] `(. ~obj (~...@member-expr))) Simply throws an error. I don't need variable arity, I will always pass an instance or class following by a list representing the member expression. Is this impossible? It seems like this would be generally useful to allow variable method calling on Java objects. As to why I want it to implement this, it would be far simpler to support Java interop from clj-cont if the dot operator could be expressed as a Clojure function. Thanks! David --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 with the dot operator special form
On Sat, Mar 21, 2009 at 9:10 PM, Kevin Downey redc...@gmail.com wrote: you want defmacro not definline. the result of a macro is a data structure. that data structure is then evaluated in place of the call to the macro. definline (I think?) behaves similar to a function, so if it returns a data structure, you just get that data structure (the data structure is not then evaluated) You missed the part that it needs to be function not a macro. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 with the dot operator special form
Or rather I did not express that requirement clearly enough. On Sat, Mar 21, 2009 at 9:21 PM, David Nolen dnolen.li...@gmail.com wrote: On Sat, Mar 21, 2009 at 9:10 PM, Kevin Downey redc...@gmail.com wrote: you want defmacro not definline. the result of a macro is a data structure. that data structure is then evaluated in place of the call to the macro. definline (I think?) behaves similar to a function, so if it returns a data structure, you just get that data structure (the data structure is not then evaluated) You missed the part that it needs to be function not a macro. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 with the dot operator special form
Thanks all for the pointers, this looks like a workable approach. In my case I'm not bothered by the performance hit from reflection (CPS transformation creates an obscene number of anonymous functions anyway). However I am running into an issue. Here's my dot function: (def not-seq? (comp not seq?)) (defn dot [obj member-expr] (let [member (str (first member-expr)) arg-or-args(rest member-expr) args (if (not-seq? arg-or-args) [arg-or-args] arg-or-args)] (Reflector/invokeInstanceMethod obj member (to-array args This works fine for: (dot Hello (list 'substring 1 2)) But throws an exception for this: (let [myref (ref {})] (dot clojure.lang.LockingTransaction (list 'runInTransaction (fn [] (commute myref assoc :mykey :myval) I'm getting a instance method not found exception which seems odd. I looked at LockingTransaction.java and I see that runInTransaction does in fact take Callable, and fn's are Callable. Any thoughts? I knew I would have to really learn Java at some point ;) On Sun, Mar 22, 2009 at 12:06 PM, Stuart Sierra the.stuart.sie...@gmail.com wrote: On Mar 21, 10:23 pm, Timothy Pratley timothyprat...@gmail.com wrote: You may be able to achieve what you want by directly accessing Clojure's reflector class instead of using the special form: You could also call Java's reflection API directly. -Stuart Sierra --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Help with the dot operator special form
That was it! At one point I knew these things. Thanks much. On Sun, Mar 22, 2009 at 2:18 PM, Eric Tschetter eched...@gmail.com wrote: (let [myref (ref {})] (dot clojure.lang.LockingTransaction (list 'runInTransaction (fn [] (commute myref assoc :mykey :myval) I'm getting a instance method not found exception which seems odd. I looked at LockingTransaction.java and I see that runInTransaction does in fact take Callable, and fn's are Callable. Any thoughts? I haven't double checked the clojure code, but it looks like you are trying to call a static method, not an instance method, and that is what is causing the exception. --Eric Tschetter --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 with the dot operator special form
Thanks again to all for the help, clj-cont now supports the new and dot special forms. This also means that dosync, doto, .. all work perfectly fine from within a with-call-cc form. You can now write things like this: (let [cc (atom nil)] [(with-call-cc (. (let-cc k (reset! cc k) (k Hello)) substring 2)) (@cc Goodbye)]) - [llo odbye] One caveat is that you can't use the let-cc form within a dosync block that's embedded in a with-call-cc. This is probably for the best anyway. Also since the dot and new forms are being transformed into a version that relies on reflection you can't expect this code to be super performant. That may or may matter depending on your use case ;) On Sun, Mar 22, 2009 at 5:28 PM, David Nolen dnolen.li...@gmail.com wrote: That was it! At one point I knew these things. Thanks much. On Sun, Mar 22, 2009 at 2:18 PM, Eric Tschetter eched...@gmail.comwrote: (let [myref (ref {})] (dot clojure.lang.LockingTransaction (list 'runInTransaction (fn [] (commute myref assoc :mykey :myval) I'm getting a instance method not found exception which seems odd. I looked at LockingTransaction.java and I see that runInTransaction does in fact take Callable, and fn's are Callable. Any thoughts? I haven't double checked the clojure code, but it looks like you are trying to call a static method, not an instance method, and that is what is causing the exception. --Eric Tschetter --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Information Hiding
You could always build something where setters/getters are auto-magically created if specified by the constructor macro. And with clojure.contrib.def you could auto-magically generate private setters/getters. On Mon, Mar 23, 2009 at 4:27 AM, Mark Engelberg mark.engelb...@gmail.comwrote: I've been thinking quite a bit about the OO side of Clojure the past couple of days, and trying to figure out how common OO design patterns would look when ported over to Clojure's way of doing things. The most obvious thing that others have noted is that you can effectively simulate a mutable object by having a ref that holds a hash map. You can then write getters and setters, and other kinds of supporting functions that use and manipulate the ref, and the hash map contained therein. But as far as I can tell, there's no way to stop a client from simply dereferencing the ref and extracting or manipulating the private information in the hash map and shoving it back into the ref. Even if you trust a client to do the right thing, if the object is complex, it might be hard for other programmers to figure out which properties are meant to be manipulated, and which are off-limits. I suspect that if you use double-colon keywords for the keys, you get a bit more privacy in the sense that these keys are slightly harder to accidentally manipulate from other namespaces, so perhaps that could at least be an informal convention for this is private. Or perhaps it's better to keep as much private data in the metadata as possible (although I would think that in many cases, the private data would still be essential to the notion of equality). Any other tricks or techniques for helping to hide or separate out the portions of a data structure that are meant to be accessed or altered from the portions that should only be accessed and changed by the existing support functions? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 errors with clojure_20090320
You need to make sure all the different moving parts are based on the newest version of Clojure as well. This includes swank-clojure, clojure-mode, and any other libs you might be using. On Mon, Mar 23, 2009 at 9:51 AM, Dan Pomohaci dan.pomoh...@gmail.comwrote: Hi, When I start slime with the new clojure_20090320 in classpath I get the messages: user= user= java.lang.Exception: Unable to resolve symbol: lazy-cons in this context (core.clj:70) user= user= java.lang.Exception: No such var: swank.swank/ignore-protocol-version (NO_SOURCE_FILE:5) user= user= java.lang.Exception: No such var: swank.swank/start-server (NO_SOURCE_FILE:7) The error is connected to swank because the same script works ok in command line. The same configuration with old clojure jar works ok in slime. Dan Pomohaci --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Problem with CLASSPATH
The latest version of Clojure incorporated lazy sequences which broke many libraries early on. Most of these problems have been worked out. In my experience you should use the cutting edge version of everything including SLIME. I clone everything from GitHub (clojure, clojure-contrib, swank-clojure, clojure-mode, slime). This has worked for me for the past 6 months with very few problems (except the original transition to lazy sequences). On Tue, Mar 24, 2009 at 5:03 AM, Rich rwml...@gmail.com wrote: Has anyone gotten 20090320 to work on a new MacBook Pro running Leopard? With further investigation, it looks like any call to (use...) either explicitly or as part of an (ns...) function call causes clojure to crash since the upgrade. I've fiddled around with the class path, and nothing seems to work. Interestingly enough, my Structure.clj file sets the namespace, but doesn't use any other files. So, I can launch it from the command line like this: java clojure.lang.Script Structure.clj And I don't get any errors. When I open up the REPL, however and try (use 'Structure), It crashes. I would go back to the older version, but I cannot get duck-streams from clojure.contrib to work on that version. Clojure.contrib seems to build without errors, but it just doesn't work. Previously, I'd built both clojure and clojure.contrib from source, and everything worked fine. However, I have no clue which revision that was, so I don't know how to go back to that version. So, I'm stuck between two non-working versions. Which is frustrating, because I'm in the middle of a project, and I need to get things moving again quickly. Any help or advice would be greatly appreciated. -Rich- On Mar 23, 11:12 am, Rich rwml...@gmail.com wrote: Let me clarify my last post. In both cases, the directory was on the class path (either implicitly as ., or explicitly given the absolute path). However, in both cases I got the same FileNotFound exception. -Rich- On Mar 23, 6:39 am, Rich rwml...@gmail.com wrote: . should be set by default. I verified that it was set using (. System getProperties). I also tried explicitly setting the absolute path using -cp. No luck on either count. -Rich- On Mar 23, 5:14 am, revoltingdevelopment christopher.jay.jo...@gmail.com wrote: I also had the NO_SOURCE_FILE error when using contrib packages, upon upgrade to 20090320. My CLASSPATH included .. I had to revert to starting clojure with an explicit -cp. I'm new to both Java and Clojure, but this led me to think my CLASSPATH was being ignored. I chalked it up to my misunderstanding or not really keeping track of how I had things set up before, but it seemed different. On Mar 23, 9:24 am, Mark Volkmann r.mark.volkm...@gmail.com wrote: On Mon, Mar 23, 2009 at 7:34 AM, Rich rwml...@gmail.com wrote: Structure.clj does call ns as shown below: (ns Structure) So, as far as I can tell, Clojure should look for Structure.clj in the class path. At least, that's what it used to do. I guess I could move all the code into a sub-directory, and rename all the namespaces--but I'd rather keep it organized the way it is, if possible. Do you have . or the current directory in CLASSPATH? On Mar 23, 1:33 am, Mark Volkmann r.mark.volkm...@gmail.com wrote: On Mon, Mar 23, 2009 at 4:59 AM, Rich rwml...@gmail.com wrote: Hi, I'd been using the 20081217 release. The following code worked, as long as Structure was in the working directory: Clojure user= (use 'Structure) nil However, after I updated to 20090320, I get the following errors: Clojure user= (use 'Structure) java.io.FileNotFoundException: Could not locate Structure__init.class or Structure.clj on classpath: (NO_SOURCE_FILE:0) In both cases, I'm launching Clojure from the directory that contains Structure.clj as follows: java clojure.lang.Repl What am I doing wrong? Does Structure.clj contain a call to the ns macro? If so, I think you need to move Structure.clj to a subdirectory that matches its namespace. For example, if the namespace is a.b.c then you need a directory in the classpath that contains an a directory that contains a b directory that conains c.clj, not Structure.clj. -- 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: Suggestion for Java Clojure code, use of checkstyle or code formatter
Javadoc would be nice, but I do note that Rich's Java code is pretty darn clear ;) I also note the indentation style is similar to Whitesmith's according to Wikipedia http://en.wikipedia.org/wiki/Indent_style. I've always preferred the BSD curly brace level matching convention over the KR derivatives. That said aren't we all hacking on Clojure because we're done with this convention thing? ;) David On Tue, Mar 24, 2009 at 8:05 AM, Laurent PETIT laurent.pe...@gmail.comwrote: Why you guys want to suppress all the fun from clojure ? ;-) :-p 2009/3/24 Mark Volkmann r.mark.volkm...@gmail.com +1 for running all the code under src/jvm through some code formatter that uses something at least similar to the Sun Java conventions. On Mon, Mar 23, 2009 at 11:59 PM, BerlinBrown berlin.br...@gmail.com wrote: I was curious about how some of the clojure code worked and observed that the coding style is a little bit non idiomatic from typical Java coding conventions. E.g. there aren't any javadoc comments on methods or classes, non standard indents. Something like checkstyle might prove useful. http://checkstyle.sourceforge.net/ While, every programmer balks at conventions, I am sure there is a mountain of evidence for increased overall maintenance and other benefits. I know, I will get suggestions for clojure/lisp coding style. -- 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: Is Clojure's lack of support for forward referencing a feature or a bug?
For what it's worth I'm a big fan of the wishful thinking programming style. I write some functions how I think they should look, declare the functions I haven't defined yet. Then I implement the lower level functions, write some tests- then usually the higher level stuff works without too much tweaking. In a non-functional programming language this doesn't work so well, but it's a good fit for something like Clojure. On Thu, Mar 26, 2009 at 1:42 AM, Timothy Pratley timothyprat...@gmail.comwrote: Hi Mark, A fuller discussion can be found here: http://groups.google.com/group/clojure/browse_thread/thread/a99b420d5ee0aa40/47f8c2ab6845e9ae Which has links to the simple patch I tried, and discusses the more advanced technique Laurent experimented with. Elena subsequently developed an emacs plugin which looks interesting (I'm a VI ninja though so haven't used it) http://groups.google.com/group/clojure/browse_thread/thread/ca7076f4c6591fdd/cda5cf10b89a3679 My own experience FWIW was that it was great for two weeks coding with autodef, then for about a week I became frustrated with my typos and disabled it. More promising solutions might come from an external tool (such as Knuth's literate programming noweb) or IDE support like Elena described. For now my work flow is write the code backwards (ie: manually move the cursor up) and/or chopping and pasting. Then when I'm happy with it, I re-chop it all in my 'preferred' order and put a declare at the top. That sounds quite inefficient, but VI is really great for re- organizing text blocks so it is not too strenuous. That said, I'm really interested in ways that literate programming style can be followed with the least external support. Regards, Tim. On Mar 26, 4:15 pm, Mark Engelberg mark.engelb...@gmail.com wrote: On Wed, Mar 11, 2009 at 5:18 PM, Timothy Pratley timothyprat...@gmail.com wrote: It is also quite trivial to patch the compiler to auto-def symbols as it finds them instead of throwing an error. I would be interested in knowing how to do such a patch. When I work on code, I like to organize my functions in a way that makes it easy to read and understand what is going on. As I work on longer chunks of Clojure code, I'm finding that shuffling around the functions to avoid a lot of forward declarations is destroying the readability of my code. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: oo
On Sat, Mar 28, 2009 at 4:40 PM, mikel mev...@mac.com wrote: So, at minimum, to make a solid port, you need to add a function that can return a sensible type value for any input Enjoying the thread. Out of curiosity for which Clojure values is the return value of the type function undefined? David --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Possible Solution for Left-Right Precedence and More when using Multimethods? (was re: oo)
Having thought a little about multiple inheritance when implementing Spinoza I also ran into this problem. However at the time I wasn't hindered by multifn dispatch as much as the fact that parents cannot be ordered (because calling parents on a tag returns a set) as pointed out by Mark. I understand Rich's point that hierarchies probably shouldn't be directional, but for the sake of practicality why not allow the programmer to specify that a tag (or even the whole hierarchy) should in fact have its relationships be ordered? In general prefer-method seemed to me (I could be wrong) to be a last attempt solution- when there is just no other way to resolve an ambiguity, and this ambiguity is not of the hierarchy, but of multimethod dispatch. As pointed out by Konrad Rich, you can work around the limitation of hierarchies right now with a lot of prefer-methods. But as Mikel points out, with current state of prefer-method you have to hunt through code to find out where these prefers were made and for what reason and they assume that you've already written your methods (this for me is the deal breaker). In anycase my general feeling (in agreement with Mark) is that the problem isn't with multifns but rather with how hierarchies are constructed. So the achilles heel of hierarchies seems to be that when you call parents (and related fns) on a tag you get a set - it has no order. For single inheritance hierarchies this is fine, but for multiple inheritance I think this becomes a problem a very fast. Working on Spinoza, I realized I would have to keep my own ordered list of parents in order to support left-right precedence, basically keeping an ordered copy of the whole hierarchy. Again prefer-method is only useful for fixing method-level ambiguities. There's no general way to say, type A always precedes type B without writing quite a bit of explicit code (or hiding the problem away with macros). Here's something that might kick of a dicussion to a proper solution (I am sure there are some gaps in my logic), why not allow something like the following? ;; allow control of how tags get introduced into the hierarchy (def h (make-hierarchy :parents-fn fn1 :ancestors-fn fn2 :descendants-fn fn3)) ;; add a new parent insertion fn to a hierarchy (add-parents-fn h fn4) ;; - returns a new hierarchy with the parents fn set, all parents sets are converted into vectors ;; add a new parent insertion fn to a hierarchy for a specific key, only the parents of ::my-tag are converted into a vector (add-parents-fn h fn4 ::my-tag) ;; a hierarchy fn might look something like the following (defn my-parents-fn [parents new-key] (conj parents new-key)) If my thinking is correct this is pretty flexible. This doesn't break the meaning of hierarchy for any existing code. It doesn't change the signature of multimethods. Yet now a user can provide fns that sorts a hierarchy anyway they please, and it doesn't even have to be the entire hierarchy. This code will probably live in one spot where anyone could look to understand how the hierarchy is being constructed. All high-level precedence ambiguities can now be resolved by looking at the hierarchy. prefer-method does only what it was intended to do- resolve method level ambiguity. David --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: new in contrib.test-is: fixtures
very cool :) On 3/28/09, Stuart Sierra the.stuart.sie...@gmail.com wrote: Hi folks, I finally came up with fixtures for clojure.contrib.test-is. Now you can do before/after setup for each test case. Here's the documentation, let me know what you think. -Stuart Sierra ;; FIXTURES (new) ;; ;; Fixtures allow you to run code before and after tests, to set up ;; the context in which tests should be run. ;; ;; A fixture is just a function that calls another function passed as ;; an argument. It looks like this: (defn my-fixture [f] ;; Perform setup, establish bindings, whatever. (f) ;; Then call the function we were passed. ;; Tear-down / clean-up code here. ) ;; Fixtures are attached to namespaces in one of two ways. each ;; fixtures are run repeatedly, once for each test function created ;; with deftest or with-test. each fixtures are useful for ;; establishing a consistent before/after state for each test, like ;; clearing out database tables. ;; ;; each fixtures can be attached to the current namespace like this: (use-fixtures :each fixture1 fixture2 ...) ;; The fixture1, fixture2 are just functions like the example above. ;; They can also be anonymous functions, like this: (use-fixtures :each (fn [f] setup... (f) cleanup...)) ;; ;; The other kind of fixture, a once fixture, is only run once, ;; around ALL the tests in the namespace. once fixtures are useful ;; for tasks that only need to be performed once, like establishing ;; database connections, or for time-consuming tasks. ;; ;; Attach once fixtures to the current namespace like this: (use-fixtures :once fixture1 fixture2 ...) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: oo
On Sun, Mar 29, 2009 at 1:25 AM, mikel mev...@mac.com wrote: (type (proxy [clojure.lang.IMeta clojure.lang.IRef][])) java.lang.UnsupportedOperationException: meta (NO_SOURCE_FILE:0) [Thrown class clojure.lang.Compiler$CompilerException] No doubt someone is going to point out that the proxy object I created there is useless; that's true, but beside the point. The point is that it's straightforward to create some value v for which (type v) is undefined. In order to make a Clojure-friendly version of CLOS, you need some concept of object type such that you can define a function that returns a sensible type for any value. Not totally following you here as: (proxy [clojure.lang.IMeta clojure.lang.IRef][]) immediately throws an error. I can't think of a situation in Clojure where the type function does not return a usable value. Let me know if I'm wrong, but your example is not a case as far as I can tell. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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's a convenient way of calling super.method()?
Glad to be of help. To be totally honest I hadn't really tested it too much, so I don't know ;) One obvious limitation here is that it doesn't work with multiple inheritance (it only looks at the first item in the parents set). As long you're sticking with a Java-style single inheritance model this doesn't really present much of a problem. I'll clean it up when I have some extra time and add some test cases, provide a small readme listing limitations, and host it on GitHub for anyone else that needs this behavior. David On Sun, Mar 29, 2009 at 8:20 AM, CuppoJava patrickli_2...@hotmail.comwrote: Thanks a lot for that David, It works perfectly for me. Are there any circumstances where it doesn't work? I haven't run into any yet, but if there are, I'll design my program around it. -Patrick --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Please suggest a way to learn just enough Java for Clojure
There's a few posts on the mailing list suggesting some good starting points. You can get far in Clojure without resorting to Java but it definitely helps to know some if you really want to advance your knowledge of Clojure's inner workings as well as get it to interoperate with Java libraries. On Mon, Mar 30, 2009 at 12:41 PM, Santanu thisissant...@gmail.com wrote: Hi Everybody, (Sorry if this post appears twice, but the first post seems to have vanished) I have recently downloaded Clojure and am learning it. As of now, I feel that to do anything substantial with Clojure, I have to be able to know how to access the Java libraries from within Clojure. But the problem is, I don't know Java. I know C, some Scheme, little bit Haskell, etc. but no Java. I am not interested in Java anyway. I downloaded Java documentation and am trying to go through interesting looking functions to try and use from within Clojure. But with no knowledge of Java, I am having problems exploring the various functions in the Java libraries. Could you please suggest any Java book (and the relevant chapters) that will teach me _just_enough_ Java so that I can understand how to use the Java library documentation effectively. Thanks in advance. Regards, Santanu Chatterjee --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 need help tracking down a performance problem.
Did you try using aset-int instead of aset? On Tue, Mar 31, 2009 at 8:25 AM, Vincent Foley vfo...@gmail.com wrote: For those interested, I managed to improve the performance of my original program from 2 minutes 40 seconds to decode 1000+ files down to 2 minutes. I'm still far from my goal, but it's an improvement, especially since the code is shorter and (IMO) cleaner. You can see it here: http://bitbucket.org/gnuvince/clj-starcraft/src/tip/src/starcraft/replay/parse.clj And here's another question, running the program with -Xprof shows that nearly 20% of my execution time is spent calling java.lang.reflect.Array.set. Is there something wrong with the way I type hint my array in make-reader? Thanks, Vincent. On Mar 19, 8:12 pm, Vincent Foley vfo...@gmail.com wrote: Hello, For the past few days, I've been trying, unsuccessfully, to make an application I wrote faster. A Java program that performs, more or less, the same task takes 12 seconds (on my machine) to parse 1000 files; my Clojure program takes nearly 3 minutes. This more than an order of magnitude slower! Using the profiling tools available with the JVM, I quickly determined which function was the costliest. I copied it into a simple script file to profile it in isolation. I have made the script and the profile results (long!) available at this URL:http://gist.github.com/82136 I'm finding the results puzzling: is dereferencing a var *that* expensive? Can anyone tell me if they see something fundamentally wrong with my approach that would explain this abysmal performance? Thank you, Vincent. P.S.: I am using Sun's JVM 1.6.0_10 as shipped in Ubuntu Ibex. My machine is an Athlon 64 X2 4200+ with 3 GB of RAM. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 need help tracking down a performance problem.
Thanks to cl-format: (fn [buf__2572__auto__ len__2573__auto__] (if (= len__2573__auto__ 1) (mask8 (. buf__2572__auto__ (get))) (let [arr__2574__auto__ (int-array len__2573__auto__)] (dotimes [i__2575__auto__ len__2573__auto__] (aset-int arr__2574__auto__ i__2575__auto__ (mask8 (. buf__2572__auto__ (get) arr__2574__auto__))) This is the expansion for (make-reader get mask8), where were you attempting putting the int coercion to to the mask-fn? David On Tue, Mar 31, 2009 at 11:38 AM, Vincent Foley vfo...@gmail.com wrote: I tried using aset-int and I tried using int to coerce the result of mask-fn, the input argument to mask-fn and few other things, but none of that seems to make a difference so far. Mind you, this is an aspect of Clojure that I find a little confusing, so I'm just putting int calls here and there and looking at what happens. On Mar 31, 10:46 am, Christophe Grand christo...@cgrand.net wrote: Did you try to coerce the result of (~mask-fn ...) with int? (or use aset-int as suggested by David) On Tue, Mar 31, 2009 at 4:17 PM, Vincent Foley vfo...@gmail.com wrote: No, but in my defense I did not know such a function existed :) I'll give it a whirl and report back! On Mar 31, 9:57 am, David Nolen dnolen.li...@gmail.com wrote: Did you try using aset-int instead of aset? On Tue, Mar 31, 2009 at 8:25 AM, Vincent Foley vfo...@gmail.com wrote: For those interested, I managed to improve the performance of my original program from 2 minutes 40 seconds to decode 1000+ files down to 2 minutes. I'm still far from my goal, but it's an improvement, especially since the code is shorter and (IMO) cleaner. You can see it here: http://bitbucket.org/gnuvince/clj-starcraft/src/tip/src/starcraft/rep. .. And here's another question, running the program with -Xprof shows that nearly 20% of my execution time is spent calling java.lang.reflect.Array.set. Is there something wrong with the way I type hint my array in make-reader? Thanks, Vincent. On Mar 19, 8:12 pm, Vincent Foley vfo...@gmail.com wrote: Hello, For the past few days, I've been trying, unsuccessfully, to make an application I wrote faster. A Java program that performs, more or less, the same task takes 12 seconds (on my machine) to parse 1000 files; my Clojure program takes nearly 3 minutes. This more than an order of magnitude slower! Using the profiling tools available with the JVM, I quickly determined which function was the costliest. I copied it into a simple script file to profile it in isolation. I have made the script and the profile results (long!) available at this URL:http://gist.github.com/82136 I'm finding the results puzzling: is dereferencing a var *that* expensive? Can anyone tell me if they see something fundamentally wrong with my approach that would explain this abysmal performance? Thank you, Vincent. P.S.: I am using Sun's JVM 1.6.0_10 as shipped in Ubuntu Ibex. My machine is an Athlon 64 X2 4200+ with 3 GB of RAM. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 need help tracking down a performance problem.
ticks 2.1% 246 Received GC ticks 4.3% 495 Compilation 0.0% 2 Other VM operations 0.0% 1 Class loader 0.0% 2 Unknown code 176.257 secs On Mar 31, 8:57 pm, David Nolen dnolen.li...@gmail.com wrote: Thanks to cl-format: (fn [buf__2572__auto__ len__2573__auto__] (if (= len__2573__auto__ 1) (mask8 (. buf__2572__auto__ (get))) (let [arr__2574__auto__ (int-array len__2573__auto__)] (dotimes [i__2575__auto__ len__2573__auto__] (aset-int arr__2574__auto__ i__2575__auto__ (mask8 (. buf__2572__auto__ (get) arr__2574__auto__))) This is the expansion for (make-reader get mask8), where were you attempting putting the int coercion to to the mask-fn? David On Tue, Mar 31, 2009 at 11:38 AM, Vincent Foley vfo...@gmail.com wrote: I tried using aset-int and I tried using int to coerce the result of mask-fn, the input argument to mask-fn and few other things, but none of that seems to make a difference so far. Mind you, this is an aspect of Clojure that I find a little confusing, so I'm just putting int calls here and there and looking at what happens. On Mar 31, 10:46 am, Christophe Grand christo...@cgrand.net wrote: Did you try to coerce the result of (~mask-fn ...) with int? (or use aset-int as suggested by David) On Tue, Mar 31, 2009 at 4:17 PM, Vincent Foley vfo...@gmail.com wrote: No, but in my defense I did not know such a function existed :) I'll give it a whirl and report back! On Mar 31, 9:57 am, David Nolen dnolen.li...@gmail.com wrote: Did you try using aset-int instead of aset? On Tue, Mar 31, 2009 at 8:25 AM, Vincent Foley vfo...@gmail.com wrote: For those interested, I managed to improve the performance of my original program from 2 minutes 40 seconds to decode 1000+ files down to 2 minutes. I'm still far from my goal, but it's an improvement, especially since the code is shorter and (IMO) cleaner. You can see it here: http://bitbucket.org/gnuvince/clj-starcraft/src/tip/src/starcraft/rep. .. And here's another question, running the program with -Xprof shows that nearly 20% of my execution time is spent calling java.lang.reflect.Array.set. Is there something wrong with the way I type hint my array in make-reader? Thanks, Vincent. On Mar 19, 8:12 pm, Vincent Foley vfo...@gmail.com wrote: Hello, For the past few days, I've been trying, unsuccessfully, to make an application I wrote faster. A Java program that performs, more or less, the same task takes 12 seconds (on my machine) to parse 1000 files; my Clojure program takes nearly 3 minutes. This more than an order of magnitude slower! Using the profiling tools available with the JVM, I quickly determined which function was the costliest. I copied it into a simple script file to profile it in isolation. I have made the script and the profile results (long!) available at this URL:http://gist.github.com/82136 I'm finding the results puzzling: is dereferencing a var *that* expensive? Can anyone tell me if they see something fundamentally wrong with my approach that would explain this abysmal performance? Thank you, Vincent. P.S.: I am using Sun's JVM 1.6.0_10 as shipped in Ubuntu Ibex. My machine is an Athlon 64 X2 4200+ with 3 GB of RAM. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 need help tracking down a performance problem.
15.1% 0 + 1711java.lang.reflect.Array.setInt Is definitely pointing at the aset-int as being the time gobbler, I think the expression in the macro should be this (aset-int (ints arr#) i# (int (~mask-fn (. buf# (~get-fn) to be extra safe. On Tue, Mar 31, 2009 at 10:00 PM, Vincent Foley vfo...@gmail.com wrote: I tried it just now; it made no difference. Nevertheless, thank you for you help and time! On Mar 31, 9:38 pm, David Nolen dnolen.li...@gmail.com wrote: Did you try (int (mask8 (. buf__2572__auto__ (get ? Your macro should like this: (defmacro make-reader [get-fn mask-fn] `(fn [#^ByteBuffer buf# len#] (if (= len# 1) (~mask-fn (. buf# (~get-fn))) (let [#^[I arr# (int-array len#)] (dotimes [i# len#] (aset-int arr# i# (int (~mask-fn (. buf# (~get-fn)) arr# On Tue, Mar 31, 2009 at 9:09 PM, Vincent Foley vfo...@gmail.com wrote: I tried surrounding the call to the (. buf# (get)) method and putting the coercion directly inside the mask8 and mask16 functions. Neither worked. I want to mention at this point that I have *warn-on- reflection* set to true for the little script that uses the library and it doesn't report any call to methods that it can't resolve. Here's the complete -Xprof output, if it helps. Flat profile of 176.10 secs (11351 total ticks): main Interpreted + native Method 4.5% 511 + 0java.lang.Integer.hashCode 1.4% 160 + 0java.lang.Integer.intValue 0.8%91 + 0starcraft.replay.unpack $decode_command_block__94.invoke 0.7%80 + 0clojure.lang.Numbers.int_array 0.2%25 + 0clojure.lang.PersistentVector.pushTail 0.1%15 + 2java.lang.ClassLoader.defineClass1 0.1%16 + 0 hu.belicza.andras.bwhf.control.BinReplayUnpacker.esi28 0.1% 4 +11clojure.core__init.load 0.1%10 + 0clojure.lang.PersistentVector.cons 0.1% 8 + 0starcraft.replay.actions$fn__71.invoke 0.1% 8 + 0 hu.belicza.andras.bwhf.control.BinReplayUnpacker.unpackSection 0.1% 0 + 7java.lang.reflect.Array.setInt 0.1% 7 + 0clojure.lang.PersistentHashMap $BitmapIndexedNode.create 0.1% 7 + 0clojure.lang.RestFn.invoke 0.1% 7 + 0clojure.lang.RestFn.invoke 0.1% 7 + 0starcraft.replay.unpack $decode_commands__99.invoke 0.1% 7 + 0starcraft.replay.parse $parse_buffer__53$fn__56.invoke 0.1% 6 + 0clojure.lang.AFn.applyToHelper 0.1% 6 + 0clojure.lang.PersistentArrayMap.assoc 0.1% 6 + 0clojure.lang.PersistentHashMap $BitmapIndexedNode.assoc 0.0% 0 + 5java.lang.reflect.Array.newArray 0.0% 0 + 5java.lang.Class.forName0 0.0% 0 + 5java.util.zip.Inflater.inflateBytes 0.0% 5 + 0java.lang.AbstractStringBuilder.init 0.0% 5 + 0java.util.Arrays.copyOfRange 10.9% 1157 +76Total interpreted (including elided) Compiled + native Method 10.4% 1183 + 1starcraft.replay.parse$fn__23$fn__49.invoke 10.0% 1123 +17starcraft.replay.unpack $decode_command_block__94.invoke 9.2% 1043 + 0clojure.core$next__3096.invoke 8.9% 1014 + 0starcraft.replay.parse $parse_buffer__53$fn__56.invoke 5.5% 626 + 0clojure.lang.PersistentArrayMap.assoc 4.3% 474 +17clojure.lang.PersistentArrayMap.assoc 4.1% 464 + 7clojure.lang.RestFn.invoke 2.9% 333 + 0clojure.lang.Cons.next 2.5% 288 + 0clojure.lang.RT.seq 2.4% 269 + 0clojure.lang.AFn.applyToHelper 2.2% 249 + 0 hu.belicza.andras.bwhf.control.BinReplayUnpacker.unpackRepChunk 1.8% 202 + 0clojure.core$seq__3112.invoke 1.6% 174 + 3clojure.lang.RestFn.applyTo 1.3% 140 + 2clojure.lang.APersistentMap.cons 1.2% 130 + 1clojure.core$spread__3225.invoke 1.1% 127 + 0clojure.lang.PersistentStructMap.valAt 0.8%93 + 0clojure.core$reduce__3304.invoke 0.6%66 + 2starcraft.replay.unpack $decode_commands__99.invoke 0.6%63 + 0clojure.lang.PersistentArrayMap.valAt 0.1%13 + 1clojure.core$conj__3100.invoke 0.1% 9 + 0clojure.lang.APersistentMap.invoke 0.1% 3 + 6starcraft.replay.parse $fn__23$read_shorts__37.invoke 0.1% 8 + 0clojure.core$nthnext__4405.invoke 0.1% 0 + 7clojure.lang.ArraySeq.next 0.0% 0 + 5clojure.lang.APersistentVector.assoc 72.3% 8126 +76Total compiled (including elided) Stub + native Method 15.1% 0 + 1711
Re: - vs. comp
comp creates a new function that you can store. - threads a value through a series of expressions. On Wed, Apr 1, 2009 at 12:52 AM, kkw kevin.k@gmail.com wrote: Hi folks, I have some code where I wanted to: - take a list of stuff (which includes another list inside) - use 'seq-utils/flatten' to flatten the list - use 'interpose' to add comma-delimiting strings between the elements - print out the results, thereby creating comma-delimited output I may choose between: ((comp (fn [x] (apply println x)) (fn [x] (interpose , x)) seq-utils/flatten) mr) OR (- mr seq-utils/flatten ((fn [x] (interpose , x))) ((fn [x] (apply println x And I found the - notation marginally easier to interpret and understand. Apart from appearance, are there any benefits to using - instead of the comp function? I happily concede that there exist nicer ways to achieve this goal, but the question I wanted to raise concerned the benefits of using - vs comp or vice-versa. Kev Kev --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Possible Solution for Left-Right Precedence and More when using Multimethods? (was re: oo)
Very cool. On Wed, Apr 1, 2009 at 8:47 AM, Rich Hickey richhic...@gmail.com wrote: I've added get-method (SVN 1338). (derive ::Circle ::Shape) (derive ::Rect ::Shape) (defmulti area :Shape) ;note - you can name methods (defmethod area ::Shape area-shape [x] nil) (get-method area ::Rect) #user$area_shape__43 user$area_shape_...@674a93a6 (defmethod area ::Rect area-rect [r] (* (:wd r) (:ht r))) (defmethod area ::Circle area-circ [c] (* (. Math PI) (* (:radius c) (:radius c (get-method area ::Rect) #user$area_rect__18 user$area_rect_...@4e42751f (get-method area ::Circ) ;not there nil (get-method area ::Circle) #user$area_circ__20 user$area_circ_...@74da0c91 ;if you don't think squares are rectangles, you can still reuse implementation (silly example) (defmethod area ::Square area-square [sqr] ((get-method area ::Rect) {:wd (:dim sqr) :ht (:dim sqr)})) (area {:Shape ::Square :dim 20}) 400 Note how you can name methods for diagnostic purposes. This doesn't introduce names into the namespace, just puts a name on the fn object. Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Array of primitives
you should look into float-array and friends. On Fri, Apr 3, 2009 at 12:04 AM, Sean francoisdev...@gmail.com wrote: I'm working with AWT, and there is a method that requires a float[] (The java.awt.BasicStroke constructor). Is it possible to directly create an array of primitives directly in Clojure, or do I need to create a utility class in Java? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 dosync/alter question
I think what you want is: (def foo (ref 0)) (defn square [x] (* x x)) (defn square-ref [x] (dosync (ref-set foo (square x (square-ref 2) On Mon, Apr 6, 2009 at 3:02 PM, bgray graybran...@gmail.com wrote: I have a some what (I believe) easy question. Could someone let me know what I'm doing wrong? A simplified version of what I'm trying to do looks like this: user= (def foo (ref 0)) #'user/foo user= (defn square [x] (* x x)) #'user/square user= (defn square-ref [x] (dosync (alter foo square x))) #'user/square-ref user= (square-ref 2) java.lang.IllegalArgumentException: Wrong number of args passed to: user$square (NO_SOURCE_FILE:0) user= (doc square) - user/square ([x]) nil nil user= Thanks, Brandon --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this 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 large Clojure deployment
Congrats! Perhaps soon there should be a Projects Using Clojure section on the main site? Good way to get the word out that people are using Clojure in the real world David On Tue, Apr 7, 2009 at 10:47 AM, Sean francoisdev...@gmail.com wrote: Okay wow... it'll take some time to fully appreciate this. Can you comment on your hardware stack? How many servers are you using? Is there an RDBMS in there somewhere? How was deployment? Looks awesome, thanks for sharing! On Apr 7, 10:41 am, Stuart Sierra the.stuart.sie...@gmail.com wrote: Here: http://www.altlaw.org/ About 4000 lines of Clojure code, 2500 of Java, powering a web site with well over a million pages, averaging around 10,000 visitors a day. Some of what I'm using: Restlet StringTemplate Solr Hadoop Apache Java Commons markdownj cpdetector JRuby Most of the code is online, GPL'd, athttp://github.com/lawcommons -Stuart Sierra --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure on Google AppEngine
Very exciting, thanks for the excellent and informative writeup. On Wed, Apr 8, 2009 at 12:41 AM, John D. Hume duelin.mark...@gmail.comwrote: As predicted, Google has now released Java support for AppEngine. I was lucky enough to get an early look, which I dedicated entirely to Clojure. Here's a writeup: http://elhumidor.blogspot.com/2009/04/clojure-on-google-appengine.html Have fun! -hume. -- http://elhumidor.blogspot.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: Enlive questions
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)) 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. David On Wed, Apr 8, 2009 at 8:06 PM, Christophe Grand christo...@cgrand.netwrote: Hi Tom, I'm sorry for this misfeature and, rejoice, it's gone from the ongoing redesign, there's now an explicit 'content function. The tildes are gone too! Christophe Tom Hickey a écrit : Hi Christophe, I keep running into the same problem with elements getting replaced. I'm trying to set the content of an element with raw html (from a snippet) and unable to avoid both 1) the html getting escaped and 2) the element getting replaced. I can avoid one or the other, via escaped or text, just not both. I'm looking forward to see what you've got planned for the redesign, as I'd really like to see this feature go away. Cheers, Tom On Mar 20, 3:59 am, Christophe Grand christo...@cgrand.net wrote: Phil Hagelberg a écrit : But I did notice you have the use test-is line commented out in the implementation; it seems a bit unfortunate to have to uncomment that to run the tests and hope you remember to re-comment it before you commit. The last commit was during the transition to lazy-seq and test-is was broken. I'll fix that. -- Professional:http://cgrand.net/(fr) On Clojure:http://clj-me.blogspot.com/(en) -- 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: Enlive questions
Real quick thought: (deftemplate-generator template-generator [args] rule-vector transform-fn) Would produce a template generator. (def template-name (template-generator path-to-xml-or-file-or-xml-string)) Would produce a real template. (apply str (template-name arg1 arg2 arg3)) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Amb operator
Using try-catch for control flow is probably not a good idea. Shameless plug, do you think you could get this to work with clj-cont? clj-cont is a port I did of cl-cont. It has some limitations, but because Clojure has so few special forms (compared to Common Lisp), it has the chance to achieve pretty good coverage. I'm trying to get it working with compojure and enlive for web development a la Seaside and Weblocks- it would be interesting to see what other uses it might have. 2009/4/10 André Ferreira greis...@gmail.com So, I was wondering if anyone had implemented the amb operator in Clojure, so I decided to give it a try. This is my first Clojure program bigger then 5 lines, the code still needs ALOT of work, it is ugly as hell atm, but I think it kind of works. (Yes, I know, it's very easy to bug it, its just a sketch). Notice that unlike most continuation based amb operators, the amount of backtracking this implementation has to do depends on the order of the requires, not the amb assignments. If anyone wants to clear or improve the code, go ahead. I also would like to know how to be able to write @baker instead of the current (myderef baker), I tried using a proxy and implementing IDeref, but then I couldn't acess the amb-struct private data. Since Clojure doesn't have continuations I had to use a try catch block to do the stack unwinding, and some redundant calculations might be done because of it. Here is the code: (defstruct amb-struct :instance :orig :possible) (def amb-stack nil) (defn amb [choices] (struct-map amb-struct :instance false :orig choices :possible choices)) (defn myderef [a] (if (:instance @a) (:value @a) (do (set! amb-stack (cons a amb-stack)) (let [oldpos (:possible @a)] (var-set a (assoc @a :value (first oldpos) :instance true :possible (rest oldpos (:value @a (defn amb-require [condition] (if condition nil (do (throw (.Exception nothing) (defn bindnext [] (if (empty? amb-stack) 'nomatchfound (let [lastbind (first amb-stack) oldpos (:possible @lastbind)] (if (empty? oldpos) (do (var-set lastbind (assoc @lastbind :instance false :possible (:orig @lastbind))) (set! amb-stack (rest amb-stack)) (recur)) (do (var-set lastbind (assoc @lastbind :value (first oldpos) :possible (rest oldpos))) 'recur) (defmacro amb-let [declarations body] `(with-local-vars ~declarations (binding [amb-stack nil] (loop [] (let [retvalue# (try (do ~...@body) (catch Exception ~'except (bindnext)))] (cond (= retvalue# 'recur) (recur) true retvalue#)) (defn distinct-seq? [s] (cond (empty? (rest s)) true (= (first s) (second s)) false true (and (distinct-seq? (cons (first s) (rest (rest s (distinct-seq? (rest s) (amb-let [baker (amb [1 2 3 4 5]) cooper (amb [1 2 3 4 5]) fletcher (amb [1 2 3 4 5]) miller (amb [1 2 3 4 5]) smith (amb [1 2 3 4 5])] (amb-require (distinct-seq? (map myderef (list baker cooper fletcher miller smith (amb-require (not (= (myderef baker) 5))) (amb-require (not (= (myderef cooper) 1))) (amb-require (not (= (myderef fletcher) 1))) (amb-require (not (= (myderef fletcher) 5))) (amb-require ( (myderef miller) (myderef cooper))) (amb-require (not (= 1 (. java.lang.Math abs (- (myderef smith) (myderef fletcher)) (amb-require (not (= 1 (. java.lang.Math abs (- (myderef fletcher) (myderef cooper)) [['baker (myderef baker)] ['cooper (myderef cooper)] ['fletcher (myderef fletcher)] ['miller (myderef miller)] ['smith (myderef smith)]]) Running it returns [[baker 3] [cooper 2] [fletcher 4] [miller 5] [smith 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 To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Amb operator
One caveat is that because this works by transforming the code into Continuation Passing Style, it's dog slow, like 2 orders of magnitude for regular Clojure code. This is not really much of an issue for user interface related code (which is what I'm using it for), but unrealistic for pretty much anything else. However, with some quick testing I note that using Exceptions for flow control might be even 2x slower than clj-cont. On Mon, Apr 13, 2009 at 1:54 PM, David Nolen dnolen.li...@gmail.com wrote: Using try-catch for control flow is probably not a good idea. Shameless plug, do you think you could get this to work with clj-cont? clj-cont is a port I did of cl-cont. It has some limitations, but because Clojure has so few special forms (compared to Common Lisp), it has the chance to achieve pretty good coverage. I'm trying to get it working with compojure and enlive for web development a la Seaside and Weblocks- it would be interesting to see what other uses it might have. 2009/4/10 André Ferreira greis...@gmail.com So, I was wondering if anyone had implemented the amb operator in Clojure, so I decided to give it a try. This is my first Clojure program bigger then 5 lines, the code still needs ALOT of work, it is ugly as hell atm, but I think it kind of works. (Yes, I know, it's very easy to bug it, its just a sketch). Notice that unlike most continuation based amb operators, the amount of backtracking this implementation has to do depends on the order of the requires, not the amb assignments. If anyone wants to clear or improve the code, go ahead. I also would like to know how to be able to write @baker instead of the current (myderef baker), I tried using a proxy and implementing IDeref, but then I couldn't acess the amb-struct private data. Since Clojure doesn't have continuations I had to use a try catch block to do the stack unwinding, and some redundant calculations might be done because of it. Here is the code: (defstruct amb-struct :instance :orig :possible) (def amb-stack nil) (defn amb [choices] (struct-map amb-struct :instance false :orig choices :possible choices)) (defn myderef [a] (if (:instance @a) (:value @a) (do (set! amb-stack (cons a amb-stack)) (let [oldpos (:possible @a)] (var-set a (assoc @a :value (first oldpos) :instance true :possible (rest oldpos (:value @a (defn amb-require [condition] (if condition nil (do (throw (.Exception nothing) (defn bindnext [] (if (empty? amb-stack) 'nomatchfound (let [lastbind (first amb-stack) oldpos (:possible @lastbind)] (if (empty? oldpos) (do (var-set lastbind (assoc @lastbind :instance false :possible (:orig @lastbind))) (set! amb-stack (rest amb-stack)) (recur)) (do (var-set lastbind (assoc @lastbind :value (first oldpos) :possible (rest oldpos))) 'recur) (defmacro amb-let [declarations body] `(with-local-vars ~declarations (binding [amb-stack nil] (loop [] (let [retvalue# (try (do ~...@body) (catch Exception ~'except (bindnext)))] (cond (= retvalue# 'recur) (recur) true retvalue#)) (defn distinct-seq? [s] (cond (empty? (rest s)) true (= (first s) (second s)) false true (and (distinct-seq? (cons (first s) (rest (rest s (distinct-seq? (rest s) (amb-let [baker (amb [1 2 3 4 5]) cooper (amb [1 2 3 4 5]) fletcher (amb [1 2 3 4 5]) miller (amb [1 2 3 4 5]) smith (amb [1 2 3 4 5])] (amb-require (distinct-seq? (map myderef (list baker cooper fletcher miller smith (amb-require (not (= (myderef baker) 5))) (amb-require (not (= (myderef cooper) 1))) (amb-require (not (= (myderef fletcher) 1))) (amb-require (not (= (myderef fletcher) 5))) (amb-require ( (myderef miller) (myderef cooper))) (amb-require (not (= 1 (. java.lang.Math abs (- (myderef smith) (myderef fletcher)) (amb-require (not (= 1 (. java.lang.Math abs (- (myderef fletcher) (myderef cooper)) [['baker (myderef baker)] ['cooper (myderef cooper)] ['fletcher (myderef fletcher)] ['miller (myderef miller)] ['smith (myderef smith)]]) Running it returns [[baker 3] [cooper 2] [fletcher 4] [miller 5] [smith 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 To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Amb operator
Wow, this is very interesting, on a MBP 2.53 JDK 1.6 ;; ~2.5 seconds (time (dotimes [_ 100] (new Exception))) ;; ~40ms or 62X faster (time (let [exc (new Exception)] (dotimes [_ 100] (try (throw exc) (catch Exception _) However does also means that you're throwing away the away stack trace making debugging more difficult? It got me thinking about arbitrary flow control, on the nested loop thread I've added my findings... On Mon, Apr 13, 2009 at 4:24 PM, Victor Rodriguez vict...@gmail.com wrote: On Mon, Apr 13, 2009 at 2:13 PM, David Nolen dnolen.li...@gmail.com wrote: One caveat is that because this works by transforming the code into Continuation Passing Style, it's dog slow, like 2 orders of magnitude for regular Clojure code. This is not really much of an issue for user interface related code (which is what I'm using it for), but unrealistic for pretty much anything else. However, with some quick testing I note that using Exceptions for flow control might be even 2x slower than clj-cont. Although I have never verified this myself, reputedly it is constructing exceptions what is slow, not throwing or catching them. In other words, for the amb implementation above, it might be worth defining a constant exception and throwing that. (Although I'm confused, I see in the code (.Exception something), shouldn't that be (Exception. something) instead?) Cheers, Victor Rodrigeuz. On Mon, Apr 13, 2009 at 1:54 PM, David Nolen dnolen.li...@gmail.com wrote: Using try-catch for control flow is probably not a good idea. Shameless plug, do you think you could get this to work with clj-cont? clj-cont is a port I did of cl-cont. It has some limitations, but because Clojure has so few special forms (compared to Common Lisp), it has the chance to achieve pretty good coverage. I'm trying to get it working with compojure and enlive for web development a la Seaside and Weblocks- it would be interesting to see what other uses it might have. 2009/4/10 André Ferreira greis...@gmail.com So, I was wondering if anyone had implemented the amb operator in Clojure, so I decided to give it a try. This is my first Clojure program bigger then 5 lines, the code still needs ALOT of work, it is ugly as hell atm, but I think it kind of works. (Yes, I know, it's very easy to bug it, its just a sketch). Notice that unlike most continuation based amb operators, the amount of backtracking this implementation has to do depends on the order of the requires, not the amb assignments. If anyone wants to clear or improve the code, go ahead. I also would like to know how to be able to write @baker instead of the current (myderef baker), I tried using a proxy and implementing IDeref, but then I couldn't acess the amb-struct private data. Since Clojure doesn't have continuations I had to use a try catch block to do the stack unwinding, and some redundant calculations might be done because of it. Here is the code: (defstruct amb-struct :instance :orig :possible) (def amb-stack nil) (defn amb [choices] (struct-map amb-struct :instance false :orig choices :possible choices)) (defn myderef [a] (if (:instance @a) (:value @a) (do (set! amb-stack (cons a amb-stack)) (let [oldpos (:possible @a)] (var-set a (assoc @a :value (first oldpos) :instance true :possible (rest oldpos (:value @a (defn amb-require [condition] (if condition nil (do (throw (.Exception nothing) (defn bindnext [] (if (empty? amb-stack) 'nomatchfound (let [lastbind (first amb-stack) oldpos (:possible @lastbind)] (if (empty? oldpos) (do (var-set lastbind (assoc @lastbind :instance false :possible (:orig @lastbind))) (set! amb-stack (rest amb-stack)) (recur)) (do (var-set lastbind (assoc @lastbind :value (first oldpos) :possible (rest oldpos))) 'recur) (defmacro amb-let [declarations body] `(with-local-vars ~declarations (binding [amb-stack nil] (loop [] (let [retvalue# (try (do ~...@body) (catch Exception ~'except (bindnext)))] (cond (= retvalue# 'recur) (recur) true retvalue#)) (defn distinct-seq? [s] (cond (empty? (rest s)) true (= (first s) (second s)) false true (and (distinct-seq? (cons (first s) (rest (rest s (distinct-seq? (rest s) (amb-let [baker (amb [1 2 3 4 5]) cooper (amb [1 2 3 4 5]) fletcher (amb [1 2 3 4 5]) miller (amb [1 2 3 4 5]) smith (amb [1 2 3 4 5])] (amb-require (distinct-seq? (map
Re: Nested loops
Out of simple curiosity I wondered how hard it would be to implement flow control using proxy. I know Rich isn't hot on non-structured programming, but there may be times where this might be useful: (ns flow.return-from (:import (flow IReturnFrom))) (defn create-return-from [value] (proxy [Throwable IReturnFrom] [] (value [ args] value))) (defmacro allow-return-from [form] `(try ~form (catch ~'clojure.proxy.java.lang.Throwable$IReturnFrom e# (.value e# (defmacro return [value] `(throw (create-return-from ~value))) (defn my-loop [count] (dotimes [x count] (if (= x 5) (return x ;; examples (allow-return-from (my-loop 10)) ; - 5 (dotimes [x 5] (allow-return-from (dotimes [y 5] (if (= y 2) (return y) (println x y) In order for the above to work you'll need to compile an interface: ;; compile with the following ;; (binding [*compile-path* /path/to/classes] ;; (compile 'flow.return-from-interface)) (ns flow.return-from-interface) (gen-interface :nameflow.IReturnFrom :methods [[value [] Object]]) Pretty cool. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Javascript generator
Do you have any plans for continuing to support this? If so are you against putting this on GitHub or Google Code so that people can follow it's development? Thanks for contributing it to the community. On Wed, Feb 25, 2009 at 7:49 PM, jim jim.d...@gmail.com wrote: I've just uploaded a javascript generator ala Parenscript. It's pretty half-baked, so be cautious using it until we get the bugs ironed out. http://clojure.googlegroups.com/web/js_gen.clj The code for the generator is about 250 lines. It depends on the mini- kanren implementation I just uploaded. The file also includes a bunch of unit tests of the various functions. At the bottom, there are some examples of javascript functions being generated. Bug reports very much appreciated. Jim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Javascript generator
One thing, there are several assertions in js-gen like the following: (assert (= '(obj = {prop2:\str-val\,prop1:3}) (run out-str (js-assignment '(= obj {prop1 3, prop2 str-val}) out-str This assertion statement might fail (and did for me) since maps are not ordered. On Tue, Apr 14, 2009 at 1:19 AM, David Nolen dnolen.li...@gmail.com wrote: Do you have any plans for continuing to support this? If so are you against putting this on GitHub or Google Code so that people can follow it's development? Thanks for contributing it to the community. On Wed, Feb 25, 2009 at 7:49 PM, jim jim.d...@gmail.com wrote: I've just uploaded a javascript generator ala Parenscript. It's pretty half-baked, so be cautious using it until we get the bugs ironed out. http://clojure.googlegroups.com/web/js_gen.clj The code for the generator is about 250 lines. It depends on the mini- kanren implementation I just uploaded. The file also includes a bunch of unit tests of the various functions. At the bottom, there are some examples of javascript functions being generated. Bug reports very much appreciated. Jim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Javascript generator
Cool! Rather then waiting, you could host it in the interim on GitHub or Google Code so people like myself can submit patches (which I'm more than willing to do) ;) Just a thought... A couple of things: (println (javascript (var x))) I would expect this to convert to: var x; It does not. (println (javascript (new Object {prop1 a prop2 b}))) var MyClass = new(ClassGenerator, {prop1:a,prop2:b}); Instead of , var MyClass = new ClassGenerator({prop1:a, prop2:b}); This idiom is essential to MooTools, a JS library I use quite a bit. The other thought that I had was how to use macros with js-gen? The javascript macro pretty much captures everything and doesn't allow macros to be embedded. Seems like this would be quite handy. I've been contemplating writing a system which generates tagged javascript so that it can be sanely debugged if generated server side via Clojure. On Tue, Apr 14, 2009 at 9:07 AM, jim jim.d...@gmail.com wrote: I'll be glad to support it if people choose to use it and report issues. My plans to use are still on my todo list, things just keep getting put on top of them. One of which is to get my own server set up to host this and some other projects. I'll check out those asserts and make them so they're not dependent on order. Have you seen anything else that needs to be fixed? Thanks Jim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Javascript generator
Cool! Rather then waiting, you could host it in the interim on GitHub or Google Code so people like myself can submit patches (which I'm more than willing to do) ;) Just a thought... A couple of things: (println (javascript (var x))) I would expect this to convert to: var x; It does not. (println (javascript (new Object {prop1 a prop2 b}))) var MyClass = new(ClassGenerator, {prop1:a,prop2:b}); Instead of , var MyClass = new ClassGenerator({prop1:a, prop2:b}); This idiom is essential to MooTools, a JS library I use quite a bit. The other thought that I had was how to use macros with js-gen? The javascript macro pretty much captures everything and doesn't allow macros to be embedded. Seems like this would be quite handy. I've been contemplating writing a system which generates tagged javascript so that it can be sanely debugged if generated server side via Clojure. On Tue, Apr 14, 2009 at 9:07 AM, jim jim.d...@gmail.com wrote: I'll be glad to support it if people choose to use it and report issues. My plans to use are still on my todo list, things just keep getting put on top of them. One of which is to get my own server set up to host this and some other projects. I'll check out those asserts and make them so they're not dependent on order. Have you seen anything else that needs to be fixed? Thanks Jim --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: [Discuss] Contribs with dependencies
Joda Time, Colt, Fork/Join seem like projects that truly add something to Clojure. These are projects which solve problems that developers have come to expect from their respective language. Joda Time - sane date/time (really useful when building web services). Colt - enough people want to do graphics related projects (and have done) that built in support for matrix math would be really great. fork/join - not my expertise, but again a lot of posts about parallel computation. On Tue, Apr 14, 2009 at 8:19 AM, Rich Hickey richhic...@gmail.com wrote: I've been thinking recently about contribs with dependencies. I think it's very important to have layers - e.g. core depends only on JDK 1.5, contrib only on core. Lately there have been some ideas centering around Joda Time, [Parallel]Colt, AWS, JFreeChart, Fork/Join etc. I'd like to start a discussion about how best to support the contributions of libraries that depend on things not in the JDK. Obviously, without care and rules it could get crazy quickly, and I want to avoid the kitchen-sink effect. It is very important that things remain [truly, not just apparently] simple. Looking for suggestions, Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: [Discuss] Contribs with dependencies
Ooops didn't finish that thought. But my point was that I think some of the libraries in consideration stand apart in terms of convenience vs. actual utility. Not so sure about how to deploy this stuff ;) Stuart's ideas seems reasonable, though again, Clojure already includes some external source (compiler stuff), perhaps some of these things should be included in core if possible? Some of the libraries really save development resources by not reinventing the wheel, and having them delivered in some way with Clojure means that newcomers don't have to make the same mistakes over and over again (writing matrix math Clojure apps on top of Clojure vectors...) On Tue, Apr 14, 2009 at 11:01 AM, David Nolen dnolen.li...@gmail.comwrote: Joda Time, Colt, Fork/Join seem like projects that truly add something to Clojure. These are projects which solve problems that developers have come to expect from their respective language. Joda Time - sane date/time (really useful when building web services). Colt - enough people want to do graphics related projects (and have done) that built in support for matrix math would be really great. fork/join - not my expertise, but again a lot of posts about parallel computation. On Tue, Apr 14, 2009 at 8:19 AM, Rich Hickey richhic...@gmail.com wrote: I've been thinking recently about contribs with dependencies. I think it's very important to have layers - e.g. core depends only on JDK 1.5, contrib only on core. Lately there have been some ideas centering around Joda Time, [Parallel]Colt, AWS, JFreeChart, Fork/Join etc. I'd like to start a discussion about how best to support the contributions of libraries that depend on things not in the JDK. Obviously, without care and rules it could get crazy quickly, and I want to avoid the kitchen-sink effect. It is very important that things remain [truly, not just apparently] simple. Looking for suggestions, Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---