Re: Another "closure" available
On 8 Lis, 08:11, pmf wrote: > > Hmm, someone else has made another "closure" available :). > > >http://googlecode.blogspot.com/2009/11/introducing-closure-tools.html > > There's also Clozure Common Lisp [1], which is conceptually closer to > Clojure. There's also a web browser written in CL called Closure (http://common-lisp.net/project/closure/) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
How to sort these data...
Hello I have such data [ [ "tom" 23 ] [ "ann" 4434 ] [ "tom" 1234 ] ["mike" 34 ] ] I would like to sort these data so finally i got [ [ "ann" 4434 ] ["mike" 34 ] [ "tom" 23 ] [ "tom" 1234 ] ] note that i don't care the order between "tom" keys (1234 can be before 23) I have seen sort-by but I can't find tutorial how to use keyfn --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Feedback on a simplified regexp implementation
Hi All, I have been watching Clojure for about 6 months. I finally sat down and tried to code a non-trivial task with it. I come from Java and have dabbled in LISP but never for something significant. So I am asking if you would look at the following code and provide feedback on how it can be made less "Java" and more "Clojure" in terms of style and approach. The code is basically a translation of the code in the first chapter of _Beautiful Code_. It is a simple regexp matcher that matches ^, $, .(dot), *, and literal characters. I didn't change much of the structure because the structure made sense to my Java sensibilities. I learned a lot in getting it to work. I had to figure out how to iterate over a string, use loop...recur, etc. But the style of coding can't be gotten from the API docs. So is this way off? Or are there different ways of thinking about the solution that would be more in line with a "Clojure way"? I must confess that the result here doesn't make me happy. The C code from the article looked very clear and extension (+, ?, character classes) looked like it would be fairly straightforward. I'm not sure that is true with my code here. Finally, this is just an exercise. If I needed regexp in another problem, I would use the clojure tools. Thanks in advance, Matthew P.S. There must be some libraries for testing that would be better than what I've done, but I didn't find anything I could get to work. (declare matchhere) (defn match "search for regexp anywhere in text" [regexp text] (if (= (first regexp) \^) (matchhere (rest regexp) (seq text)) (loop [re (seq regexp) t (seq text)] (if (matchhere re t) ; always search even if text is empty true (if (seq (rest t)) (recur re (rest t)) false) (defn matchstar "search for [char]*regexp at beginning of text" [char regexp text] (loop [c char re regexp t text] (if (matchhere re t) ; a * matches zero or more instances true (if (and (seq t) (or (= (first t) c) (= c \.))) (recur c re (rest t)) false (defn matchhere "search for regexp at beginning of text" [regexp text] (loop [re regexp t text] (if (nil? re) true (if (and (= (first re) \$) (nil? (rest re))) (nil? t) (if (= (nth re 1 ()) \*) (matchstar (first re) (rest (rest re)) t) (if (and (seq t) (or (= (first re) \.) (= (first re) (first t (recur (rest re) (rest t)) false)) ;; some of my tests that show usage (= true (match "a" "a")) (= false (match "b" "a")) (= true (match "b" "ab")) (= true (match "^a" "ab")) (= false (match "^b" "ab")) (= true (match "b$" "b")) (= true (match "a$b" "aaa$bBB")) (= false (match "ab$" "ab$")) (= false (match "a.*b" "a")) (= true (match "a.*b" "aaab")) (= true (match "a.*b" "aabb")) ;; etc. etc. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to sort these data...
OK. I have figured it out. I just looked into core.clj and noticed that keyfn is a function which know how to get a value from an element in a collection. That value is just compared with other. 2009/11/7 Michael Jaaka > Hello I have such data > > [ [ "tom" 23 ] [ "ann" 4434 ] [ "tom" 1234 ] ["mike" 34 ] ] > > I would like to sort these data so finally i got > > [ [ "ann" 4434 ] ["mike" 34 ] [ "tom" 23 ] [ "tom" 1234 ] ] > > note that i don't care the order between "tom" keys (1234 can be > before 23) > > I have seen sort-by but I can't find tutorial how to use keyfn --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Michael newbee challange nr 1
Hi! How would you solve such problem: I have a collection of pairs (key, value) -> [ [ "tom" 32 ] [ "tom" 2333 ] [ "anne" 12 ] [ "anne" 55 ] ] As you can see keys can occur more than once, also that collection is very large so it should be evaluated lazily (for example the collection cames from stream input). I have function with two arguments key and sequence of its values, the pseudo code would be: callbackListener(string key, iterator values) now I would like get such effect that callbackListener will be called twice for the example collection. once with "tom" and iterator (or a lazy seq) to lazy evaluated collection of (32 and 2333) and second with "anne" and iterator for collection of (12 and 55) In Java it is easy because the language is imperative. But how about such logic in Clojure? Note that all must be evaluated lazily. Thanks in advance. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Functions and vars and meta-data
Hi Alex, Wow! Thank you so much for this excellent explanation! It totally makes sense now :-) S. On 2009-11-07, at 9:46 PM, Alex Osborne wrote: > > Stefan Arentz wrote: > >> I must admin that I don't fully understand the difference between foo >> and #'foo. That is probably why I'm making this beginner mistake :-) > > The difference takes some explanation. So without further ado... > > Functions and Metadata: in Vivacious Gory Detail > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Converting to TCO
I've started reading SICP and I came across the Fermat primality test implemented an Scheme. I reimplemented it in Clojure and was able to switch the recursive call in fast-prime to TCO/recur, but I was unable to do the same for the exp-mod function. (defn exp-mod [base exp m] (cond (zero? exp) 1 (even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m) :else (mod (* base (exp-mod base (inc exp) m)) m))) (defn fermat-test [n] (defn try-it [a] (= (exp-mod a n n) a)) (try-it (inc (rand-int (dec n) (defn fast-prime? [n times] (cond (zero? times) true (fermat-test n) (recur n (dec times)) :else false)) Calling (fast-prime? 5 3) blows the stack. How can I change exp-mod to use TCO? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Converting to TCO
One correction: after playing with the functions a bit I noticed I screwed up, putting sqrt where I needed square. On Sun, Nov 8, 2009 at 4:43 PM, Robert Campbell wrote: > I've started reading SICP and I came across the Fermat primality test > implemented an Scheme. I reimplemented it in Clojure and was able to > switch the recursive call in fast-prime to TCO/recur, but I was unable > to do the same for the exp-mod function. > > (defn exp-mod [base exp m] > (cond > (zero? exp) 1 > (even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m) > :else (mod (* base (exp-mod base (inc exp) m)) m))) > > (defn fermat-test [n] > (defn try-it [a] > (= (exp-mod a n n) a)) > (try-it (inc (rand-int (dec n) > > (defn fast-prime? [n times] > (cond > (zero? times) true > (fermat-test n) (recur n (dec times)) > :else false)) > > Calling (fast-prime? 5 3) blows the stack. How can I change exp-mod to use > TCO? > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Converting to TCO
Hint: Use an accumulator. http://htdp.org/2003-09-26/Book/curriculum-Z-H-39.html#node_chap_31 In fact, you may want to consider reading How to Design Programs before SICP. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Michael newbee challange nr 1
Hi, Am 08.11.2009 um 13:33 schrieb Michael Jaaka: > Hi! How would you solve such problem: > > I have a collection of pairs (key, value) -> > [ [ "tom" 32 ] [ "tom" 2333 ] [ "anne" 12 ] [ "anne" 55 ] ] > > As you can see keys can occur more than once, also that collection > is very large so it should be evaluated lazily (for example the > collection cames from stream input). > > I have function with two arguments key and sequence of its values, > the pseudo code would be: > > callbackListener(string key, iterator values) > > now I would like get such effect that callbackListener will be > called twice for the example collection. > > once with "tom" and iterator (or a lazy seq) to lazy evaluated > collection of (32 and 2333) > and second with "anne" and iterator for collection of (12 and 55) > > In Java it is easy because the language is imperative. But how about > such logic in Clojure? > Note that all must be evaluated lazily. Obviously, this cannot be done completely lazy since changing the first element is not a stopping time. You'll always need at least one lookahead to determine the change of the key and you'll have to realize the input to find all values for a key. (defn grouped-seq [input] (lazy-seq (when-let [s (seq input)] (let [k (ffirst s) [vs r] (split-with #(-> % first (= k)) s)] (cons [k vs] (grouped-seq r)) (map #(apply callbackListener %) (grouped-seq [["tom" 32] ["tom" 2333] ["anne" 12] ["anne" 55]])) Note: if you try to avoid realizing all values of a given key, you'll need two sequences: one to keep track of the key and of for the values. While callbackListener realises the values, the key sequence will retain the head of the input causing all values to stay in memory. If you want really laziness, you'll have to traverse the input twice over independent input streams. So if you have a file containing the data, you'll have to read the file twice from independent streams to get full laziness. Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Imperative into functional?
Can any imperative code be transformed to functional equivalent? (Give an answer in terms of the same way I can answer on recursion and loops) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Converting to TCO
You have a bug: (defn exp-mod [base exp m] (cond (zero? exp) 1 (even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m) :else (mod (* base (exp-mod base (inc exp) m)) m))) should be (defn exp-mod [base exp m] (cond (zero? exp) 1 (even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m) :else (mod (* base (exp-mod base (dec exp) m)) m))) The recursion depth is logarithmic in exp so TCO is probably unnecessary here. But with the bug, it gets locked into a cycle of exp being alternately 2 and 1 and never reaching zero, the base case, so the recursion continues until the stack blows up. Meanwhile, (defn fermat-test [n] (defn try-it [a] (= (exp-mod a n n) a)) (try-it (inc (rand-int (dec n) should really be (defn fermat-test [n] (letfn [(try-it [a] (= (exp-mod a n n) a))] (try-it (inc (rand-int (dec n)) in Clojure, or even (defn fermat-test "Performs the Fermat test on n with a, if specified, or with a random value from 2 to n." ([n a] (= (exp-mod a n n) a)) ([n] (fermat-test n (inc (rand-int (dec 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Imperative into functional?
On Sun, Nov 8, 2009 at 8:41 AM, Michael Jaaka wrote: > Can any imperative code be transformed to functional equivalent? > (Give an answer in terms of the same way I can answer on recursion and > loops) Short answer: Yes. Long answer: Yes, but sometimes the transformation can get rather unwieldy. Most of the time, such transformations are easy. For example, when writing the clojure-contrib combinatorics library, I was transforming highly imperative register-based algorithms from Knuth's books into loop/recur using Clojure's functional vectors. It's just as inscrutable to read as the original, but it was fairly easy to transform. The basic technique is to, rather than change something in place and "returning void", you return the changed version from a function. The problem is that sometimes, there are many different pieces of many different states that need to be updated, and you end up passing more and more things around in a functional way until eventually you are threading some monolithic "world state" through all your functions, basically simulating the imperative process. This is where monads can come in handy, to help hide the threading of the monolithic state. But at this point, it's not clear whether you're really any better off than doing it imperatively to begin with. That's why it's good that Clojure has a suite of mechanisms for dealing with state (agents, refs, vars, atoms...) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Michael newbee challange nr 1
On Sun, Nov 8, 2009 at 7:33 AM, Michael Jaaka wrote: > Hi! How would you solve such problem: > > I have a collection of pairs (key, value) -> > [ [ "tom" 32 ] [ "tom" 2333 ] [ "anne" 12 ] [ "anne" 55 ] ] > > As you can see keys can occur more than once, also that collection is very > large so it should be evaluated lazily (for example the collection cames > from stream input). > > I have function with two arguments key and sequence of its values, the > pseudo code would be: > > callbackListener(string key, iterator values) > > now I would like get such effect that callbackListener will be called twice > for the example collection. > > once with "tom" and iterator (or a lazy seq) to lazy evaluated collection > of (32 and 2333) > and second with "anne" and iterator for collection of (12 and 55) > Something related to (let [ks (distinct (map first s)) vals-for-key (fn [k] (map second (filter #(= (first %) k) s)))] (doseq [k ks] (callback k (vals-for-key k or to collect and return the return values of the callbacks, use "for" instead of "doseq". The problem is that this will realize s and hold onto its head, as Meikel points out. To make it really lazy you need something more like (defn do-it [callback producer] (let [ks (fn [p] (distinct (map first (p vals-for-key (fn [k p] (map second (filter #(= (first %) k) (p] (doseq [k (ks p)] (callback k (vals-for-key k p and call this with two arguments, the first the callback that will take a key and a lazy seq of the associated values, and the second a function that will produce anew a lazy sequence of key-value pairs from your disk file each time it's called, with the property that the lazy-seq clause that returns nil when the sequence is exhausted also has the side effect of closing the input stream so as not to leak file handles. This will grovel over the file N+1 times where N is the number of distinct keys, though, and will have in general two input streams open on the file at the same time, one of them crawling along discovering more distinct keys, and the other finding all the values for one key, then for the next, etc. It will also build up a hashset of all of the keys over time, hidden inside the "distinct" function's returned seq. So, if the summed lengths of the distinct keys is going to be big enough to blow the heap all on its own, you've got real problems and you'll probably need to use a scratch disk file. In that case I'd recommend a more imperative style with a loop/recur and lazy-seq, where the outer loop starts with a copy of the input file, runs the inner loop, and then deletes its input and reruns itself with the file generated by the inner loop (hence starting with a *copy* of the input file), and the inner loop reads the first key from the current input file, creates an empty temp file to be the current output file, then calls the callback with a lazy seq object whose realization actually advances through the input file, copying entries to the output file that are not matching the current key and producing lazy seq elements for entries that do match. The idea is that if your input file foo.dat reads [[x 1] [y 2] [x 3] [z 4] [y 5]] it will make a copy foo1.tmp, then call the callback with x and a lazy seq whose realization emits (1 3) while also generating foo2.tmp = [[y 2] [z 4] [y 5]]; then the outer loop deletes foo1.tmp and repeats on foo2.tmp and the callback is called with y and a lazy seq whose realization emits (2 5) while generating foo3.tmp = [[z 4]]; and then the outer loop deletes foo2.tmp and the callback is called with z and a lazy seq (4) whose realization creates an empty foo4.tmp; then the outer loop deletes foo3.tmp, sees foo4.tmp is empty, and deletes foo4.tmp and terminates. If you want the callback's return values, you'll need to make the outer loop another lazy-seq. I'm a bit uncomfortable with lazy-seq bodies that have side effects. You might want to consider if you need to be using a RDBMS instead of just disk files for whatever it is you're doing. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Converting to TCO
Mark: that looks a lot like the "collector" I learned about in The Little Schemer. I actually do have How to Design Programs, but I wanted to finish Seasoned Schemer first. I was poking around in SICP because of a Project Euler problem. Thanks for the tip! John: good catch. Can you confirm the difference between my original defn and your letfn? Both work, but as I understand it from the documentation, defn would actually define that local function globally, while letfn actually does bind it locally to all the expr which follow in the body.. On Sun, Nov 8, 2009 at 7:01 PM, John Harrop wrote: > You have a bug: > (defn exp-mod [base exp m] > (cond > (zero? exp) 1 > (even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m) > :else (mod (* base (exp-mod base (inc exp) m)) m))) > should be > (defn exp-mod [base exp m] > (cond > (zero? exp) 1 > (even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m) > :else (mod (* base (exp-mod base (dec exp) m)) m))) > The recursion depth is logarithmic in exp so TCO is probably unnecessary > here. But with the bug, it gets locked into a cycle of exp being alternately > 2 and 1 and never reaching zero, the base case, so the recursion continues > until the stack blows up. > Meanwhile, > (defn fermat-test [n] > (defn try-it [a] > (= (exp-mod a n n) a)) > (try-it (inc (rand-int (dec n) > should really be > (defn fermat-test [n] > (letfn [(try-it [a] > (= (exp-mod a n n) a))] > (try-it (inc (rand-int (dec n)) > in Clojure, or even > (defn fermat-test > "Performs the Fermat test on n with a, if specified, or with a random > value from 2 to n." > ([n a] > (= (exp-mod a n n) a)) > ([n] > (fermat-test n (inc (rand-int (dec 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Gensym collisions can be engineered.
It's one thing to try to protect the programmer from accidentally shooting himself on the foot, but I don't think it is as necessary for a language to prevent him from doing it on purpose. On 8 nov, 02:59, John Harrop wrote: > user=> (def q 'G__723) > #'user/q > user=> (def r (gensym)) > #'user/r > user=> q > G__723 > user=> r > G__723 > user=> (= q r) > true > > It's possible to anticipate the next gensym name that will be generated and > then engineer a collision, and therefore possibly variable capture > unintended by the author of a macro. > > It looks like "manually" generating a name does not remove it from the pool > of allowable future gensym names. > > This shouldn't tend to cause accidental problems in practice, since gensym > names tend not to collide with the kinds of identifiers programmers > ordinarily use. Nonetheless it can be partially fixed comparatively easily > by adding to the runtime a WeakHashMap into which a reference to any symbol, > however created, is placed and modifying the gensym-generator to, at the > point where it currently returns a value, first check if the WeakHashMap > contains it already and if so, generate the next one, and the next, as > needed until it gets a not-in-use name. This requires gensym creation and > normal symbol creation to occur in a global lock but symbol creation rarely > occurs at runtime and even more rarely in any kind of hot-spot at runtime. > The use of WeakHashMap would prevent the runtime clogging up with > ungarbagecollectable symbols, so the memory overhead of adding this would be > smallish, one machine pointer per in-use symbol or so, equivalent to if > every symbol had a few more characters in its name. > > This would stop gensym from producing a name already in use. It wouldn't > prevent a gensym being generated somewhere and *then* the identical name > being put together someplace else and passed to the symbol function, though; > a small loophole. Collisions between gensyms in preexisting code and an > enclosing lexical scope in new code would become impossible, but collisions > between gensyms in preexisting code and an enclosed lexical scope (e.g. a > macro-invocation body, such as a loop body) would remain theoretically > possible. > > That last loophole can't really be plugged without giving Clojure "true" > gensyms (uninterned anywhere), which would bring with it its own > architectural problems. If that change were made, the above REPL interaction > would be possible up to the (= q r) evaluation, but that would return false > despite the names looking the same, so the symbols wouldn't really collide > even though a collision of their printed representations could still be > engineered. One bothersome consequence though would be that the textual > output of macroexpand-1 could no longer always be substituted for a macro > call in source code without altering the run-time semantics of that code, > even when the macro's expansion-generation does not have side effects. > > (To reproduce that REPL interaction for yourself, evaluate (gensym) at the > REPL and note the number. Add seven and then evaluate (def q 'G__#) with # > replaced with the sum. Then evaluate (def r (gensym)) and, if you like, skip > straight to (= q r). If that doesn't work, the number it goes up by must > have changed between Clojure 1.0 and whatever version you're using; evaluate > (gensym), then (def q 'xyzzy), then (gensym) again and note the increment > and use that instead of seven. Oh, and don't have any background threads > running in that JVM instance that might do something autonomously that > causes a gensym to be generated.) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Converting to TCO
On Sun, Nov 8, 2009 at 1:39 PM, Robert Campbell wrote: > John: good catch. Thanks. > Can you confirm the difference between my original > defn and your letfn? Both work, but as I understand it from the > documentation, defn would actually define that local function > globally, while letfn actually does bind it locally to all the expr > which follow in the body.. Yup. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Using Compojure's defroutes in a macro
I have this Compojure code that works fine: (defroutes my-routes (GET "/api" (my-code request))) I want this code to be generated by a macro. My real code is more complex but the error is the same. (defmacro mydefroutes [] `(defroutes my-routes (GET "/api" (my-code request When I run this code, I get the following error: (foo) No such var: webservice/request [Thrown class java.lang.Exception] (webservice is the namespace of my code) When I macroexpand the code I see this: webservice> (macroexpand-1 '(foo)) (compojure/defroutes webservice/my-routes (compojure/GET "/api" (webservice/my-code webservice/request))) I'm not sure what to do here. S. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Using Compojure's defroutes in a macro
Try (defmacro mydefroutes [] `(defroutes my-routes (GET "/api" (my-code ~'request --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Using Compojure's defroutes in a macro
On 2009-11-08, at 3:40 PM, Richard Newman wrote: > > Try > > (defmacro mydefroutes [] > `(defroutes my-routes > (GET "/api" > (my-code ~'request Brilliant! I learn something new every day :-) S. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Add whitespace cleanup support
On Nov 4, 9:07 pm, Lauri Oherd wrote: > With this patch, the trailing whitespace characters in clojure file > buffer will be deleted automatically before each save if custom > parameter 'clojure-mode-cleanup-whitespace' is set. > > This is based on the js2-mode where similar defcustom parameter is > used. Many thanks to Steve Yegge for the code. > > Any comments and suggestions would be greatly appreciated. Thanks for this patch, but stripping trailing whitespace is not a Clojure-specific piece of functionality. I don't think it belongs in clojure-mode itself. If a user wants to add this functionality to clojure-mode (or any mode really) he should just put this in his own configuration: (add-hook 'clojure-mode-hook (lambda () (set (make-local-variable 'before-save-hook) 'delete-trailing-whitespace)) -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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
equivalent to Haskell's group function
Hi, I did search in the API docs for both core and contrib, but didn't find anything like it. Does Clojure have a function like Haskell's group? In Haskell, Input: group [1,2,2,1,1,1,2,2,2,1] Output: [[1],[2,2],[1,1,1],[2,2,2],[1]] Thanks -- Omnem crede diem tibi diluxisse supremum. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: equivalent to Haskell's group function
Wilson MacGyver wrote: > Does Clojure have a function like Haskell's group? > > In Haskell, > Input: group [1,2,2,1,1,1,2,2,2,1] > Output: [[1],[2,2],[1,1,1],[2,2,2],[1]] (use 'clojure.contrib.seq-utils) (partition-by identity [1 2 2 1 1 1 2 2 2 1]) => ((1) (2 2) (1 1 1) (2 2 2) (1)) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: equivalent to Haskell's group function
ah, thank you for the help! On Mon, Nov 9, 2009 at 1:57 AM, Alex Osborne wrote: > > Wilson MacGyver wrote: >> Does Clojure have a function like Haskell's group? >> >> In Haskell, >> Input: group [1,2,2,1,1,1,2,2,2,1] >> Output: [[1],[2,2],[1,1,1],[2,2,2],[1]] > > (use 'clojure.contrib.seq-utils) > > (partition-by identity [1 2 2 1 1 1 2 2 2 1]) > => ((1) (2 2) (1 1 1) (2 2 2) (1)) > > > > -- Omnem crede diem tibi diluxisse supremum. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---