Re: What exactly is a form in Clojure?
Ray, The question of what a form is is actually quite an important part of grasping Lisp/Clojure. Earlier versions of Lisp used the term S-expression (symbolic expression) extensively. But during the process of defining Common Lisp, the term was dropped in favor of the notion of forms. Stuart Shapiro wrote a Common Lisp book that you may find useful in studying Clojure as well: http://www.cse.buffalo.edu/~shapiro/Commonlisp/ In the book’s preface he defines these two terms: S-expression - syntactic units, sequences of characters that form the written version of Lisp programs and data structures. Form - a Common Lisp object that can be evaluated In terms of the REPL (read-eval-print loop), an S-expression is the input to the reader, and a form is the output of the reader, which then becomes the input to eval. An S-expression is syntax. A form is some sort of representation in memory. So a simple rule of thumb is that S-expressions in Lisp often contain parentheses, but there are no parentheses in forms. Here are a couple more formal definitions, again from a Common Lisp perspective: http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#form form n. 1. any object meant to be evaluated. 2. a symbol, a compound form, or a self-evaluating object. 3. (for an operator, as in ``<> form'') a compound formhaving that operator as its first element. ``A quote form is a constant form.’' A self-evaluating object would be something like a numeric literal: 2.4 or a string “Yo!”. Compound forms are further defined: http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_c.htm#compound_form compound form n. a non-empty list which is a form: a special form, a lambda form, a macro form, or a function form. Remember that these Common Lisp definitions don’t line up exactly with Clojure, but they are illuminating. Have all good days, David Sletten On Dec 28, 2015, at 11:16 AM, Ray Toal <ray.t...@gmail.com> wrote: > I think of it this way too but was really trying to get a formal definition, > if one exists. > > While I've not seen a formal grammar of Clojure anywhere, I have looked at > > > https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java > > which seems to show that forms can be a lot of things, including > READ_FINISHED and READ_EOF, which probably aren't intended for public > consumption. :) > > The actual read() function (or method, as this is all written in Java), > looked promising but was hard to decipher. > > Maybe the term is intentionally vague? I was hoping it wasn't. But the fact > that it is hard to find a hard definition of it makes me wonder. > > Thanks > > > On Monday, December 28, 2015 at 5:08:36 AM UTC-8, Gregg Reynolds wrote: > > On Dec 28, 2015 6:58 AM, "Ray Toal" <ray@gmail.com> wrote: > > > > Throughout the Clojure documentation there are many references to forms. > > > > I know about special forms, macros, vars, symbols, keywords, integers, > > doubles, ratios, sets, maps, lists, vectors, booleans, nil, etc. > > > > What exactly, though, is a form? > > A syntactic unit, as opposed to a lexical unit? Left paren is a lexical > unit, to "read it you have to find the following balanced right paren, and if > everything in between is syntactically correct you have a list form. At > least that's how I think of it. > > Gregg > > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: why Clojure/Lisp is so fast
The OP almost certainly intended CLISP to mean Common Lisp. While the CLISP implementation of Common Lisp is a decent platform (Conrad Barski features it in his book _Land of Lisp_, for example), it is not the fastest implementation. Their documentation acknowledges as much: http://www.clisp.org/propaganda.html See the section CLISP Performance at the bottom of the page. Have all good days, David Sletten On Feb 18, 2014, at 10:37 PM, Mars0i marsh...@logical.net wrote: It really depends on the benchmark and the programmer, and sometimes on the computer. And on what a person chooses to report. Here are some benchmarks, probably only representative of very special cases, that show Java beating Clojure in many cases, Java and SBCL both beating each other in some cases, etc. (For my work, I have found SBCL to be a lot faster than CLISP, but again, it probably depends on what you're doing.) http://benchmarksgame.alioth.debian.org/ Other cases would be different. (None of this conflicts with Mikera's insightful comments.) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Difficulty understanding (new?) behavior of identical?
Can anyone explain this change? (clojure-version) = 1.2.0 (let [x 8.9] (identical? x x)) = true Compared to: (clojure-version) = 1.4.0 (let [x 8.9] (identical? x x)) = false Thanks. David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Difficulty understanding (new?) behavior of identical?
On May 5, 2012, at 3:06 PM, Daniel Solano Gómez wrote: On Sat May 5 14:53 2012, David Sletten wrote: Can anyone explain this change? (clojure-version) = 1.2.0 (let [x 8.9] (identical? x x)) = true Compared to: (clojure-version) = 1.4.0 (let [x 8.9] (identical? x x)) = false Well, this is certainly an interesting phenomenon. What is happening here is part of Clojure's primitive optimisations introduced in Clojure 1.3. Before Clojure 1.3, the code: (let [x 8.9] (identical? x x)) Roughly can be thought of expanding to something like: (let [x (Float. 8.9)] (identical? x x)) Since x is an object, it is indeed identical to itself. In Clojure 1.3, the code could be thought of evaluating to something like: (let [x (float 8.9)] (identical? (Double. x) (Double. x))) The x remains unboxed, so that when it is passed to the function call, which presumably has no primitive-hinted forms, it much be boxed each time it is an argument, and the resulting objects are not identical. To see more of the same in action (in Clojure 1.3 and above): (let [x 127] (identical? x x)) ;= true (let [x 128] (identical? x x)) ;= false The JVM has an optimisation such that boxed versions of small integers get boxed to cached instances. However for integers with large enough magnitudes, the JVM produces new objects. Thanks for your response Daniel. You explain WHAT is apparently happening here. However, I am still struggling to understand WHY this is the new behavior. The documentation for 'identical?' states: Tests if 2 arguments are the same object. To me, (identical? x x) asks whether 2 references to the same object (the referent of x) are identical. Clojure 1.4's response suggests that in some cases, within a given scope, a local can refer to 2 different things. To be charitable, this is a counterintuitive result. It's obvious that (identical? (Double. x) (Double. x)) should return false, but that's not what I'm asking. To suggest that x is not identical to x (within the same scope where they refer to the same thing) violates one of the most fundamental laws of logic. You give interpretations of what is happening under the covers in both pre- and post-1.3 Clojure above. Your explanation appears to correspond to the observed behavior, but how did you come to this realization? Can you point me to where this issue is documented? I don't find any clues in the Clojure literature. I see the following example in _The Joy Of Clojure_ (pg. 71): (let [x 'goat y x] (identical? x y)) = true As you point out, this is also the behavior with cached integers (-128 = n 127). However, the following does not make the issue any clearer: (let [x 123] (identical? x x)) = true (let [x 1234] (identical? x x)) = false (let [x 1234N] (identical? x x)) = true (let [x 8.9M] (identical? x x)) = true (let [x (Double. 8.9)] (identical? x x)) = true (class 8.9) = java.lang.Double Furthermore, in _Clojure Programming_ (pg. 433) the authors write: [identical?] corresponds directly to == in Java. This is clearly not true in the example I presented. This code will print 'true' in all 4 cases: Double d1 = 8.9; Double d2 = d1; double d3 = 8.9; double d4 = d3; System.out.println(d1 == d1); System.out.println(d1 == d2); System.out.println(d3 == d3); System.out.println(d3 == d4); Of course, looking at the source for 'identical?' vindicates what these authors have written: (defn identical? [x y] (clojure.lang.Util/identical x y)) In clojure.lang.Util: static public boolean identical(Object k1, Object k2){ return k1 == k2; } So apparently as far as Java is concerned, my example should return 'true'. Therefore something must be occurring in the reader that results in the explanation which you gave. To be fair, the Common Lisp standard seems goofy to me on this issue too. The analogous operator is EQ, documented here: http://www.lispworks.com/documentation/HyperSpec/Body/f_eq.htm Of note is the example below: (let ((x 5)) (eq x x)) = true OR= false This states that a conforming system may return either a true or a false value in this case. This doesn't make any more sense to me than what Clojure is doing, but all of the Common Lisp implementations I've tested (Allegro, Clozure, SBCL, CLISP) do return T as I expected. David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Difficulty understanding (new?) behavior of identical?
Fantastic Daniel. Your thorough analysis has cleared up my confusion. I see now that Java is partly to blame for this idiosyncratic behavior. Furthermore, I agree that this is a relatively unlikely use of 'identical?'. Considering all of the usual concerns when comparing floating-point numbers, this is probably not worth getting worked up about. Thanks, David Sletten On May 5, 2012, at 5:14 PM, Daniel Solano Gómez wrote: On Sat May 5 16:43 2012, David Sletten wrote: Thanks for your response Daniel. You explain WHAT is apparently happening here. However, I am still struggling to understand WHY this is the new behavior. Yes, this is indeed a valid question. I think the answer is that this particular behaviour is an unintended side effect of the performance optimizations introduced in Clojure 1.3. By refusing to box numeric primitives until it's absolutely necessary, the results are generally much better performance for arithmetic code. The documentation for 'identical?' states: Tests if 2 arguments are the same object. To me, (identical? x x) asks whether 2 references to the same object (the referent of x) are identical. Clojure 1.4's response suggests that in some cases, within a given scope, a local can refer to 2 different things. To be charitable, this is a counterintuitive result. It's obvious that (identical? (Double. x) (Double. x)) should return false, but that's not what I'm asking. To suggest that x is not identical to x (within the same scope where they refer to the same thing) violates one of the most fundamental laws of logic. Well, arguably, this is part of the unfortunate fallout of the JVM's disjoint type system between objects and primitives. The key thing to realise is that before Clojure 1.3, (let [x 2] …) resulted in x referring to an object that contains the value of 2. In Clojure 1.3 and newer, the x in (let [x 2] …) now refers to a primitive long with the value 2. You give interpretations of what is happening under the covers in both pre- and post-1.3 Clojure above. Your explanation appears to correspond to the observed behavior, but how did you come to this realization? Can you point me to where this issue is documented? I don't find any clues in the Clojure literature. I don't think it's documented, not as such. I just happen to be familiar with a lot of implementation details. I see the following example in _The Joy Of Clojure_ (pg. 71): (let [x 'goat y x] (identical? x y)) = true As you point out, this is also the behavior with cached integers (-128 = n 127). However, the following does not make the issue any clearer: (let [x 123] (identical? x x)) = true As we have established, the JVM's cache kicks in for this. (let [x 1234] (identical? x x)) = false This is outside the range of the cache, the boxed values of x are different. (let [x 1234N] (identical? x x)) = true Here, you are explicitly creating a clojure.lang.BigInt, an object. (let [x 8.9M] (identical? x x)) = true (let [x (Double. 8.9)] (identical? x x)) = true (class 8.9) = java.lang.Double Again for these, you are explicitly creating objects. Furthermore, in _Clojure Programming_ (pg. 433) the authors write: [identical?] corresponds directly to == in Java. This is clearly not true in the example I presented. This code will print 'true' in all 4 cases: Double d1 = 8.9; Double d2 = d1; double d3 = 8.9; double d4 = d3; System.out.println(d1 == d1); System.out.println(d1 == d2); System.out.println(d3 == d3); System.out.println(d3 == d4); Of course, looking at the source for 'identical?' vindicates what these authors have written: (defn identical? [x y] (clojure.lang.Util/identical x y)) In clojure.lang.Util: static public boolean identical(Object k1, Object k2){ return k1 == k2; } So apparently as far as Java is concerned, my example should return 'true'. Therefore something must be occurring in the reader that results in the explanation which you gave. Not quite, you get the same behaviour in Java if you have to autobox the values like Clojure does: public class Equals { static boolean eq(Object lhs, Object rhs) { return lhs == rhs; } public static void main(String[] args) { // prints true System.out.println(eq(1, 1)); // prints true System.out.println(eq(127, 127)); // prints false System.out.println(eq(128, 128)); } } To be fair, the Common Lisp standard seems goofy to me on this issue too. The analogous operator is EQ, documented here: http://www.lispworks.com/documentation/HyperSpec/Body/f_eq.htm Of note is the example below: (let ((x 5)) (eq x x)) = true OR= false This states that a conforming system may return either a true or a false value in this case. This doesn't make any more sense to me than what Clojure is doing, but all of the Common Lisp implementations
Re: Correct way to define the else clause of a cond form?
Conrad, The syntax of 'cond' is actually pretty straightforward. Following the symbol 'cond' you have pairs of predicate forms and consequent expressions. The 'cond' form evaluates each predicate in turn until one evaluates to true and then returns the value of the corresponding consequent form. Many 'cond' forms have a default value that is returned when none of the predicates succeed. Remember that in Clojure only the value 'false' and the value 'nil' are considered false. Everything else is true. By convention we use the keyword ':else' as a 'predicate' for the default case. Since ':else' is neither 'false' nor 'nil', it is considered to be true, and if the 'cond' form reaches the ':else' clause, then the default value will be returned. Given these restrictions, only a) and c) are syntactically correct. And even they don't do what you want. a) (cond (= total 20) 8.75 (or (amount 20) (= country US) 9.75) (else 10.0)) Here we have: predicate | consequent (= total 20) | 8.75 (or (amount 20) (= country US) 9.75) | (else 10.0) Unfortunately, (else 10.0) winds up as the consequent of the 2nd predicate. Furthermore, 'else' is not a Clojure operator. Unless you've defined a function or macro named 'else' you will get an error. b) (cond (= total 20) 8.75 (or (amount 20) (= country US) 9.75) :default 10.0) predicate | consequent (= total 20) | 8.75 (or (amount 20) (= country US) 9.75) | :default 10.0 | ??? These are not paired up properly. c) (cond (= total 20) 8.75 (or (amount 20) (= country US) 9.75) 10.0 ) predicate | consequent (= total 20) | 8.75 (or (amount 20) (= country US) 9.75) | 10.0 Not what you expected... d) (cond (= total 20) 8.75 (or (amount 20) (= country US) 9.75) :else 10.0 ) predicate | consequent (= total 20) | 8.75 (or (amount 20) (= country US) 9.75) | :else 10.0 | ??? Not syntactically correct. Here's what you want to use: (cond (== total 20) 8.75 (or ( amount 20) (= country US)) 9.75 :else 10.0) (Note that '==' is the proper predicate for numerical equality.) Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Correct way to define the else clause of a cond form?
On Jul 6, 2011, at 10:58 PM, Conrad Taylor wrote: On Jul 6, 7:33 pm, Benny Tsai benny.t...@gmail.com wrote: Could you please post the entire form, including the code surrounding the cond form (since total, amount, and country need to be defined somewhere)? Benny, that was just sample code to zero in on the initial issue. I'm working through the SICP with a lot of pain but here's what I have so far: (def us-coins (list 50 25 10 5 1)) (def uk-coins (list 100 50 20 10 5 2 1 0.5)) (defn first-denomination [ coin-values ] (first coin-values)) (defn except-first-denomination [ coin-values ] (rest coin-values)) (defn no-more? [coin-values] (nil? coin-values)) (defn cc [amount coin-values] (cond (= amount 0) 1 (or ( amount 0) (no-more? coin-values)) 0  :else (+ (cc amount (except-first-denomination coin-values)) (cc (- amount (first-denomination coin- values)) coin-values Part of the problem is that Clojure uses a slightly different syntax for 'cond' than Scheme (and Common Lisp) do. In particular, Common Lisp more frequently allows for side effects, so rather than a single consequent value Common Lisp's COND encloses its consequent expressions in a an additional layer of parentheses. Clojure discourages side effects, so it's reasonable to think in terms of a single expression as a consequent. The need for enclosing parentheses disappears. Beware that the predicate 'nil?' tests whether an object is 'nil'. You probably want to use the predicate 'empty?' to test whether your coin list is empty. Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Translating Java code with nested for loops
On Jun 29, 2011, at 1:45 AM, David Sletten wrote: (defn compute-contrib [daily-values total-values] (loop [contrib [] daily-values daily-values total-values total-values] (if (empty? daily-values) contrib (recur (conj contrib (* (first daily-values) (reduce (fn [sum total-value] (* sum (+ (/ total-value 100.0) 1.0))) 1.0 (rest total-values (rest daily-values) (rest total-values ) Arrgghh! Now you've got me doing it too... :) Replace 'sum' with 'product': (defn compute-contrib [daily-values total-values] (loop [contrib [] daily-values daily-values total-values total-values] (if (empty? daily-values) contrib (recur (conj contrib (* (first daily-values) (reduce (fn [product total-value] (* product (+ (/ total-value 100.0) 1.0))) 1.0 (rest total-values (rest daily-values) (rest total-values ) Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Translating Java code with nested for loops
On Jun 28, 2011, at 8:20 PM, Bhinderwala, Shoeb wrote: The inputs are two arrays of type double of the same length – dailyValues and totalValues. The output is the array contrib of the same length. int n = dailyValues.length; for (int i = 0; i n; i++) { sum = 1.0; for (int j = i + 1; j n; j++) { sum *= (1.0 + (totalValues[j] / 100.0)); } contrib[i] = sum * dailyValues[i]; } 1. Are you sure that this does what you want it to? 2. What does it do? There are two obvious red flags with the code: -You have a variable called 'sum' which is really a product. -You never use index 0 of totalValues Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Translating Java code with nested for loops
On Jun 28, 2011, at 11:37 PM, David Sletten wrote: On Jun 28, 2011, at 8:20 PM, Bhinderwala, Shoeb wrote: The inputs are two arrays of type double of the same length – dailyValues and totalValues. The output is the array contrib of the same length. int n = dailyValues.length; for (int i = 0; i n; i++) { sum = 1.0; for (int j = i + 1; j n; j++) { sum *= (1.0 + (totalValues[j] / 100.0)); } contrib[i] = sum * dailyValues[i]; } 1. Are you sure that this does what you want it to? 2. What does it do? There are two obvious red flags with the code: -You have a variable called 'sum' which is really a product. -You never use index 0 of totalValues Assuming that your code is correct, the following reproduces your results: (defn compute-contrib [daily-values total-values] (loop [contrib [] daily-values daily-values total-values total-values] (if (empty? daily-values) contrib (recur (conj contrib (* (first daily-values) (reduce (fn [sum total-value] (* sum (+ (/ total-value 100.0) 1.0))) 1.0 (rest total-values (rest daily-values) (rest total-values ) In the outer loop you are working with each element of dailyValues and consecutively smaller subsequences of totalValues. In the inner loop you repeat a calculation using each of the remaining elements of totalValues starting with a seed value of 1.0. The Clojure implementation uses 'loop' to traverse each of the input sequences. On each iteration we use 'reduce' to do the work of the inner loop (notice that 'reduce' is working with (rest total-values) rather than simply total-values itself, so we discard the first element each time just as your inner loop does), multiply that by the current element of interest in daily-values and then accumulate the result by conjoining it with our result 'contrib'. The mental shift that you need to make involves forgetting about the index variables i and j and thinking instead about what the loops are accomplishing. If an inner loop is collapsing a sequence to a single result as above, then 'reduce' is what you want to use. Other inner loops might require 'map' or 'filter' depending on the computation. Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Cons vs List vs. ISeqs
On Jun 24, 2011, at 7:35 PM, Tim Robinson wrote: I'm under the impression that traditional lisps have a greater distinction between a cons operation vs. a list operation. Specifically I had believed that consing was a more efficient and better performing operation than using list. This is not true, but it is also not relevant. In historical Lisps, the list datatype is a singly-linked list consisting of nodes known as CONS cells. In Common Lisp, for example, the predicate (listp obj) is simply equivalent to the test (typep obj '(or cons null)). A list is either a (chain of) CONS or the empty list. Notice that this implicitly includes improper lists (dotted pairs) such as (cons 1 2). In Clojure, on the other hand, it is illegal for the second argument to 'cons' to be an atom: (cons 1 2) = java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer A Lisp form such as (list 1 2 3) is just a series of calls to cons: (cons 1 (cons 2 (cons 3 '(. Is this true? and if so, given both the Cons and Lists are actually both just seqs in Clojure, does the above statement still hold true in the Clojure world? As I mentioned, the correspondence between LIST and CONS in traditional Lisps is not really relevant in Clojure, where the emphasis is on the sequence abstraction. A sequence simply satisfies an interface that provides a 'first' element, the 'rest' of the sequence, and allows you to construct ('cons') a new sequence from an existing one. Lists and vectors are two concrete sequence types, and they have significant differences in terms of behavior and performance. But in Clojure you can 'cons' using a list or a vector. So the rules are a little different from other Lisps. Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Small Problem: Which Strings Differ at One Location
On May 30, 2011, at 3:55 PM, joshua-choi wrote: Let's say that I have a set of strings, each three English letters long. How can I determine which strings differ only at one location (e.g. xxe and xbe)? Right now, I'm writing a loop that sequentially compares every string to every other string. I think that there's a better way, but I don't know where to start. I haven't given too much thought to performance here, but this collects all strings which differ only at one position. The program removes successive characters from each string and groups those that are the same after that deletion. For example, abc, dbc, zbc are all reduced to bc when the first letter is removed. Thus, all three strings would be grouped together rather than pairwise. 'match-position' groups related strings and weeds out singletons. (defn remove-nth [s n] (str (subs s 0 n) (subs s (inc n (defn match-position [words i] (remove (fn [coll] (= (count coll) 1)) (map (fn [[key val]] (map second val)) (group-by first (map (fn [s] [(remove-nth s i) s]) words) (match-position [abc abd aed axf zqr zbc aqd] 0) = ((abc zbc)) (match-position [abc abd aed axf zqr zbc aqd] 1) = ((abd aed aqd)) (match-position [abc abd aed axf zqr zbc aqd] 2) = ((abc abd)) (match-position [abc abd aed axf zqr zbc aqd qbd tbd tqr] 0) = ((abc zbc) (abd qbd tbd) (zqr tqr)) Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: every-nth
On Nov 24, 2010, at 11:45 PM, Ken Wesson wrote: On Wed, Nov 24, 2010 at 11:11 PM, Baishampayan Ghose b.gh...@gmail.com wrote: I just needed a function for every-nth element in a sequence.. I know it can be trivially implemented as .. (defn every-nth [n coll] (letfn [(evn [cn s] (when s (if (= cn 1) (lazy-seq (cons (first s) (evn n (next s (evn (dec cn) (next s)] (evn n coll))) But I remember seeing inbuilt function .. can anybody help me find it? take-nth should do the job - http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/take-nth And it can be even more trivially implemented as (map first (partition n coll)). :) (map first (partition 1 n coll)) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: every-nth
I stand corrected. I thought it required another arg. Yours was right already. On Nov 24, 2010, at 11:53 PM, David Sletten wrote: On Nov 24, 2010, at 11:45 PM, Ken Wesson wrote: On Wed, Nov 24, 2010 at 11:11 PM, Baishampayan Ghose b.gh...@gmail.com wrote: I just needed a function for every-nth element in a sequence.. I know it can be trivially implemented as .. (defn every-nth [n coll] (letfn [(evn [cn s] (when s (if (= cn 1) (lazy-seq (cons (first s) (evn n (next s (evn (dec cn) (next s)] (evn n coll))) But I remember seeing inbuilt function .. can anybody help me find it? take-nth should do the job - http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/take-nth And it can be even more trivially implemented as (map first (partition n coll)). :) (map first (partition 1 n coll)) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You 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: sort-by reverse order?
Alex, There might be some useful info here: http://www.gettingclojure.com/cookbook:sequences#sorting Have all good days, David Sletten On Nov 22, 2010, at 12:07 AM, Alex Baranosky wrote: So for the case I had that method worked. I wonder though if I had wanted to sort by multiple keys, with some of the keys sorting in reverse order and others in regular order, how I could do that... Say last name ascending, date of birth descending for example. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: string interpolation
The cool way is to use Tom Faulhaber's cl-format in clojure.pprint: http://clojure.github.com/clojure/#clojure.pprint (use '[clojure.contrib.pprint :only (cl-format)]) (cl-format true This is a ~A string.~% 'funky) This is a funky string. I have a mini-tutorial plus links here: http://www.gettingclojure.com/cookbook:sequences#commas Have all good days, David Sletten On Nov 20, 2010, at 6:00 PM, HiHeelHottie wrote: I think ruby has nice string interpolation. You can put the following in a textfield that a user can modify This is a #{adjective} string. Then, you can take that string, put it in quotes and have ruby evaluate it as a string. What is the clojure way of doing something similar. Presenting something like This is a adjective string and then wrapping that in (str ) before evaluating it in clojure seems less attractive. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Dynamic Binding of Self-Referencing Functions Expected Behavior?
On Nov 17, 2010, at 9:22 AM, Stuart Halloway wrote: In 1.2, functions were always looked up through their vars. While this is a low-cost operation, it does not allow maximum performance. In 1.3, function calls are compiled through their vars. If function a calls function c inside its body, there is no runtime lookup of the var c. However, each function makes a (very low cost) check on entry to see if anything has been recompiled. If so, the function is recompiled. This enables the dynamic repl interaction that you would expect from a lisp, with great performance. When, as in your example, a var b refers to var a, there is no function call, hence no hook point at which to make the check. If you want b to point to the new a, redef b. Stu, This doesn't seem consistent with what Alyssa is reporting. She's getting a weird mix of both old 'a' and new 'a': = (defn a ([x] x) ([x y] (+ (a x) (a y #'user/a = (a 1 2) 3 = (def b a) #'user/b = (b 1 2) 3 = (defn a [x] (- x)) #'user/a = (b 1 2) -3 Let's call the original function assigned to 'a' a0 and the new one a1. After 'a' has been redefined to a1, 'b' still refers to a0. So the 2nd call to 'b' invokes a0 with two args (in fact, a1 only takes one arg now). But within a0 itself the references to 'a' are being resolved at runtime to a1 now, not as references to a0 as before. Are you saying that inside a0 Clojure detects that 'a' means something else now and recompiles a0 to point to a1? In any case, this behavior seems weird. Have all good days, David Sletten Stu Notice that when I redefined a, I only included one arity. If b were updated with the fn that a was redefined to, then (b 1 2) should have thrown an exception. Instead, it used the old definition of a but within that definition pointed to the new definition of a. This is internally inconsistent. I'm not proposing making all function definitions lexically bound. Yes, that would destroy interactive coding. But to be internally consistent, self-references should be lexical. In any case, I am using Github master and I thought I was using 1.2. 1.2 has self-references lexically bound, as David Sletten points out, which I agree is the correct behavior. But something has happened on 1.3 alpha that has changed that. I don't know if it's intentional or not. Thanks, Alyssa Kwan On Nov 16, 6:01 pm, David Nolen dnolen.li...@gmail.com wrote: But that would destroy one of the most useful features Lisp has to offer, interactive coding. Live coding would be impossible w/o this behavior as you would need to find and update all callers. Yuk. David On Tue, Nov 16, 2010 at 5:26 PM, Alyssa Kwan alyssa.c.k...@gmail.comwrote: I ran into this while working on making functions durable. Here's a contrived example: = (defn a ([x] x) ([x y] (+ (a x) (a y #'user/a = (a 1 2) 3 = (def b a) #'user/b = (b 1 2) 3 = (defn a [x] (- x)) #'user/a = (b 1 2) -3 Is this what people expect? I would think that the original definition of a, which is self-referencing, should point to itself no matter what it's named, not get resolved at invoke-time to see what the var is currently resolving to. Thanks, Alyssa Kwan -- You 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.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http
Re: Dynamic Binding of Self-Referencing Functions Expected Behavior?
On Nov 16, 2010, at 5:26 PM, Alyssa Kwan wrote: I ran into this while working on making functions durable. Here's a contrived example: = (defn a ([x] x) ([x y] (+ (a x) (a y #'user/a = (a 1 2) 3 = (def b a) #'user/b = (b 1 2) 3 = (defn a [x] (- x)) #'user/a = (b 1 2) -3 I'm confused here. Are you saying that this is what _you_ expect to see? Because that's not how Clojure actually behaves. You assign the function 'a' to 'b', and 'b' continues to refer to the original function after you redefine 'a'. So your second call to (b 1 2) still returns 3. That's interesting since the function assigned to 'b' (the original version of 'a') retains the self-reference after 'a' is redefined. The call to 'a' in 'b' still refers to the original 'a'. In other words, Clojure is not looking up the current value of 'a' when 'b' is invoked. But that is what happens with non-self-referencing functions (There must be a clearer way to say that...a function which references a function other than itself): (defn d [x y] (* x y)) (defn c [x] (d x 2)) (def f d) (defn e [x] (f x 2)) user= (c 5) 10 user= (e 5) 10 (defn d [x y] ( x y)) user= (c 5) false user= (e 5) 10 Here the value of (c 5) changes depending on how 'd' is defined, whereas 'f' continues to refer to the original definition. I suppose the answer comes from expanding 'defn': (macroexpand '(defn a ([x] x) ([x y] (+ (a x) (a y ) = (def a (.withMeta (clojure.core/fn a ([x] x) ([x y] (+ (a x) (a y (.meta (var a (macroexpand '(defn c [x] (d x 2))) = (def c (.withMeta (clojure.core/fn c ([x] (d x 2))) (.meta (var c And the documentation (http://clojure.org/special_forms#fn) says: If a name symbol is provided, it is bound within the function definition to the function object itself, allowing for self-calling, even in anonymous functions. So I guess technically the self-referential 'a' in the function definition actually refers to the name inside the 'fn' form not the variable that is getting def'd? Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Passing arguments from clojure to java
On Nov 16, 2010, at 5:49 PM, unst...@gmail.com wrote: This seems like such an obvious question, but I can't seem to find the answer anywhere. I don't understand why this would not be included in the java_interop section of the clojure documentation. Is it possible to pass a clojure vector to a java function that requires a java vector as an argument? Apparently not since: (javax.swing.table.DefaultTableModel. [I B] 0) fails. What is the idiomatic way to do this? It looks as though your constructor takes either a java.util.Vector or an array of Object[]. To make a String[] array out of a Clojure vector (clojure.lang.PersistentVector): (into-array String [I B]) So you wind up with this: (javax.swing.table.DefaultTableModel. (into-array String [I B]) 0) #DefaultTableModel javax.swing.table.defaulttablemo...@3ebc312f Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Dynamic Binding of Self-Referencing Functions Expected Behavior?
Ok, now I get it. The results you included weren't a hypothetical example, you were simply using a different version of Clojure. So in your 1.3 version, the second (b 1 2) does return -3? Are the macro expansions of 'defn' different? Have all good days, David Sletten On Nov 16, 2010, at 10:52 PM, Alyssa Kwan wrote: Notice that when I redefined a, I only included one arity. If b were updated with the fn that a was redefined to, then (b 1 2) should have thrown an exception. Instead, it used the old definition of a but within that definition pointed to the new definition of a. This is internally inconsistent. I'm not proposing making all function definitions lexically bound. Yes, that would destroy interactive coding. But to be internally consistent, self-references should be lexical. In any case, I am using Github master and I thought I was using 1.2. 1.2 has self-references lexically bound, as David Sletten points out, which I agree is the correct behavior. But something has happened on 1.3 alpha that has changed that. I don't know if it's intentional or not. Thanks, Alyssa Kwan On Nov 16, 6:01 pm, David Nolen dnolen.li...@gmail.com wrote: But that would destroy one of the most useful features Lisp has to offer, interactive coding. Live coding would be impossible w/o this behavior as you would need to find and update all callers. Yuk. David On Tue, Nov 16, 2010 at 5:26 PM, Alyssa Kwan alyssa.c.k...@gmail.comwrote: I ran into this while working on making functions durable. Here's a contrived example: = (defn a ([x] x) ([x y] (+ (a x) (a y #'user/a = (a 1 2) 3 = (def b a) #'user/b = (b 1 2) 3 = (defn a [x] (- x)) #'user/a = (b 1 2) -3 Is this what people expect? I would think that the original definition of a, which is self-referencing, should point to itself no matter what it's named, not get resolved at invoke-time to see what the var is currently resolving to. Thanks, Alyssa Kwan -- You 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.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You 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
Clojure typing test
The StackOverflowError jumps over the lazy seq. Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Performance of seq on empty collections
On Nov 15, 2010, at 4:41 PM, Alan wrote: Yes, the API *does* suggest using seq to check for emptiness. (empty? x) is implemented as (not (seq x)). You certainly won't ever get improved performance by using empty? - at best you break even, most of the time you lose. For example: The only way the API could suggest using 'seq' to check for emptiness is by not having a function called 'empty?'. It's irrelevant that 'empty?' is merely implemented as (not (seq)). The function is there for a reason. Are you suggesting that it's deprecated? If you would like to focus on a premature optimization of this sort, go right ahead. I will stick with the more meaningful function name. If I'm testing whether or not a sequence is empty I will use 'empty?'. Of course performance isn't usually the main driver, so if you feel empty? really is more expressive in your case, go for it. But the OP seems to care about performance, and suggesting empty? is off the mark. Apparently you didn't read what I wrote. I didn't suggest that using 'empty?' would solve the OP's performance issue. I simply pointed out that he was testing two opposite things. On Nov 14, 11:42 am, David Sletten da...@bosatsu.net wrote: On Nov 14, 2010, at 2:16 PM, Eric Kobrin wrote: In the API it is suggested to use `seq` to check if coll is empty. Your timing results raise some interesting questions, however, the API doesn't suggest using 'seq' to check if a collection is empty. That's what 'empty?' is for. The documentation note suggests (for style purposes apparently) that you use 'seq' to test that the collection is not empty. So to be precise you are testing two different things below. For instance, (identical? coll []) is true when coll is an empty vector. (seq coll) is true when coll is not empty. The correct equivalent would be to test (empty? coll). Of course, this doesn't change the results. I get similar timings with empty?: user= (let [iterations 1] (time (dotimes [_ iterations] (identical? [] []))) (time (dotimes [_ iterations] (empty? [] Elapsed time: 2.294 msecs Elapsed time: 2191.256 msecs nil user= (let [iterations 1] (time (dotimes [_ iterations] (identical? ))) (time (dotimes [_ iterations] (empty? Elapsed time: 2.657 msecs Elapsed time: 4654.622 msecs nil user= (let [iterations 1] (time (dotimes [_ iterations] (identical? () ( (time (dotimes [_ iterations] (empty? () Elapsed time: 2.608 msecs Elapsed time: 2144.142 msecs nil This isn't so surprising though, considering that 'identical?' is the simplest possible test you could try--do two references point to the same object in memory? It can't get any more efficient than that. Have all good days, David Sletten I was working on some code recently found that my biggest performance bottleneck was calling `seq` to check for emptiness. The calls to `seq` were causing lots of object allocation and taking noticeable CPU time. I switched to using `identical?` to explicitly compare against the empty vector and was rewarded with a drastic reduction in execution time. Here are some hasty tests showing just how big the difference can be: user= (let [iterations 1] (time (dotimes [_ iterations] (identical? [] []))) (time (dotimes [_ iterations] (seq [] Elapsed time: 3.512 msecs Elapsed time: 2512.366 msecs nil user= (let [iterations 1] (time (dotimes [_ iterations] (identical? ))) (time (dotimes [_ iterations] (seq Elapsed time: 3.898 msecs Elapsed time: 5607.865 msecs nil user= (let [iterations 1] (time (dotimes [_ iterations] (identical? () ( (time (dotimes [_ iterations] (seq () Elapsed time: 3.768 msecs Elapsed time: 2258.095 msecs nil Has any thought been given to providing a faster `empty?` that is not based on seq? Thanks, Eric Kobrin -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post
Re: Performance of seq on empty collections
On Nov 14, 2010, at 2:16 PM, Eric Kobrin wrote: In the API it is suggested to use `seq` to check if coll is empty. Your timing results raise some interesting questions, however, the API doesn't suggest using 'seq' to check if a collection is empty. That's what 'empty?' is for. The documentation note suggests (for style purposes apparently) that you use 'seq' to test that the collection is not empty. So to be precise you are testing two different things below. For instance, (identical? coll []) is true when coll is an empty vector. (seq coll) is true when coll is not empty. The correct equivalent would be to test (empty? coll). Of course, this doesn't change the results. I get similar timings with empty?: user= (let [iterations 1] (time (dotimes [_ iterations] (identical? [] []))) (time (dotimes [_ iterations] (empty? [] Elapsed time: 2.294 msecs Elapsed time: 2191.256 msecs nil user= (let [iterations 1] (time (dotimes [_ iterations] (identical? ))) (time (dotimes [_ iterations] (empty? Elapsed time: 2.657 msecs Elapsed time: 4654.622 msecs nil user= (let [iterations 1] (time (dotimes [_ iterations] (identical? () ( (time (dotimes [_ iterations] (empty? () Elapsed time: 2.608 msecs Elapsed time: 2144.142 msecs nil This isn't so surprising though, considering that 'identical?' is the simplest possible test you could try--do two references point to the same object in memory? It can't get any more efficient than that. Have all good days, David Sletten I was working on some code recently found that my biggest performance bottleneck was calling `seq` to check for emptiness. The calls to `seq` were causing lots of object allocation and taking noticeable CPU time. I switched to using `identical?` to explicitly compare against the empty vector and was rewarded with a drastic reduction in execution time. Here are some hasty tests showing just how big the difference can be: user= (let [iterations 1] (time (dotimes [_ iterations] (identical? [] []))) (time (dotimes [_ iterations] (seq [] Elapsed time: 3.512 msecs Elapsed time: 2512.366 msecs nil user= (let [iterations 1] (time (dotimes [_ iterations] (identical? ))) (time (dotimes [_ iterations] (seq Elapsed time: 3.898 msecs Elapsed time: 5607.865 msecs nil user= (let [iterations 1] (time (dotimes [_ iterations] (identical? () ( (time (dotimes [_ iterations] (seq () Elapsed time: 3.768 msecs Elapsed time: 2258.095 msecs nil Has any thought been given to providing a faster `empty?` that is not based on seq? Thanks, Eric Kobrin -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Slogan help
This is kind of a silly question, but I found this in my Clojure notes from last year: Contemporary Lisp Optimized for the JVM: Un- Restricted Expressiveness I can't remember whether I created it or I found it somewhere... Has anyone seen this phrase before? I can't find it on Google. Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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
Being not Lisp is a feature?
I don't want to start any language wars, but this is funny: http://gosu-lang.org/comparison.shtml Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Why isn't there a fold-right?
You could define a naive 'foldr' like this: (defn foldr [f coll] (if (empty? (rest coll)) (first coll) (f (first coll) (foldr f (rest coll ) (foldr list '(1 2 3 4)) = (1 (2 (3 4))) (foldr - [1 2 3 4]) = -2 However, this is not a tail-recursive function and will be limited by the size of the stack. An alternative involves reversing the sequence and applying the function with its arguments reversed. Then we can just pretend that we are doing a left fold and use 'reduce': (defn foldr [f coll] (reduce (fn [x y] (f y x)) (reverse coll))) Or for those of you who prefer that other people won't be able to read your code: (defn foldr [f coll] (reduce #(f %2 %1) (reverse coll))) Have all good days, David Sletten On Nov 5, 2010, at 10:03 PM, Yang Dong wrote: Maybe because Clojure has a vector, and conj conjoins new elements to the end of the vector, so there's mere little use of fold-right. But, fold-right is an abstraction tool, missing it in the core is kind of pity. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: figuring out sets
From a mathematical perspective the essential aspect of a set is its extension, namely what elements are contained in the set. This leads immediately to the property of uniqueness you mentioned. But the fundamental operation is 'contains?'. In other words, does the set contain some object or not? In order to search a vector to answer this question we have to perform a linear search. Thus, the longer the vector, the longer this search could take. In Clojure, sets are ultimately constructed out of hash tables, which allows a constant time check to see whether an object is a key and therefore a member of the set. The fact that the keys in a hash table are unique is a useful side benefit, but I believe that an efficient 'contains?' method is the main reason for their choice. All of the other set operations (union, intersection, etc...) are derived from our ability to determine whether or not an element is present in some set. In case you haven't found it yet, there is a section on Sets on the data structures page: http://clojure.org/data_structures Note especially that you have a choice between hash-set and sorted-set. Also check out the documentation for clojure.set: http://clojure.github.com/clojure/clojure.set-api.html Have all good days, David Sletten On Oct 31, 2010, at 10:55 PM, tonyl wrote: I guess I should've look harder (and ask more in the irc ;) it is a data structure and has a set fn too. #{} is just a reader macro for syntactic sugar. And the difference of usage between sets and vectors are they sets can't have duplicates. This is great, clojure group with irc chat, good learning. On Oct 31, 9:35 pm, tonyl celtich...@gmail.com wrote: I've been wondering if sets are actually a defined data structure like vectors and maps or are they a result of an expansion of the dispatch macro? I was wondering since it uses the dispatch macro and AFAIK there is no api fn to create them like hash-maps to create maps, vector/vec for vectors, or list for lists. Another thing I am trying to figure out is, are they really needed? vectors seem to fill in anytime sets could be used, unless I am missing something here. Any information would be appreciated. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: How to simplify cond statements
Andrei, You could just bind another local variable in the loop form: (loop [ps pairs ret {} ffps (ffirst ps)] (cond (empty? ps) ret (some-test ffps) (recur (rest ps) (add-to-result ret ffps) (ffirst (rest ps))) :true (recur (rest ps) (do-sth-else ret ffps) (ffirst (rest ps ) I think I like Andrew's solution better though. But you probably want to use 'reduce' instead of 'loop' anyway: (reduce (fn [ret [key val]] (if (some-test key) (add-to-result ret key) (do-sth-else ret key))) {} pairs) Notice how you can destructure each pair in a convenient way. BTW, do you really mean to call 'add-to-result' and 'do-sth-else' with a map and a key but no value? Have all good days, David Sletten On Oct 28, 2010, at 8:49 PM, andrei wrote: Hi, I have a code similar to this: (def pairs (list [1 :a] [2 :b] [3 :c])) ... (loop [ps pairs, ret {}] (cond (empty? ps) ret (some-test (first (first ps))) (recur (rest ps) (add-to- result ret (first (first ps :true (recur (rest ps) (do-smth-else ret (first (first ps)) You can see that string (first (first ps)), which actually gets first element of a first vector in pairs, occur many times. I can't move it before cond, since ps may be empty and evaluating of (first (first ps)) will produce an error (ok, it won't, but in general case it may). Is there another way to simplify code to not repeat one form several times? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
I eat parentheses for breakfast
Some of you might enjoy the music video for the new Land of Lisp book: http://www.youtube.com/watch?v=HM1Zb3xmvMcfeature=player_embedded Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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
I eat parentheses for breakfast
Some of you might enjoy the music video for the new Land of Lisp book: http://www.youtube.com/watch?v=HM1Zb3xmvMcfeature=player_embedded Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: precise numbers
Steven, Thanks for your comments. You bring up some interesting points, however, you also raise some more questions. First, you criticize my use of the variable name 'epsilon'. Of course, this usage is entirely consistent with its ubiquitous use in mathematics. I am designating a(n) (arbitrarily) small positive number used as a bound on the difference of x and y. I am well aware of the more restricted use that you are emphasizing: * (apropos-list 'epsilon) (DOUBLE-FLOAT-EPSILON DOUBLE-FLOAT-NEGATIVE-EPSILON LONG-FLOAT-EPSILON LONG-FLOAT-NEGATIVE-EPSILON SHORT-FLOAT-EPSILON SHORT-FLOAT-NEGATIVE-EPSILON SINGLE-FLOAT-EPSILON SINGLE-FLOAT-NEGATIVE-EPSILON EPSILON) In fact, two articles referenced in this thread also use 'epsilon' in exactly the way I have: http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm http://adtmag.com/Articles/2000/03/16/Comparing-Floats-How-To-Determine-if-Floating-Quantities-Are-Close-Enough-Once-a-Tolerance-Has-Been.aspx?Page=1 But if you would prefer to use the word 'tolerance' or some such term and reserve 'epsilon' (more properly 'machine epsilon') for the concept you have in mind, then I'll go along with that (and I won't even complain about you using the word 'mantissa' :-) ). More significantly, your discussion of scaling epsilon (your meaning, I presume) got me thinking. Is it strange that we are using a decimal fraction for our tolerance? Should we be thinking in terms of a binary fraction, i.e., rather than 1/10 we use 1/131072. In other words (Math/pow 2 -17) rather than (Math/pow 10 -5): (Math/pow 10 -5) = 9.999E-6 (Math/pow 2 -17) = 7.62939453125E-6 Or are you saying that we should specifically be scaling (machine) epsilon rather than some arbitrary tolerance? As you mentioned this is not as easy in Clojure/Java as in Common Lisp. Could we define 'scaled-epsilon' something like this? (defn log2 [x] (/ (Math/log x) (Math/log 2))) (def epsilon (loop [eps 1.0] (if ( (+ eps 1.0) 1.0) (recur (* eps 0.5)) eps))) (defn scaled-epsilon [x] (* epsilon (Math/pow 2 (Math/floor (log2 x ) And finally, what is your response to the OP? You define 'same?' but place several caveats on its use. Are you warning that there is no general-purpose solution? Have all good days, David Sletten On Oct 16, 2010, at 7:05 PM, Steven E. Harris wrote: cej38 junkerme...@gmail.com writes: (defn float= ([x y] (float= x y 0.1)) ([x y epsilon] (let [scale (if (or (zero? x) (zero? y)) 1 (Math/abs x))] (= (Math/abs (- x y)) (* scale epsilon ) You're scaling epsilon incorrectly here. Epsilon defines the smallest value that yields a value greater than one when added to one. If you're not using it along with one, you're using it incorrectly. What you need to do is scale epsilon by having its exponent match the value with which you want to use it, while maintaining its mantissa. The C library offers functions ldexp()¹ and frexp()² to split and scale the exponent of a floating point number, respectively; Common Lisp offers DECODE-FLOAT³ and SCALE-FLOAT for the same purpose. I don't know of any standard functions in Java -- or Clojure -- that allow one to destructure a floating point number like this. It's possible to use Float#floatToRawIntBits(), an understanding of IEEE 754, and tweezers to get there. If you assume you have a function called `scaled-epsilon' that accepts the exemplar value with which you intend to use epsilon, (defn scaled-epsilon [n] ...) you can use the following function `same?' to compare your floating point values, assuming they're nonnegative: , | (defn same? | [m n] | (if ( n m) | (sufficiently-close? n m) | (sufficiently-close? m n))) | | (defn- sufficiently-close? | [smaller larger] | (or (zero? larger) | (if (zero? smaller) | ( larger (scaled-epsilon 0.0))) | (zero? (- 1 (/ smaller larger) ` Note too that scaling epsilon must take into account whether you intend to add it or subtract it from some companion number. It's common to use the word epsilon to mean some fudge factor without considering what the value really means for a floating point number. Indeed, using it properly in Java is still too difficult. Footnotes: ¹ http://www.dinkumware.com/manuals/?manual=compleatpage=math.html#frexp ² http://www.dinkumware.com/manuals/?manual=compleatpage=math.html#ldexp ³ http://www.lispworks.com/documentation/HyperSpec/Body/f_dec_fl.htm#decode-float http://www.lispworks.com/documentation/HyperSpec/Body/f_dec_fl.htm#scale-float -- Steven E. Harris -- You 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
Re: precise numbers
On Oct 14, 2010, at 12:07 PM, cej38 wrote: I am kinda sorry that I started this whole thing. I don't need another lesson in limits. The simple fact of the matter is that, in my code, I run into a place where I have a comparison (= some-value (some-function some-data)), the function, data, and value can change. In a use case that I am interested in, I run into the problem stated, user= (= 0.0001 (- 12.305 12.3049)) false I am OK with replacing the = function with something like float= discussed above, but whatever I change it two needs to work. If anyone has found a way, that reliably works, please post it here. Further, , , =, and = would also be appreciated. Thank you. If you define 2 of them, then you get the rest for free. We already have float=: (defn float= ([x y] (float= x y 0.1)) ([x y epsilon] (let [scale (if (or (zero? x) (zero? y)) 1 (Math/abs x))] (= (Math/abs (- x y)) (* scale epsilon ) If x y, then in our case x should be more than epsilon below y: (defn float ([x y] (float x y 0.1)) ([x y epsilon] (let [scale (if (or (zero? x) (zero? y)) 1 (Math/abs x))] ( x (- y (* scale epsilon )) (defn float= ([x y] (or (float x y) (float= x y))) ([x y epsilon] (or (float x y epsilon) (float= x y epsilon (defn float ([x y] (not (float= x y))) ([x y epsilon] (not (float= x y epsilon (defn float= ([x y] (or (float x y) (float= x y))) ([x y epsilon] (or (float x y epsilon) (float= x y epsilon Then you determine how strict epsilon needs to be: (float 12.3049 12.305) = false (float 12.3049 12.305 1e-6) = true (float= 12.305 12.3049) = true (float= 12.305 12.3049 1e-6) = false (float 12.305 12.3049 1e-6) = true Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: precise numbers
On Oct 12, 2010, at 5:44 PM, Brian Hurt wrote: For example, in base 10, 1/3 * 3 = 0.9... It may seem counterintuitive, but that statement is perfectly true. 1 = 0.... That's a good test of how well you understand infinity. Of course, the problem arises when we truncate the string of 9's, which we must invariably do in a computer-based representation. Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: precise numbers
Here's a slightly more informal argument. Suppose you challenge me that 1 is not equal to 0.... What you are saying is that 1 - 0.... is not equal to 0, i.e., the difference is more than 0. But for any positive value arbitrarily close to 0 I can show that 0.999... is closer to 1 than that. If you were to say that the difference is 0.1, I could show that 0.999... 0.9 so the difference is smaller. For every 0 you added to your challenge: 0.1, 0.01, 0.001 I could provide a counterexample with another 9: 0.9, 0.99, 0.999, ... In other words, there is no positive number that satisfies your claim, so equality must hold. Have all good days, David Sletten On Oct 13, 2010, at 6:36 PM, Matt Fowles wrote: Felix~ You are correct that the sequence of numbers 0.9 0.99 0.999 ... asymptotically approaches 1; however, the number 0.... (with an infinite number of 9s) is equal to 1. The formal proof of this is fairly tricky as the definition of the real number is usually done as an equivalence class of Cauchy sequences; a simplified version of the proof can be thought of as follows: For any two real numbers a and b there exists an infinite number of real numbers c such that a c b. However, there do not exist any numbers between 0.9... and 1, thus they must be same number. As it turns out, it took mathematicians a long time to nail down formally exactly what we naively think of as numbers. Matt On Wed, Oct 13, 2010 at 6:27 PM, Felix H. Dahlke f...@ubercode.de wrote: On 13/10/10 22:28, David Sletten wrote: On Oct 12, 2010, at 5:44 PM, Brian Hurt wrote: For example, in base 10, 1/3 * 3 = 0.9... It may seem counterintuitive, but that statement is perfectly true. 1 = 0.... That's a good test of how well you understand infinity. I'm clearly not a mathematician, but doesn't 0.9... asymptotically approach 1, i.e. never reaching it? How is that the same as 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 -- You 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: precise numbers
This discussion may help: http://www.gettingclojure.com/cookbook:numbers#comparing-floats Have all good days, David Sletten On Oct 12, 2010, at 12:17 PM, cej38 wrote: I keep running into this type of problem: user= (- 12.305 12.3049) 9.9976694E-5 The computer (probably the JVM) has just lied to me. Any fourth grade student will know that this does not equal 0.0001. This would be less of a problem is the JVM was consistent; if it were consistent then the following equality would be true: user= (= 0.0001 (- 12.305 12.3049)) false Now it has lied to me again! I need a method to reliably compare two numbers. My first choice would be to have the JVM compute (- 12.305 12.3049) correctly. Barring that, I need a way to, without fail, compute the truthfulness of the following: =, , , =, =. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: precise numbers
I suggest you read the article a bit more closely. Here are the details of your specific case. The number that you are typing as 12.305 is actually being stored in the computer as this: 1100.010011110100001011110100001011100 This number is actually this fraction: 1731774794212311/140737488355328 So here is the true value in decimal: 12.304715782905695959 It is not possible to represent 12.305 any closer than that on conventional hardware. Likewise your 12.3049 is this: 1100.01001110110011010010100010001100111001110 Which is this fraction: 3463521440926951/281474976710656 Or in decimal: 12.304848840923025272 This is the best approximation for 12.3049. When you scale epsilon (0.1) by about 12, you can see that these two numbers are equal as expected in the sense defined by float=. Have all good days, David Sletten On Oct 12, 2010, at 2:53 PM, cej38 wrote: On Oct 12, 12:50 pm, David Sletten da...@bosatsu.net wrote: This discussion may help:http://www.gettingclojure.com/cookbook:numbers#comparing-floats I originally tried something like float= described in the link, I give the definition here (defn float= ([x y] (float= x y 0.1)) ([x y epsilon] (let [scale (if (or (zero? x) (zero? y)) 1 (Math/abs x))] (= (Math/abs (- x y)) (* scale epsilon ) And the truth-table that was given with the function definition: (float= 0.01 0.0) = false (float= 0.001 0.0) = false (float= 0.0001 0.0) = false (float= 0.1 0.0) = true And this works for the problem that I discussed before user= (float= 0.0001 (- 12.305 12.3049)) true But I can come up with a use case where it fails: user= (float= 12.3049 12.305) true The problem is that the IEEE specification does a great job of comparing floats, but does a crap job of doing simple math on them. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Is This Function Idiomatic Clojure?
On Oct 7, 2010, at 2:29 AM, Stefan Rohlfing wrote: Dear Clojure Group, Following an Enlive tutorial I wanted to implement a function 'd-map' that takes an arbitrary number of [:key (list of values)] parameters like this: (d-map [:headline [this is me] ] [:points [1 2 3] ] [:comments [10 20 30] ]) and returns a collection of [:key value] vectors where each value is grouped with its respective key: [ [:headline this] [:headline is] [:headline me] [:points 1] [:points 2] [:points 3] [:comments 10] [:comments 20] [:comments 30] ] I could only come up with the following implementation for 'd-map'. Although it works it just does not 'feel' elegant of even very functional: (defn d-map [ kfps] (let [keys (map first kfps) fns (map second kfps)] (loop [keys keys fns fns res []] (if (seq keys) (recur (rest keys) (rest fns) (into res (map (fn [x] [(first keys) x]) (first fns res If you treat a map as a sequence it will yield the vectors you are handling explicitly: (map identity {:a [1 2 3] :b [4 5 6]}) = ([:a [1 2 3]] [:b [4 5 6]]) So it might be more convenient to pass in a map and do something like this: (defn d-map [m] (apply concat (map (fn [[key val-list]] (map (fn [val] [key val]) val-list)) m))) (d-map {:headline [this is me] :points [1 2 3] :comments [10 20 30]}) ([:headline this] [:headline is] [:headline me] [:points 1] [:points 2] [:points 3] [:comments 10] [:comments 20] [:comments 30]) Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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
Attribution in the cookbook
As I mentioned before, I have no intention of being the sole contributor to the Clojure Cookbook site. In a few days we plan to open it up so that anyone may contribute recipes (or fix mine :-) ). However, in the meantime I have already included a little bit of material from other people. Specifically I added a couple of examples gleaned from this mailing list: http://www.gettingclojure.com/cookbook:sequences#winnow I haven't asked for permission (sorry Adrian and Rich) because I'm not presenting the material as my own and it's taken from what's already a very public source (which I've indexed). If anyone has a problem with this I will remove their content. I have also incorporated some suggestions made in the comments at the site (thanks Sean, matti, and tebeka) without asking permission. Presumably these readers added their thoughts for the purpose of improving the examples. What are your thoughts on this issue? Am I out of line, or is this a reasonable policy? Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Changing keys in a map
On Oct 1, 2010, at 1:57 AM, Sean Corfield wrote: On Thu, Sep 30, 2010 at 12:52 AM, David Sletten da...@bosatsu.net wrote: Huh?! How many solutions do you want? You're starting to annoy me Sean. Sorry dude. I think it's really insightful to see lots of different solutions to small point problems like this when you're learning a language - particularly when the issue of idiom is being discussed. I've certainly found this thread educational and I hope I'm not annoying too many people :) Sean, Sean...I was just making fun of your signature. :) Keep up the questions! If you're not annoying somebody, you're not really alive. -- Margaret Atwood -- You 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: Changing keys in a map
On Sep 30, 2010, at 2:53 AM, Baishampayan Ghose wrote: I have a need to convert maps in the following ways: Given a map with keyword keys, I need a map with uppercase string keys - and vice versa. { :stuff 42 :like 13 :this 7 } = { STUFF 42 LIKE 13 THIS 7 } What about this - (into {} (for [[k v] { :stuff 42 :like 13 :this 7 }] [(.toUpperCase (name k)) v])) One small suggestion based on something Christophe Grand once pointed out: (defn string-keys [m] (into (empty m) (for [[k v] m] [(.toUpperCase (name k)) v]))) (defn keyword-keys [m] (into (empty m) (for [[k v] m] [(keyword (.toLowerCase k)) v]))) This will preserve the type of the map. (string-keys { :stuff 42 :like 13 :this 7 } ) = {THIS 7, LIKE 13, STUFF 42} (keyword-keys (string-keys { :stuff 42 :like 13 :this 7 } )) = {:stuff 42, :like 13, :this 7} Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Changing keys in a map
On Sep 30, 2010, at 3:40 AM, Sean Corfield wrote: On Thu, Sep 30, 2010 at 12:30 AM, Mark Engelberg mark.engelb...@gmail.com wrote: Except that if you use .toUpperCase, you have to remember to type hint the input. Any time you call a Java method without type hinting, you take a significant performance hit. The wrapper function takes care of that for you. Good to know, thanx Mark. Keep 'em coming folks, this is exactly what I was hoping for when I posted the question. Huh?! How many solutions do you want? You're starting to annoy me Sean. Hmm, I guess you must really be alive. :) If you're not annoying somebody, you're not really alive. -- Margaret Atwood -- You 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 write this in Clojure? Example from PAIP
On Sep 29, 2010, at 3:55 AM, nickikt wrote: (defun find-all (item sequence rest keyword-args key (test #'eql) test-not allow-other-keys) Find all those elements of sequence that match item, according to the keywords. Doesn't alter sequence. (if test-not (apply #'remove item sequence :test-not (complement test-not) keyword-args) (apply #'remove item sequence :test (complement test) keyword-args))) Both Clojure and Common Lisp have a function to remove a value from a sequence. However, the CL version supports quite a few more options, which accounts for the complexity of this FIND-ALL function. The function 'remove' in both languages obviously has to take an item to look for and a sequence to search. But the CL version also accepts various keyword arguments that tailor how it behaves. There is a default test which determines whether the item matches a given element, but another test can be specified by the :test keyword. This allows for various flavors of equality when matching. There is also a :test-not keyword which works in the opposite sense. You can see both of those keywords above. The CL version also accepts other keywords such as :start, :end, :from-end, :count, and :key. In the section after the lambda-list keyword key above you can see that FIND-ALL also accepts :test and :test-not keywords, with a default :test of the function EQL. The lambda-list keyword allow-other-keys is used to show that FIND-ALL will also accept the other REMOVE keywords and pass them along. Before the key section, however, there is the rest section. What actually happens is that every argument passed to FIND-ALL, besides the first two required arguments, is captured as a list in the variable KEYWORD-ARGS. CL also processes the :test and :test-not keyword arguments separately, but they and their keywords are also bundled up in KEYWORD-ARGS. This makes it easy to pass everything along to REMOVE via the APPLY form. Here is a Clojure implementation that is pretty true to the spirit of the CL version. All of the optional arguments are captured in the list 'keyword-args', but we also break out the keywords into a map: (defn find-all [item coll keyword-args] (let [keywords (apply hash-map keyword-args)] (if (:test-not keywords) (remove (fn [elt] ((:test-not keywords) item elt)) coll) (remove (fn [elt] (not ((:test keywords) item elt))) coll Since we want to find things that match our criterion we reverse the sense of the :test and remove things that fail our criterion. But we have to do the opposite with the :test-not case here since Clojure's 'remove' doesn't understand that :test-not is the opposite of :test. Notice also that we can call 'remove' directly (without 'apply') since we aren't passing in a list of keywords. (find-all 1 '(1 2 3 2 1) :test =) = (1 1) (find-all 1 '(1 2 3 2 1) :test not=) = (2 3 2) (find-all 1 '(1 2 3 2 1) :test-not =) = (2 3 2) Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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 write this in Clojure? Example from PAIP
On Sep 29, 2010, at 11:01 AM, Meikel Brandmeyer wrote: Hi, a slight enhancement for 1.2: Clojure now supports keyword arguments directly. (defn find-all [item coll {:keys [test test-not] :or {test =}}] (if test-not (remove #(test-not item %) coll) (filter #(test item %) coll))) That's really nice Meikel. I was trying to remember how to do the new keywords, but I couldn't find an example. You have the default value for :test in there too. Interesting idea to replace 'remove not' with 'filter'. Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Literal collection of numbers - prefer list or vector?
On Sep 26, 2010, at 10:42 AM, Steven E. Harris wrote: ataggart alex.tagg...@gmail.com writes: Vectors also permit evaluation of the literal collection's elements: user= [(+ 1 2) (+ 3 4)] [3 7] user= '((+ 1 2) (+ 3 4)) ((+ 1 2) (+ 3 4)) That's a false distinction. You used `quote' rather than `list'. Macroexpand your form to see: , | user (quote ((+ 1 2) (+ 3 4))) | ((+ 1 2) (+ 3 4)) ` Umm, kind of...The single quote is a macro character not a real macro. Therefore it's not subject to macroexpansion as macros are. Unfortunately the Clojure reader normally conspires against you to hide what's really going on. The reader silently converts 'pung to (quote pung) prior to evaluation, so you have to come at it in a roundabout way: (read-string '((+ 1 2) (+ 3 4))) = (quote ((+ 1 2) (+ 3 4))) (count (read-string '((+ 1 2) (+ 3 4 = 2 (class (read-string '((+ 1 2) (+ 3 4 = clojure.lang.Cons (first (read-string '((+ 1 2) (+ 3 4 = quote At least the Clojure printer is cooperating here. In Common Lisp the printer helps hide QUOTE too in the first line here: ? (read-from-string '(+ 1 2)) '(+ 1 2) 8 ? (first (read-from-string '(+ 1 2))) QUOTE ? (length (read-from-string '(+ 1 2))) 2 Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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
ANN: Clojure Cookbook
Ladies and Gentlemen, I present for your viewing pleasure the Clojure Cookbook (beta :) ): http://www.gettingclojure.com/cookbook:clojure-cookbook Gregg Williams has set up a framework at Getting Clojure to gather material, primarily focused on newbies, on how to flatten the learning curve. The cookbook is a part of that vision. Inspired of course by O'Reilly's Perl Cookbook, the cookbook aims to present concrete examples along with brief discussions of specific tasks a new Clojure programmer might want to accomplish. The cookbook should complement the existing Clojure books and other documentation and provide additional examples that the other resources don't have time or space to consider. At this point I have seeded the cookbook with approximately 20 recipes. I want to emphasize that I hope this will be a community resource with others providing content or even fixing my explanations where they are incorrect or off target. At the moment the cookbook is essentially read-only aside from the comments section at the bottom of each page. But once we get a sense of the community response the site will be opened for anyone to contribute. Please take a look at the site and let us know what works and what needs to be fixed. And start thinking up your own recipes. Thanks. Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Byte Literals
Ah, right. Thanks. I'm not keeping up with my Clojure version numbers... On Sep 24, 2010, at 1:52 AM, Rasmus Svensson wrote: There's also 'bytes', 'byte-array' and 'into-array': (byte-array (map byte [1 2 3])) (into-array Byte/TYPE (map byte [1 2 3])) // raek -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Byte Literals
I'm not quite sure what you're asking. Clojure doesn't have byte literals, but you can use the function 'byte' to coerce an int literal: (map class [2 3 4]) = (java.lang.Integer java.lang.Integer java.lang.Integer) (map class (map byte [2 3 4])) = (java.lang.Byte java.lang.Byte java.lang.Byte) Or you can create a Java byte[] array: (def a (make-array Byte/TYPE 3)) But you still have to coerce: (aset a 0 (byte 2)) = 2 (aset a 0 2) = java.lang.IllegalArgumentException: argument type mismatch (NO_SOURCE_FILE:0) Have all good days, David Sletten On Sep 24, 2010, at 12:31 AM, HiHeelHottie wrote: Is there a way to create a vector of byte literals eg. [64 69 72] as bytes? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Little LISPer and Ten Commandments
That book is amazing. Enjoy working through it, it will stretch your mind. However, keep in mind that their emphasis is on getting a feel for how recursion works. Real world Clojure code (any Lisp really) de-emphasizes recursion to some extent. Particularly with regard to list (sequence) processing (the name Lisp comes from List processing after all), Clojure has a powerful library of functions that handle much of what the book implements recursively. For example, if you would like to apply a function f to each element in a list you could write code similar to the book: (defn my-map [f l] (cond (empty? l) '() :else (cons (f (first l)) (my-map f (rest l ) (my-map inc '(1 2 3 4 5)) = (2 3 4 5 6) Here we apply the First Commandment--is the list l empty? If so, return an empty list. Otherwise, apply the function to the first element of the list and recursively process the rest of the list. We could accomplish the same thing more succinctly in Clojure like this: (map inc '(1 2 3 4 5)) = (2 3 4 5 6) Clojure has a built-in 'map' function which iterates over each element in a sequence, not merely lists: (map dec [2 4 6 8]) = (1 3 5 7) (map #(Character/toUpperCase %) Is this not pung?) = (\I \S \space \T \H \I \S \space \N \O \T \space \P \U \N \G \?) Furthermore, the book is pretty much using a dialect of Lisp called Scheme, and the semantics are a little different from Clojure. For instance, Clojure does not have the concept of 'atom'. It may actually be easier to work through the book in a Scheme environment (I used Common Lisp though). But what you learn there will help you later with Clojure. In fact, if you are brave here is some of the material from chapter 9 dealing with the Y-Combinator implemented in Clojure. It's pretty weird: http://groups.google.com/group/clojure/browse_thread/thread/c9bd4e79e5877a66 Have all good days, David Sletten On Sep 21, 2010, at 6:38 PM, ax2groin wrote: Newbie here, to both LISP and Clojure. A friend has lent me a copy of The Little LISPer and I've started working through it, using some web resources to translate it into clojure. My questions: How relevant are the ten commandments? What modification need to be made ... either to the commandments or to your code in clojure? I ask because the first commandment (always ask null?) hasn't translated directly into any single statement for me. I can achieve the same with (or) to navigate the difference between nil and () in clojure, but sure that difference is in there for a reason. Any other input on the other commandments or using the book in general? Thanx -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: misunderstanding collection
Hi Glen, You have two separate problems here. The question of understanding collections isn't really that tricky. Your variable 'signals' is simply a 2-element list. Conceptually it's no different than: (a b). But in your case each element is itself a 3-element list. An equivalent would be: ((a b c) (d e f)). But again, in your case, each of those 2nd-level elements is itself a 4-element list. So your list has 3 levels with numbers at the bottom. If you map across signal, you will handle the two 3-element lists: (map count signal) = (3 3) To get to the next level, we need another map: (map (fn [level-1] (map count level-1)) signal) = ((4 4 4) (4 4 4)) Finally, we can get to the numbers themselves: (map (fn [level-1] (map (fn [level-2] (map class level-2)) level-1)) signal) = (((java.lang.Integer java.lang.Integer java.lang.Integer java.lang.Integer) ... Let's take a look at the second problem before we finish above. Your example with 'reduce' is: (map #(map reduce + %) signal) But we can't bundle it that way. 'reduce' is a 2-arg (optionally 3-arg) function, however, you are asking 'map' to apply 'reduce' to the 2 sequences '+' and the value of '%'. Of course, '+' is not a sequence. What you need instead is this: (map #(map (fn [coll] (reduce + coll)) %) signal) = ((10 14 18) (18 22 26)) Now 'reduce' takes each of the sublists in '%' as an arg and does its work. You might find it easier to work with such nested structures by using named functions to process each level. Or at the very least be careful about choosing names and layout: (map (fn [level-1] (map (fn [level-2] (reduce + level-2)) level-1)) signal) That's a lot easier for me to understand. Have all good days, David Sletten On Aug 25, 2010, at 10:06 AM, Glen Rubin wrote: After toying around at the REPL I realize that I have been working with a heretofore invalid understanding of collections. For example, working with the following collection(s): signal: (((1 2 3 4) (2 3 4 5) (3 4 5 6)) ((3 4 5 6) (4 5 6 7) (5 6 7 8))) I wanted to sum each individual list: e.g. (1 2 3 4) = (10) I thought I could do this as follows: (map #(map reduce + %) signal) This resulted in an error, so trying to comprehend why I ran the following: (map #(map identity (take 1 %)) signal) which results in, (((1 2 3 4)) ((3 4 5 6))) So, clojure sees 'signal' as 2 collections, whereas I thought it was a single collection. This makes me concerned that I have been doing everything wrong thus far and getting computational errors. :( So, how should I sum each individual list in the above collections? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: trouble using nested map fn
There may be some value in the intellectual exercise to try something like your solution, but I think this is far more tractable if you use meaningful variable names: (map (fn [group scalars] (map (fn [trial] (map (fn [signal scalar] (* signal scalar)) trial scalars)) group)) signal target) You have one top-level list in 'target' for each top-level list in 'signal', so clearly the outer map must pair them. However, you want each 'target' sublist to be applied to several sublists, so you need the next map to iterate across the 2nd-level lists in 'signal'. Finally, the innermost map must do the actual work pairing each 'signal' and 'scalar'. Have all good days, David Sletten On Aug 23, 2010, at 11:26 AM, Glen Rubin wrote: I am trying to write a fn to correlate 2 signals using 3 nested map fn. I have 2 collections of data. THe first group of signals called target looks something like this. target: ( (1,2,3,4) (2,3,4,5) ...) The second collection is called signal and looks like this: signal: ( ((1,2,3,4)(2,3,4,5)(3,4,5,6)) ((2,3,4,5)(3,4,5,6)(4,5,6,7)) ... ) I would like to take the first list in target and multiply it by every list in the first group of signal. And then continue on processing the second list, etc... which would result in something like: ( ((1,4,9,16)(2,6,12,20)(3,8,15,24)) ((4,9,16,25) (6,12,20,30) (8,15,24,35)) ... ) I try a nested map fns like this, but can't get it to work: (map #(map #(map * %1 %2) %1 %2) target signal) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Simple Regex Question
Does this make the processing a little clearer? #(?=([ ab]))?([ab])\2* Have all good days, David Sletten On Aug 21, 2010, at 10:02 PM, CuppoJava wrote: Wow that's so short! Thanks Chouser! I will abstain from showing the awful hack that I've been working with currently. -Patrick On Aug 21, 8:45 pm, Chouser chou...@gmail.com wrote: On Sat, Aug 21, 2010 at 7:11 PM, CuppoJava patrickli_2...@hotmail.com wrote: Hi Everyone, I'm extremely stuck on this simple regex question, which I'm sure someone with a little more experience will be able to write in a second. I would really appreciate the help. Given a string consisting of a's, b's, and spaces: aaa bbb abb ab bb I want to tokenize this into string's of a's and b's. eg. aaa, bbb, a, bb, a, b, bb AND also, I have to be able to tell which of the strings of b's was preceded with an a, and which was preceded by a space. (- aaa bbb abb ab bb (re-seq #(?=(.))?(\w)\2*) (map (fn [[s pre]] {:s s, :pre pre}))) returns a lazy seq: ({:s aaa, :pre nil} {:s bbb, :pre } {:s a, :pre } {:s bb, :pre a} {:s a, :pre } {:s b, :pre a} {:s bb, :pre }) --Chouserhttp://joyofclojure.com/ -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: [noob] Using dochars
Hi Mark, What the documentation means is that you give dochars a name for a variable and a string to process. It then iterates over each character in the string using 'name' as a variable representing the character, so that each of the (0 or more) forms in the body can do something with the character by referring to name: (dochars [ch Is this not pung?] (print (Character/toUpperCase ch))) However, what you probably want to do is use 'map' to transform one string to another: (map (fn [ch] (Character/toUpperCase ch)) Is this not pung?) = (\I \S \space \T \H \I \S \space \N \O \T \space \P \U \N \G \?) But now we've wound up with a sequence rather than a string specifically, so we need one more step: (apply str (map (fn [ch] (Character/toUpperCase ch)) Is this not pung?)) = IS THIS NOT PUNG? Have all good days, David Sletten On Aug 20, 2010, at 4:25 AM, probertm wrote: Hi... New here to Clojure-land and loving what I am seeing, though I am not getting some of the forms yet. Can someone help me with contrib.str-utils2/dochars? I have a need to iterate over each character in a string and this seems to be a macro that will do that (I suppose I could create my own map function but that kind of misses the point ;) ). The doco says Usage: (dochars bindings body) bindings = [name string] Repeatedly executes body, with name bound to each character in string. which I don't really understand. Any examples gratefully accepted. TIA .. mark. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: questions about float operations
This may help explain things: http://groups.google.com/group/clojure/msg/325228e8b66923ac Have all good days, David Sletten On Aug 20, 2010, at 8:26 AM, bufo wrote: I am currently learning clojure by reading The Joy of Clojure and I have 2 questions on float opertions: - why does (+ 4.2 8.4) return 12.601 and (+ 1.5 2.6) 4.1? Since 4.2, 8.4 and (+ 4.2 8.4) are java Doubles why does it not behave as expected? What does clojure do in the background? - I also have a question regarding float precison in big operations, consider the following code: (defn ope [a b] (+ a (* b (Math/sqrt b (reduce ope (range 100)) 3.9501039E14 vs (loop [i 1 x 0] (if ( i 100) x (recur (inc i) (ope x i 4.0501039E14 (which is what we get if we do a for loop in java) I had the same problem in haskell, why are the two results different? 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 -- You 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: Please help! Really simple function not working.
Carlos, I think this is pretty much what you had in mind: (defn count-zeros [l] (cond (empty? l) 0 (zero? (first l)) (inc (count-zeros (rest l))) :else (count-zeros (rest l (count-zeros '(9 8 6 0 1 2 0 5)) = 2 (count-zeros '(9 8 6)) = 0 (count-zeros '()) = 0 Of course the above version is not tail-recursive. However, once you're written a straightforward recursive function it is often easy to see how to rewrite it (using an accumulator here) to take advantage of Clojure's recur: (declare count-zeros-aux) (defn count-zeros [l] (count-zeros-aux l 0)) (defn- count-zeros-aux [l result] (cond (empty? l) result (zero? (first l)) (recur (rest l) (inc result)) :else (recur (rest l) result))) Here the base function presents the same interface to the user, and the private auxiliary function takes an additional accumulator argument. You could accomplish pretty much the same thing by defining two versions with different arities: (defn count-zeros ([l] (count-zeros l 0)) ([l result] (cond (empty? l) result (zero? (first l)) (recur (rest l) (inc result)) :else (recur (rest l) result Or you could simplify things by using loop: (defn count-zeros [l] (loop [num-list l result 0] (cond (empty? num-list) result (zero? (first num-list)) (recur (rest num-list) (inc result)) :else (recur (rest num-list) result Have all good days, David Sletten On Aug 9, 2010, at 8:24 PM, Carlos Torres wrote: Hi to everyone, I'm trying to create a function that takes a simple list and returns the number of zeros in the list. So I'm assuming that they will enter a list containing only numbers. This is what I have so far, but it only works when the list empty. Can somebody tell me what I'm missing? (defn count-zeros Returns the numbers of zero in a simple sequence of numbers [list1] (cond (empty? list1) 0 (not (zero? (first list1))) 0 :else (recur (+ 1 (count-zeros (rest list1)) --Carlos -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: noob q: infinite loop recur
On Aug 9, 2010, at 11:52 PM, chepprey wrote: (defn show [words] (let [word (first words)] (do (println word) (if (nil? word) (println DONE) (recur (rest words)) (show '(some sample words)) ... this shows the 3 words, then DONE, and terminates. Your program works but maybe not the way you think it does. The first issue is related to an idiosyncrasy of other Lisps compared to Clojure. It's easy to understand the basic behavior of 'first' and 'rest': (first '(a b c)) = a (rest '(a b c)) = (b c) However, what happens when we look at the empty list? (first '()) = nil (rest '()) = () Notice how Clojure returns two different values here. Other Lisps (such as Common Lisp) define FIRST/REST of the empty list to both be NIL (i.e., the empty list itself). So it is common in other Lisps to test for the end of a list using the equivalent of 'nil?', namely the function NULL. But in Clojure if we are traversing a list and looking for the end, the correct function is 'empty?'. (nil? '()) = false (empty? '()) = true Furthermore, in your example you are testing whether the current first element is nil rather than checking that the list itself is empty. Your test should be (if (empty? words) ...). Your program eventually terminated because once your list was empty the first element was evaluated to be nil as above. But originally, I was trying to use loop/recur. If I replace the let with loop in the above code, it goes into an infinite loop. I assume there's something different in the scoping/binding rules with loop, but I can't find a good explanation of what. I read in Programming Clojure, regarding loop, that it ...works like let, establishing bindings and then evaluating exprs... This is a separate issue. It is true that 'loop' establishes bindings, however, it is your responsibility to update those bindings on each iteration through the loop by means of the 'recur' form. Your 'recur' confuses the distinction between the variables 'words' and 'word'. On the initial loop iteration, the variable 'word' is assigned the value of the first element of 'words'. But on the next iteration (and all others) your recur passes the rest of 'words' as the new value of 'word'. So in your example we wind up with this: 1. word - some 2. word - (sample words) Obviously this 2-element list is never 'nil?', and the recur form keeps reassigning the same value forever. Instead, you need to rebind the variable 'words' to subsequent tails of the original list: (defn show [words] (loop [l words] (println (first l)) (if (empty? l) (println DONE) (recur (rest l) And you probably want to test for the end of list before you print anything: (defn show [words] (loop [l words] (if (empty? l) (println DONE) (do (println (first l)) (recur (rest l )) Have all good days, David Sletten -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: shortcut for for comprehension
On Apr 20, 2009, at 12:19 PM, Michael Hunger wrote: Is it possible to use :while to shortcut a for macro when a certain number of yiels have happened? e.g. (for [x (range 1000) :when (= (rem x) 1) :while (number of yields = 10)] so i want only the first 10 results. Is it possible? Yes... (let [yields (ref 0)] (for [x (range 1000) :when (when (odd? x) (dosync (ref-set yields (inc @yields))) true) :while (= @yields 10)] x)) = (1 3 5 7 9 11 13 15 17 19) Is it advisable? No. Or should I just use (take 10 ) on the for ? Definitely yes. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: howto update with a constant when a function is expected?
On Apr 15, 2009, at 11:30 PM, bOR_ wrote: Hi all, some functions (like map, or update-in) expect a function to be applied on a value. In the case where the update I want is merely a constant, is there a short way to write it? (map (fn [n] :new) (list :old1 :old2 :old3)) works (map :new (list :old1 :old2 :old3)) unfortunately doesn't work in the way I would hope (gives nil nil nil) There are a number of possible answers here depending on what you're trying to do. The one that corresponds literally to your approach is this: (map (constantly :new) (list :old1 :old2 :old3)) 'constantly' creates a function which simply ignores its arguments and returns the value provided. But if all you are really doing is creating a sequence of a given length containing a constant element, then this is more straightforward: (repeat (count (list :old1 :old2 :old3)) :new) Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: howto update with a constant when a function is expected?
On Apr 16, 2009, at 1:57 AM, bOR_ wrote: (fn [n] :new) or (constantly :new) was what I was looking for. Just found out the two are not exactly the same. Hmm. I guess I should have expected this from the docstring. Anyway, thanks all! Clojure= (map (constantly (ref nil)) (range 10)) 50 (#Ref clojure.lang@1417690 #Ref clojure.lang@1417690 #Ref clojure.lang@1417690 #Ref clojure.lang@1417690 #Ref clojure.lang@1417690 #Ref clojure.lang@1417690 #Ref clojure.lang@1417690 #Ref clojure.lang@1417690 #Ref clojure.lang@1417690 #Ref clojure.lang@1417690) 51 Clojure= (map (fn [n] (ref nil)) (range 10)) 52 (#Ref clojure.lang@1e32382 #Ref clojure.lang@1304043 #Ref clojure.lang@cb07ef #Ref clojure.lang@176086d #Ref clojure.lang@234265 #Ref clojure.lang@dc1f04 #Ref clojure.lang@1784427 #Ref clojure.lang@c272bc #Ref clojure.lang@1fac852 #Ref clojure.lang.Ref...@1758cd1) In that case, here's something that reads more clearly to me: (take 10 (repeatedly #(ref nil))) = (#r...@66036e: nil #r...@6b6b13: nil #r...@42c747: nil #r...@2943ff: nil #r...@2f4fc5: nil #r...@1e4683: nil #r...@a761ce: nil #r...@622e6: nil #r...@2689a7: nil #r...@173b39: nil) Also, in your second example above, I think it's more idiomatic to write (fn [_] (ref nil)) to demonstrate that you're ignoring the argument. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Fixing Documentation Errors
What is the mechanism for reporting errors in documentation? For instance, the doc string is in the wrong place for 'rational?'. And 'quot' and 'rem' take parameters 'num' and 'div', but the documentation talks about denominators rather than divisors. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Simple dosync/alter question
On Apr 6, 2009, at 9:02 AM, bgray 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) Paul and David N. have already given you the right advice. But to help you understand why your square-ref function didn't work, compare it to this: (defn square-ref [x] (dosync (alter foo (fn [_] (square x) Do you see the difference? Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Nested loops
I'm working on a spell checker that attempts to suggest corrections from a given dictionary. One of the heuristics is to see if inserting a character at each point in the given string results in a recognized word. So I have an outer loop that moves across each position in the string and an inner loop that tests a-z at that point. In Common Lisp I use this: (defun word-insertion (s) (let ((s1 (make-string (1+ (length s) ; Copy the input and make room for an extra char (setf (subseq s1 1 (length s1)) s) (dotimes (i (length s1) nil) ; Outer loop (unless (zerop i) (setf (char s1 (1- i)) (char s (1- i (dotimes (j (1+ (- (char-code #\z) (char-code #\a ; Inner loop (setf (char s1 i) (code-char (+ j (char-code #\a (let ((index (binary-search s1))) ; Check in the dictionary for a match (when index (return-from word-insertion index ))); Done if match found The main point is that I can use two DOTIMES forms, one nested inside the other, and I can exit either at any point. I actually exit the entire function as soon as I find a match via RETURN-FROM. Clojure has 'dotimes', but from what I understand there is no way to exit prematurely? The obvious alternative is to nest a couple of 'loop' forms: (defn g [p q] (loop [i 0] (if (= i p) nil (do (loop [j 0] (if (= j q) nil (do (prn (list i j)) (recur (inc j ) (recur (inc i )) The loop/recur pairs seem to establish outer and inner recursion points (I can't really tell from the macro expansion), and this function behaves as expected. This approach appears to be equivalent to something like this: (defn f [p q] (letfn [(outer [i] (if (= i p) nil (do (inner i 0) (outer (inc i ) (inner [i j] (if (= j q) nil (do (prn (list i j)) (inner i (inc j )] (outer 0))) Again the important thing is that I can terminate the inner loop based on my own condition. However, it seems that in the outer loop I have to capture the value of the inner loop directly. I can't simply leave both loops: (defn word-insertion [s] (let [s1 (make-array Character/TYPE (inc (count s)))] (System/arraycopy (.toCharArray s) 0 s1 1 (count s)) (loop [i 0] (if (= i (count s1)) nil (do (when-not (zero? i) (aset s1 (dec i) (nth s (dec i (let [match (loop [j 0] (if (= j (inc (- (int \z) (int \a nil (do (aset s1 i (char (+ j (int \a (let [match (binary-search (String. s1))] (if match match (recur (inc j )))] (if match match (recur (inc i ) One other version I considered makes due with a single 'loop', but this is pretty convoluted: (defn word-insertion [s] (let [s1 (make-array Character/TYPE (inc (count s)))] (System/arraycopy (.toCharArray s) 0 s1 1 (count s)) (loop [i 0 j 0] (when (and (not (zero? i)) (zero? j)) (aset s1 (dec i) (nth s (dec i (cond (= i (count s1)) nil (= j (inc (- (int \z) (int \a (recur (inc i) 0) :else (do (aset s1 i (char (+ j (int \a (let [match (binary-search (String. s1))] (if match match (recur i (inc j ) The one nice thing about this is I can terminate the entire loop and return a value in one step. Otherwise the logic is a mess. Any suggestions out there? Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Nested loops
On Apr 4, 2009, at 6:18 PM, Mark Triggs wrote: Hi David, Quite a few times when I've felt the need for this sort of thing I've found that laziness comes to the rescue. Would something like this sort of approach work for you? (defn possibilities [word pos] All variations of `word' with letters from 'a' to 'z' inserted at `pos' (let [[beg end] (split-at pos word) letters (map char (range (int \a) (inc (int \z] (map #(apply str (concat beg [%] end)) letters))) (defn all-possibilities [word] (for [n (range (inc (count word))) pos (possibilities word n)] pos)) ;; Since all-possibilities produces a lazy seq we don't need short circuiting anyway... (some #(binary-search word) (all-possibilities hello)) Mark and Jim, Thanks for your responses. You both make an excellent point about functional code not often needing explicit loops (and even being a sign of design problems). My example is decidedly non-functional (I don't really like that term...My code works--it does function! :-) ). It was kind of a first cut in a more imperative style because I thought it might be more efficient destructively modifying a char array rather than copying lots of substrings. I intended to attempt a more functional version next. I was more curious about the general case, but you guys may be right that nested loops just aren't needed. Your example looks useful, Mark. In fact, for the real program I do want to collect all possible suggestions rather than terminating with the first one. So I'll be dealing with sequences anyway. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Advanced Practical Recursion in Lisp 1.0
[future] (m (fn [arg] ((future future) arg (fn [future] (m (fn [arg] ((future future) arg )) (fn [rec] (fn [l] (if (empty? l) 0 (inc (rec (rest l ))) '(a b c d e)) = 5 And 'reverse': (((fn [m] ((fn [future] (m (fn [arg] ((future future) arg (fn [future] (m (fn [arg] ((future future) arg )) (fn [rec] (fn [l] (cond (empty? l) '() (empty? (rest l)) (list (first l)) :else (cons (first (rec (rest l))) (rec (cons (first l) (rec (rest (rec (rest l ))) '(a b c d e)) = (e d c b a) Breathtaking in its elegance! I'm going to move forward with the negotiations, but I need to know if you, the Clojure community, are on board here. Ultimately the decision is going to come down to whether or not you find the APRiL 1.0 technology useful. Try it out and let me know your opinions. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Trying to get a list of random numbers using repeat
On Mar 23, 2009, at 10:36 PM, Paul Drummond wrote: 2009/3/24 Joshua Fox joshuat...@gmail.com: Why presumably with side effects? Otherwise you would use repeat. A pure function returns the same value every time, so there is no reason to call it repeatedly. Yup, that makes sense. Random numbers are side-effecting (is that the right term?) and I was trying to think about the (simple) problem in a pure functional way which was getting my simple brain all confused! It's not obvious what side effect is occurring by calling rand-int, but in fact the state of the pseudorandom generator is affected by each call. This is from java.util.Random. Everybody calls next() sooner or later, and it calls the compareAndSet() method: * This is a linear congruential pseudorandom number generator, as * defined by D. H. Lehmer and described by Donald E. Knuth in iThe * Art of Computer Programming,/i Volume 2: iSeminumerical * Algorithms/i, section 3.2.1. protected int next(int bits) { long oldseed, nextseed; AtomicLong seed = this.seed; do { oldseed = seed.get(); nextseed = (oldseed * multiplier + addend) mask; } while (!seed.compareAndSet(oldseed, nextseed)); return (int)(nextseed (48 - bits)); } As Joshua pointed out, whenever a function returns different values given the same args that's a good sign that a side effect has occurred--some state has obviously changed. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Information Hiding
On Mar 22, 2009, at 10:27 PM, Mark Engelberg wrote: 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? One simple (simplistic?) way to guarantee privacy is through closures: (defn make-person [first-name last-name age sex] (let [age (ref age)] {:first-name (fn [] first-name) :last-name (fn [] last-name) :sex (fn [] sex) :age (fn [] @age) :set-age (fn [new-age] (dosync (ref-set age new-age)))})) person= (def me (make-person David Sletten 39 male)) #'person/me person= ((me :first-name)) David person= ((me :last-name)) Sletten person= ((me :age)) 39 person= ((me :set-age) 40) 40 person= ((me :age)) 40 There's no way to manipulate the age ref except through the :set-age function. This may not scale though if every 'object' carries around its own set of all the methods. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Month/Day names
Is there a simpler way to do this? (defn get-months [] (drop-last (.getMonths (java.text.DateFormatSymbols. (defn get-weekdays [] (drop 1 (.getWeekdays (java.text.DateFormatSymbols. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Mapping a function over a map's values
On Mar 23, 2009, at 5:24 AM, Jeff Valk wrote: On Mon, 23 Mar 2009 at 03:29, Mark Engelberg wrote: But it traverses m twice, which is likely to be less efficient. I wondered about this too, and actually no. I think Mark was referring to the call to 'keys'. But apparently Clojure doesn't need to traverse the map to generate the keys? Zipmap is efficient. It constructs its return map in a single loop from two lazy seqs. Not sure what you mean here. It will produce a map from any 2 seqs. And it does not generate it lazily--it uses loop. Don't try this at home: (zipmap (map str (iterate inc 1)) (iterate inc 1)) Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Calling `str' on a LazySeq
On Mar 21, 2009, at 1:44 PM, Mark Triggs wrote: user= (str (filter even? (range 1 10))) clojure.lang.lazy...@f1005 Previously this would readably print the contents of the seq and some of my code was relying on this. Obviously it's not difficult to call `prn-str' myself, but I just wondered if this change was made consciously. According to the documentation for 'str': With one arg x, returns x.toString(). So it looks like toString() on a sequence used to return its contents and now doesn't. However, rather than relying on this behavior what you probably should be doing is using 'apply': (apply str (filter even? (range 1 10))) = 2468 If you want commas between those elements, use 'interpose': (apply str (interpose , (filter even? (range 1 10 = 2, 4, 6, 8 Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Calling `str' on a LazySeq
On Mar 21, 2009, at 11:30 PM, Mark Triggs wrote: Yep, that's fine. In my case I was actually relying on the fact that `str' was effectively doing a `prn-str' because I would later read it back using `read-string' elsewhere. Calling `prn-str' explicitly isn't a problem--I just thought I'd mention that the semantics have now changed a little. Sorry Mark. I guess I misunderstood what 'prn-str' does. I thought it was for I/O. I missed the print TO string part. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: 08 and 09 are invalid numbers, but 01 through 07 are fine?
On Mar 15, 2009, at 4:53 PM, Aaron Brooks wrote: Rather than going to the horrible effort /irony of looking up to see if Clojure had support for binary notation, I had a Clojure prompt so I just tried it and got semi-surprising results: user= #b010001 java.lang.Exception: No dispatch macro for: b 4097 I'm not surprised that Clojure complains of not knowing what manner of macro #b is but I was impressed (?) that it still yielded the correct value. Somewhere, deep in Clojure's little heart, it wants to do other bases. Umm, that's not really the correct value. Clojure gave you octal 010001 - 4097 not binary 010001 - 17 Sorry, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: 08 and 09 are invalid numbers, but 01 through 07 are fine?
On Mar 13, 2009, at 3:07 AM, Michael Wood wrote: This is pretty standard behaviour. On the other hand, it's not universal. sbcl: * 07 7 * 08 8 Common Lisp uses a separate syntax for binary/octal/hex literals. Legal: #b1011, #o377, #xDEADBEEF, #36rZZZ (Base 36 anyone?) Illegal: #b2, #o8, #xQUICKSAND (Of course, #36rCLOJURE = 27432414842 :-) ) Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Two quick questions on functions...
On Mar 9, 2009, at 11:11 PM, Rich wrote: 1) You must define a method before you call it from another function. Stylistically, I prefer to define helper functions after the main function, but that seems to cause errors. If I move them in front of the main function, the errors go away. I don't know if there's some way to declare the methods before you define them (like C header files). Don't know about this one. It's been bugging me too. 2) To have two or more functions with the same name and a different arity, you must define them in a single (defn...). Correct. For example, the following code: (defn good ([a] (println (str argument: a))) ([a, b] (println (str arguments: a , b (defn bad [a] (str argument: a)) (defn bad [a b] (str arguments: a , b)) (good foo) (good foo bar) (bad foo) (bad foo bar) Generates the following output: argument: foo arguments: foo, bar Exception in thread main java.lang.IllegalArgumentException: Wrong number of args passed to: core$bad (SandBox.clj:0) This crops up when I have a function that was created using a function- building macro, and I wanted to define a wrapper with the same name that allowed me to enter the arguments in a simpler manner. Also, it just feels odd. You don't get an error when defining the same- named function--but suddenly neither version works. That's a pretty serious side-effect. So maybe this is just a bug? What happens if you flip you 2 tests of bad. (I'll bet it's exactly what you expect to happen.) Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: letfn - mutually recursive local functions
On Feb 28, 2009, at 2:38 PM, Rich Hickey wrote: I've added letfn, which lets you define mutually recursive local functions a la CL's labels. (defn ring [n] (letfn [(a [n] (if (zero? n) n (b (dec n (b [n] (if (zero? n) n (c (dec n (c [n] (if (zero? n) n (a (dec n] (c n))) (ring 1000) Note this is still subject to stack limits, i.e. no TCO, so please don't report your StackOverflowErrors. Useful for bounded data only. Do you advocate usage of 'letfn' and 'let' similar to the distinction between LABELS and FLET in CL? In other words, FLET implies non- recursive local function definition whereas LABELS suggests (mutually) recursive function(s). So, (letfn [(f [x] (+ x 2))] (f 8)) ; LABELS should ideally be: (let [f (fn [x] (+ x 2))] (f 8)) ; FLET Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
List comprehension examples for Wikibook
I translated some examples from the book The Haskell Road (http:// homepages.cwi.nl/~jve/HR/): (defn naturals [] (iterate inc 0)) (def evens1 (for [n (naturals) :when (even? n)] n)) (def odds1 (for [n (naturals) :when (odd? n)] n)) (def evens2 (for [n (naturals)] (* 2 n))) (def small-squares1 (for [n (range 0 1000)] (* n n))) (def small-squares2 (for [n (naturals) :when ( n 1000)] (* n n))) ; Maybe should use :while instead? Are these appropriate for inclusion on the Wikibook API page (http:// en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples) since they are derived from a copyrighted book? Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Problems with read-line
While using the code distributed with Stu Halloway's Programming Clojure book I get the following exception from (read-line): java.lang.ClassCastException: clojure.lang.LineNumberingPushbackReader (NO_SOURCE_FILE:0) So I downloaded the latest trunk from SVN, and (read-line) works fine. However, as I tried to run Stu's translation of Peter Seibel's PCL ch. 3 (http://blog.thinkrelevance.com/2008/9/16/pcl-clojure- chapter-3), I got this exception: java.lang.Exception: Unable to resolve symbol: lazy-seq in this context (duck_streams.clj:175) At first I thought this was a problem with my clojure-contrib. But I realized I needed the lazy branch of Clojure from SVN. I downloaded that, and the problem with lazy-seq goes away. But now (read-line) is broken again... Here's read-line from trunk: (defn read-line Reads the next line from stream that is the current value of *in* . [] (. *in* (readLine))) And the lazy branch: (defn read-line Reads the next line from stream that is the current value of *in* . [] (. #^java.io.BufferedReader *in* (readLine))) Apparently *in* is a LineNumberingPushbackReader: public class LineNumberingPushbackReader extends PushbackReader{ Can't be cast to BufferedReader... What's the policy for fixing something like this? Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Help please: or function
On Mar 9, 2009, at 5:48 AM, timc wrote: (re-seq #([a-zA-Z_0-9]+)=([^ ]+) arg))] Two small suggestions--it's easier, and more legible to use \S to match non-whitespace characters: (re-seq #([a-zA-Z_0-9]+)=(\S+) arg) And you've basically defined the word character class \w verbatim in your example: (re-seq #(\w+)=(\S+) Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Problems with read-line
On Mar 9, 2009, at 8:41 AM, Jason Wolfe wrote: I think this was discussed here: http://groups.google.com/group/clojure/browse_frm/thread/ 48f1fb08b3052083/85f858df39daca2a? hl=enlnk=gstq=linenumberingpushbackreader#85f858df39daca2a I'm not sure what the resolution was, if any. -Jason Sorry. I missed that. Thanks for the link. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Clojure Cookbook
Has anyone done any work towards assembling a cookbook of Clojure recipes along the lines of the Perl/Ruby Cookbooks? Even something less formal such as the Common Lisp Cookbook would be useful (http:// cl-cookbook.sourceforge.net/index.html). It would be good to have something like this in place to support the increased interest in Clojure that Stu Halloway's book will generate. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Capitalize string
Is there a function to capitalize the first letter of a string or a better way than this idiotic code? (apply str (map #(if (zero? %2) (Character/toUpperCase %1) %1) clojuriffic (iterate inc 0))) Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Capitalize string
On Mar 8, 2009, at 2:45 AM, Joshua Fox wrote: How about this? user= (defn upper-first [s] (apply str (Character/toUpperCase (first s)) (rest s))) #'user/upper-first user= (upper-first a) A That certainly qualifies as less idiotic. :) Mahalo, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
filter-split
I'm reading the Sequences chapter of Programming Clojure, and Stu points out that split-with combines the semantics of take-while and drop-while. But is there a function that does something similar with filter? Namely, rather than simply filtering the elements of a collection that satisfy a predicate I also want to capture those that don't. Something like this: (defn filter-split [pred coll] (loop [trues '() falses '() coll coll] (cond (empty? coll) (vector (reverse trues) (reverse falses)) (pred (first coll)) (recur (cons (first coll) trues) falses (rest coll)) :else (recur trues (cons (first coll) falses) (rest coll) (filter-split #{\a\e\i\o\u} is this not pung?) = [(\i \i \o \u) (\s \space \t \h \s \space \n \t \space \p \n \g \?)] (filter-split even? (range 10)) = [(0 2 4 6 8) (1 3 5 7 9)] Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: filter-split
On Mar 7, 2009, at 7:17 PM, Adrian Cuthbertson wrote: That's the beauty of this language - there are many ways to skin the cat! Hmmm...I'm not sure what I'll do with a skinless cat. :) Here's a version using reduce... (defn filt-split [pred col] (reduce (fn [[a b] x] (if (pred x) [(conj a x) b] [a (conj b x)])) [[] []] col)) (filt-split even? [1 2 3 4 5 6 7 8]) [[2 4 6 8] [1 3 5 7]] I like that a lot. As long as the repeated creation of the ephemeral vectors isn't too expensive. But when you look at separate in clojure.contrib.seq-utils its simple and elegant; (defn separate [f s] [(filter f s) (filter (complement f) s)]) This is exactly what I'm trying to avoid. I don't want to traverse the collection twice. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: filter-split
On Mar 7, 2009, at 6:44 PM, e wrote: check the discussion with the subject, time lies, even with doall. We came up with something like the following, but some name change change tweaks were suggested. This thing takes a pred and a collection and returns a list of two collections -- one that passes the pred, and one that fails. (defn filt-rem [pred coll] (loop [l1 () l2 () [f r] coll] (if f (if (pred f) (recur (conj l1 f) l2 r) (recur l1 (conj l2 f) r)) (list l1 l2 This is almost identical to what I posted. However, is this the intended behavior? (filt-rem identity '(true nil false 8)) = ((true) ()) (filt-split identity '(true nil false 8)) = [[true 8] [nil false]] (filt-rem even? (range 10)) = ((8 6 4 2 0) (9 7 5 3 1)) (filter-split even? (range 10)) = [(0 2 4 6 8) (1 3 5 7 9)] (defn filter-split [pred coll] (loop [trues '() falses '() coll coll] (cond (empty? coll) (vector (reverse trues) (reverse falses)) (pred (first coll)) (recur (cons (first coll) trues) falses (rest coll)) :else (recur trues (cons (first coll) falses) (rest coll) Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: float vs fraction (just playing around)
is different from 6 * 0.1: (rationalize 0.6) = 3/5 (rationalize (* 6 0.1)) = 6001/1 (rationalize (+ 0.1 0.1 0.1 0.1 0.1 0.1)) = 3/5 Even worse is the potential for infinite loops: (defn trap [x] (prn x) (cond (= x 1) How nice. 10 * 0.1 = 1 ( x 1) Whoops. Good thing I had an escape hatch. :else (trap (+ x 0.1 (trap 0.1) 0.1 0.2 0.30004 0.4 0.5 0.6 0.7 0.7999 0.8999 0. 1.0999 Whoops. Good thing I had an escape hatch. If you've read this far you'll want to take a look at the links Mark provided earlier. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
let vs. let*
I see a lot of let* in macro expansions, but Clojure's let already behaves like Common Lisp's LET*. Is let* archaic? It seems to behave the same as let in terms of sequential binding. (let [x 8 y (inc x)] (list x y)) = (8 9) (let* [x 8 y (inc x)] (list x y)) = (8 9) Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Roman Numerals
On Mar 4, 2009, at 8:29 PM, Tom Faulhaber wrote: BTW, cl-format (my Common Lisp format function for Clojure), supports the ~...@r directive for converting Arabic to Roman (but nothing to go the other way around. I didn't spend too much time thinking about stylistic issues when I wrote it, but if you're interested you can compare. It's at http://github.com/tomfaulhaber/cl-format.) Thanks for the link Tom. I'd read mention of your work somewhere but hadn't had a chance to look at it yet. That's extremely cool that you've implemented FORMAT! Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Roman Numerals
) num- list)) (arabic-to-roman n tail )) You might consider using 'reduce' instead of recursion here. Alternatively, it's interesting to note that because of the ease with which you're destructuring arabic-values, it would be no more difficult if you had a single list (or vector) of alternating numbers and strings rather than nesting them. I don't think reduce would actually work here. As you see, the test (= n arabic) determines whether we continue working with the original num-list or proceed to the tail. I'm not sure of how to get that behavior with reduce. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
When in Rome
On Mar 4, 2009, at 3:56 AM, Rich Hickey wrote: Conversely, when says side effect. This is clear for 2 reasons. First, there is no else clause, so when doesn't really work as an expression. Furthermore, the forms in the when body are evaluated in an implicit do. Since only the final value is returned, any of the earlier expressions in the when body are useful only for their side effects. This is not the convention in Clojure for a couple of reasons. First, there are far fewer side effects. 'when' does not say side effects, although as you point out, it does support them. But then, so do function bodies and they don't inherently say side-effects. Rich, You're obviously the wrong guy to argue with regarding what the right way to do stuff in Clojure is, so I'll take your comment to heart. At the same time though, I still don't quite get why when by definition evaluates its subexpressions in an implicit do (as CL's WHEN provides an implicit PROGN). There is no point in evaluating multiple expressions unless they produce side effects: printing to the screen, writing to disk, etc... Since this is the defined semantics of when it seems this should be a flag that governs how when is used. I understand that there is far less mutability in Clojure, but that's not to say there aren't side effects. I agree 'if' should always have 3 subexpressions, all the more reason to use 'when' when the second is going to be nil. Idiomatic Clojure code is full of expressions like: (when there-is-stuff (expr stuff)) Which I read as when there is stuff, some function of it, else nothing. There's nothing inherently side-effecting about it. Again here I'm not sure what you mean by else nothing. If you're using when as an expression, it has to produce a value even when the test fails. Why not just use if and make that value explicit? It would certainly be a waste of 'when' in Clojure to reserve it for side effects, since so much code contains none. It was 50 years ago today that John McCarthy's description of Lisp was published in an AI Memo (AIM-8). Here's to McCarthy and Lisp. And here's to you, RIch, for carrying on the flame. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Roman Numerals
Here's a little toy to practice my basic Clojure skills. I didn't see any similar topic in the archives, so here we go... This code performs conversions between Roman and Arabic numerals. Roman numerals are represented as strings and Arabic numerals are just integers. Arabic numerals in the range of 1 and 3999 inclusive are allowed. Conventionally, 3999 is the upper limit since the Roman numeral for 5000 (a V with a bar over it) cannot be represented in ASCII (although it exists in Unicode). The function roman-to-arabic-aux correctly converts any valid Roman numeral. This can be exhaustively tested by comparing the Roman numeral output of Common Lisp's FORMAT function for example (e.g., (format nil ~...@r n)). The trick, however, is weeding out bogus strings representing invalid Roman numerals such as IVI, IXV, etc... For this purpose the function roman? uses a regular expression I cribbed from Perl's CPAN module Roman.pm (http://search.cpan.org/ ~chorny/Roman-1.23/lib/Roman.pm). arabic-to-roman performs the obvious conversion in the other direction. Incidentally, the cond form in roman-to-arabic-aux seems to me harder to read in Clojure than it would be in CL with its additional set of grouping parentheses. When you can't fit both the predicate and the consequent expression on the same line it gets confusing. I'd appreciate any feedback regarding my Clojure style. Any more natural ways to do things? Aloha, David Sletten (def roman-values-map {\I 1 \V 5 \X 10 \L 50 \C 100 \D 500 \M 1000}) (defn value [roman] (get roman-values-map (Character/toUpperCase roman))) (defn roman? [roman-string] (and (not (empty? roman-string)) (re-matches #(?:M{0,3})(?:D?C{0,3}|C[DM])(?:L?X{0,3}|X[LC])(?:V?I{0,3}|I [VX])$ roman-string))) (defn roman-to-arabic-aux [roman-string] (cond (empty? roman-string) 0 (empty? (rest roman-string)) (value (first roman-string)) ( (value (first roman-string)) (value (second roman-string))) (- (roman-to-arabic-aux (rest roman-string)) (value (first roman-string))) :else (+ (value (first roman-string)) (roman-to-arabic-aux (rest roman-string) (defn roman-to-arabic [roman-string] (if (roman? roman-string) (roman-to-arabic-aux roman-string) (format '%s' is not a valid Roman numeral. roman-string))) (def arabic-values '((1000 M) (900 CM) (500 D) (400 CD) (100 C) (90 XC) (50 L) (40 XL) (10 X) (9 IX) (5 V) (4 IV) (1 I))) (defn arabic-to-roman ([n] (if (= 1 n 3999) (apply str (arabic-to-roman n arabic-values)) (format %d cannot be converted. n))) ([n num-list] (cond (empty? num-list) '() (zero? n) '() :else (let [[[arabic roman] tail] num-list] (if (= n arabic) (cons roman (arabic-to-roman (- n arabic) num-list)) (arabic-to-roman n tail )) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
member function
Does Clojure have an analog of Lisp's MEMBER function? (member 'a '(c a f e b a b e)) = (A F E B A B E) (I'm more interested in it's use as a predicate rather than the fact that it returns a sublist when true.) find and contains? are listed under the Maps section of the data structures page (http://clojure.org/data_structures#toc17) so no good with lists. I can't think of any other synonyms. The documentation for some suggests this: (some (fn [elt] (= elt 'a)) '(a b c)) = true That's pretty verbose, and even the shortcut is kinda long: (some #(= % 'a) '(a b c)) = true Although this alternative is alright: (some #{'a} '(a b c)) = a Is that the Clojure version of MEMBER? Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: member function
On Mar 2, 2009, at 3:39 AM, Meikel Brandmeyer wrote: Does Clojure have an analog of Lisp's MEMBER function? (member 'a '(c a f e b a b e)) = (A F E B A B E) I don't know the member function of CL, but I interpret your example, that it cuts away the head of the list until the first occurence of the given thing. MEMBER is a fancy predicate that tests whether or not an item is an element of a given list. I say fancy because rather than simply returning true when the item is present it returns the tail of the list starting with the item. It returns nil otherwise. I don't care about this fancy value. I just want to know whether or not the item is in the list without too much verbosity. I think (some #{ITEM} LIST) is probably the way to do it. You can do that in Clojure with drop-while: (drop-while #(not= % :a) (list :c :a :f :e :b :a :b :e)) = (:a :f :e :b :a :b :e) Thanks for your example anyway. Mahalo nui loa (vielen dank), David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: member function
On Mar 2, 2009, at 4:01 AM, Mark Volkmann wrote: It's verbose in order to discourage its use since its a linear search. See the discussion about the contains? function at http://www.ociweb.com/mark/clojure/article.html#Lists and http://www.ociweb.com/mark/clojure/article.html#Sets. Ahh. Nice explanation. Thanks again Mark for the article. sheepish As you can see I haven't finished reading the whole thing yet. /sheepish Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Clojure documentation problems
On Feb 19, 2009, at 2:52 AM, David Sletten wrote: The macros page at clojure.org (http://clojure.org/macros) has links to several points in the API page. The link to the if-not macro appears to be broken (http://clojure.org/api#if-not). There is no such entry in the API. The same holds true for the condp macro (http://clojure.org/api#condp). Their documentation is available via doc at the REPL though. In addition, the rationalize function was missing last week, but it has an entry now. So never mind that... Whoops...it's rational? that was missing from the API page and still is. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Flatten a list
On Feb 24, 2009, at 5:42 PM, Timothy Pratley wrote: user= (remove nil? '(:a nil nil :b :a)) (:a :b :a) C'mon! Doesn't anybody do things the old-fashioned way anymore? (defn kill-nil ([l] (kill-nil l '())) ([l result] (cond (nil? l) (reverse result) (nil? (first l)) (recur (rest l) result) true (recur (rest l) (cons (first l) result ) You young whipper snappers! Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Flatten a list
On Feb 24, 2009, at 6:07 PM, David Sletten wrote: (defn kill-nil ([l] (kill-nil l '())) ([l result] (cond (nil? l) (reverse result) (nil? (first l)) (recur (rest l) result) true (recur (rest l) (cons (first l) result ) I forgot to ask... In Lisp, rather than repeatedly testing for an optional argument like this: (defun kill-nil (l optional (result '())) (cond ((endp l) (nreverse result)) ((null (first l)) (kill-nil (rest l) result)) (t (kill-nil (rest l) (cons (first l) result ) I would preserve the interface to the user (i.e., single arg) but eliminate the decisions regarding the optional arg from the recursive calls: (defun kill-nil (l) (labels ((kill-nil-aux (l result) (cond ((endp l) (nreverse result)) ((null (first l)) (kill-nil-aux (rest l) result)) (t (kill-nil-aux (rest l) (cons (first l) result )) (kill-nil-aux l '( In the Clojure version above there doesn't seem to be any penalty since the recur only occurs after the correct arity has been selected. Is this correct? How about a more traditional recursion? (defn kill-nil ([l] (kill-nil l '())) ([l result] (cond (nil? l) (reverse result) (nil? (first l)) (recur (rest l) result) true (kill-nil (rest l) (cons (first l) result ) Is there a penalty deciding which arity to use on each call? Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Clojure documentation problems
The macros page at clojure.org (http://clojure.org/macros) has links to several points in the API page. The link to the if-not macro appears to be broken (http://clojure.org/api#if-not). There is no such entry in the API. The same holds true for the condp macro (http://clojure.org/api#condp). Their documentation is available via doc at the REPL though. In addition, the rationalize function was missing last week, but it has an entry now. So never mind that... Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: terminology question re: binding
On Feb 16, 2009, at 10:34 AM, Stuart Halloway wrote: David Sletten sent me this erratum: At the beginning of section 2.4 we have The symbol user/foo refers to a var which is bound to the value 10. Under the next subsection Bindings we have Vars are bound to names, but there are other kinds of bindings as well. The Common Lisp standard defines a binding as an association between a name and that which the name denotes. This is the second sense used in the book. The first sense of a binding between a var and its value is inconsistent. Should I be using two different terms, or is the notion of binding overloaded? Stuart, I'm sorry but my comments appear to have raised more of a fuss than I intended. I think I need to clarify two issues: 1. I was probably not sufficiently clear in my intent. I did not mean so much to point out that you were wrong as to simply highlight the inconsistent use of the words binding and bound. Your term overloaded is more neutral, and therefore a better choice than mine. In a language such as Common Lisp where every variable is (effectively) a reference variable, we have three concepts: names, variables (references), and values (referents). These three things have two connections. In an orthodox (perhaps pedantic) sense a name is bound to a variable, and the variable has a value. Names can be bound to different variables and variables can be assigned new values: (defvar *x* 8) ; Bind *x* to special variable and assign value. (setf *x* 9) ; Assign new value to variable. Binding hasn't changed. (let ((x 12)) ; Bind x to variable, assign value. (let ((x pung)) ; Bind x to different variable - different binding. (setf x foo) ; Same (2nd) variable, new value. ...) ; 1st binding visible again outside of inner LET ...) ; No more binding for x out here On a side note, when we talk of scope we shouldn't talk about an identifier's scope or a variable's scope. Scope is an issue involving both names and variables: bindings have scope. The definitions in the CLHS glossary all reflect this interpretation. However, as I was looking through my notes it became clear that your overloaded use is hardly idiosyncratic. For example, the CLHS entry for LET states: let and let* create new variable bindings and execute a series of forms that use these bindings. Yet it explicitly states later that: ...Then all of the variables varj are bound to the corresponding values. This seems to me inconsistent with the glossary definitions, but such usage occurs throughout the Standard. I think that the strict usage is consistent with Clojure's binding macro, which binds a name to a new variable. The let special form does a similar thing, but the situation is a little different than in CL since you can't assign a new value to a variable established by a Clojure let binding. Consequently, it seems that we can more safely blur the distinctions among name/variable/value here. A name is associated with a given value for the lifetime of the binding. As another example, the language Oz has the notion of identifiers, which may be either bound or free, and variables, which may either be bound or unbound. Oz variables are like Clojure lexicals--once assigned their values cannot change. So an unbound variable is simply a variable that has not been assigned a value yet. Assignment binds a value to a variable. Likewise, a free identifier is a name that doesn't refer to anything yet. Once bound, an identifier names a variable. So to wrap this all up, if you are satisfied with your discussion in the book--and you seem justified in that--then I'll just shut up about binding. 2. My erratum report and comments above should not be viewed as though I advocate Clojure being evaluated through the lens of Common Lisp. I have a few years experience studying CL, so naturally that affects my perception of Clojure. However, in fairness the language should be judged on its own merits, and I am far too new to Clojure to make any such judgment yet. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: terminology question re: binding
On Feb 17, 2009, at 5:10 AM, Chouser wrote: I think that the strict usage is consistent with Clojure's binding macro, which binds a name to a new variable. Are you sure? It seems to me the most natural mapping from the CL concepts to Clojure is: CL name - Clojure symbol, name, or perhaps namespace entry CL variable - Clojure Var (or perhaps ref, atom, etc.) CL value or referent - Clojure value. Clojure's 'binding' macro does not change the connection from name to Var, but the one from Var to (effective, thread-local) value. I see that you are correct. Observe the following behavior: ; Common Lisp. We have no way to get ahold of the variable (reference) to which a ; name is bound. Dereferencing is automatic. However, with a dynamic ; variable we can access the symbol data structure associated with the name *PUNG*. (defvar *pung* 8) (defvar *foo* *pung*) ; Referent of *PUNG* assigned (defvar *bar* '*pung*) ; Note the quote here--assigning symbol *PUNG* ; Establish a new binding for *PUNG*. *BAR* changed as well. (let ((*pung* 9)) (list *pung* *foo* (symbol-value *bar*))) = (9 8 9) ; Clojure. We can access the reference itself via var. (def pung 8) (def foo pung) ; i.e., (deref (var pung)) or @#'pung (def bar (var pung)) ; binding changes value of pung--apparently not the variable itself, thus ; bar also reflects changed value. (binding [pung 9] (list pung foo @bar)) = (9 8 9) ; By contrast let binds pung to a new variable, which shadows the global. ; bar still refers to global pung (let [pung 9] (list pung foo @bar)) = (9 8 8) Do I have it right now? Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: is mod correct?
On Feb 10, 2009, at 6:37 PM, Timothy Pratley wrote: I would have expected the mult to be a performance hit, but my overly simple tests show it performing better: user= (time (dotimes [i 100] (zero? (* 5 11 Elapsed time: 183.358706 msecs user= (time (dotimes [i 100] (or ( 5 0 11) ( 11 0 5 Elapsed time: 682.586025 msecs In practice it doesn't seem to make much difference overall: user= (time (dotimes [i 100] (map #(mod2 % 3) (range -9 9)) )) Elapsed time: 966.868765 msecs user= (time (dotimes [i 100] (map #(mod42 % 3) (range -9 9)) )) Elapsed time: 938.675334 msecs But the multiply seems to have the edge in both expression and speed. The real hit would come with bignums, no? But as far as the routine use of MOD goes we're probably talking about fixnums 99% of the time. Aloha, David Sletten --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---