Re: proposal for core arithmatic functions
On 13 Mar 2010, at 03:32, Jonathan Shore wrote: Could + and other operators be changed to a macro mapping rather than the current defn, mapping the argument list to a binary expression tree (+ (+ (+ ... instead of the list style application (I'm guessing yes, not being familiar with CL-style macros). This would not be a good idea for the arithmetic functions in clojure.core, as macros come with their own restrictions. For example, if + were a macro, you couldn't pass it as an argument to map, reduce, or apply. All of these occur very frequently. I don't really share your worries at this time because the kind of performance problem you describe can always be fixed in a later optimized implementation. Clojure is still a very young and evolving language, so that level of optimization cannot be expected in my opinion. What is nice about Lisp is that everything that Clojure does, you can do yourself. If you are not happy with how + works, write your own. You can make it a function that is more efficient in general, or more efficient just for your use cases, or you can make it a macro. All you need to change in your code to use your own version is the ns form at the beginning which specifies which symbols to take from where. For an example, see http://code.google.com/p/clj-nstools/source/browse/src/nstools/generic_math.clj That does exactly the opposite of what you want: it replaces arithmetic by a generic and thus slower implementation. But the same approach would work for whatever other implementation you might want. Of course, if you come up with a clearly improved arithmetic without restrictions, it would be nice to propose it for inclusion into Clojure itself. Secondly, if one has code like: (let [ x (int a) y (int b)] (+ (* x 2) (* y 3) (* x y 5)) (* x 2) -> a function of (int, Object), as the literal 2 is not assumed to be a primitive type.This instead needs to be mapped to: (let [ x (int a) y (int b)] (+ (+ (* x (int 2)) (* y (int 3)) (* (* x y) (int 5 I don't know if type hints can be interrogated or known at the time of macro evaluation (I'm guessing not), but if so, would like to see that in such a macro. Yes, a macro has access to everything. It is perfectly possible, and even not very difficult, to write a macro that does the transformation you describe. The tricky part is knowing when it is a good idea to apply it - but if you leave that decision to the programmer using it, the problem becomes a quite straightforward one to solve. Automatically decorating literals that are used in the context of arithmetic with a primitive would make clojure a lot more usable for performance-concerned arithmetic. Perhaps. I find it very hard to predict what can be gained by a specific optimization, since it's so hard to predict what the JIT compiler will take care of automatically. I think I saw mention that #^int (and other primitive types) will be supported at some point in argument declarations as well? That has been mentioned on this list, but I don't expect it to happen before the rewrite of the Clojure compiler in Clojure itself. Konrad. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: proposal for core arithmatic functions
Thanks for your thoughtful reply, see below. On Mar 13, 2010, at 3:03 AM, Konrad Hinsen wrote: > On 13 Mar 2010, at 03:32, Jonathan Shore wrote: > >> Could + and other operators be changed to a macro mapping rather than the >> current defn, mapping the argument list to a binary expression tree (+ (+ >> (+ ... instead of the list style application (I'm guessing yes, not being >> familiar with CL-style macros). > > This would not be a good idea for the arithmetic functions in clojure.core, > as macros come with their own restrictions. For example, if + were a macro, > you couldn't pass it as an argument to map, reduce, or apply. All of these > occur very frequently. ic your point. Then really what I am asking for is for the compiler to decompose these into binary operations in a future release. > > I don't really share your worries at this time because the kind of > performance problem you describe can always be fixed in a later optimized > implementation. Perhaps not, but most of my work would have to be done in Java, which for me would be unacceptabe. I'm thinking Clojure is premature for my work at the moment. > Clojure is still a very young and evolving language, so that level of > optimization cannot be expected in my opinion. I recognize that Clojure is a smaller effort. It may well be that users in the clojure community use clojure in situations that are not as performance sensitive.For possible adopters with issues such as mine, clojure competitors are much ahead on the performance angle.I do hope that the compiler rewrite is to put focus on perf. > > Yes, a macro has access to everything. It is perfectly possible, and even not > very difficult, to write a macro that does the transformation you describe. > The tricky part is knowing when it is a good idea to apply it - but if you > leave that decision to the programmer using it, the problem becomes a quite > straightforward one to solve. > >> Automatically decorating literals that are used in the context of arithmetic >> with a primitive would make clojure a lot more usable for >> performance-concerned arithmetic. > > Perhaps. I find it very hard to predict what can be gained by a specific > optimization, since it's so hard to predict what the JIT compiler will take > care of automatically. I could be wrong, but would think that: static public int intCast(Object x){ if(x instanceof Number) return ((Number) x).intValue(); return ((Character) x).charValue(); } the "if" statement is not going to be optimised away by JIT. (This is what gets called on the literals). > >> I think I saw mention that #^int (and other primitive types) will be >> supported at some point in argument declarations as well? > > That has been mentioned on this list, but I don't expect it to happen before > the rewrite of the Clojure compiler in Clojure itself. > > Konrad. > > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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
filter sequence until false result
Hey all! I am trying to filter a sequence until a false value is returned. Is there a control-flow form to do this? ( I know I could write a loop statement to do it) Here are more details of what I am actually trying to do, in case above is not clear. input is the lazy sequence of primes: (use '[clojure.contrib.lazy-seqs :only (primes)]) I would like to filter the lazy sequence of primes for all of the primes less than 2,000,000 If I try: (filter #(while (< % 20)) primes) It gets hung up since filter keeps testing primes, despite the fact that they have grown too large. So, I would like filter to stop at the first false result. -- You 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: filter sequence until false result
You can use either take-while or for to do what you want. (take-while #(< % 20) primes) (for [p primes :while (< p 20)] p) Hope that helps -Patrick -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: filter sequence until false result
On 13 March 2010 15:49, Glen Rubin wrote: > If I try: > > (filter #(while (< % 20)) primes) > > It gets hung up since filter keeps testing primes, despite the fact > that they have grown too large. So, I would like filter to stop at > the first false result. Actually that's not what happens. Execution never leaves the first application of #(while (< % 20)), since it expands (performing macro-expansion and substituting the concrete parameter for the formal %) to (loop [] (when (< 2 20) (recur))) See the docs on while (e.g. through (doc while) at the REPL) and its source (e.g. through (c.c.repl-utils/source while) at the REPL). Sincerely, Michał -- You 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] clj-native 0.8.1
Hello all. I have had some time lately to work on my C FFI for Clojure and I think it's pretty much feature complete now. It has support for functions, callbacks, structures, unions and globals. For structures there is support for different alignments. The library has two main namespaces: clj-native.direct and clj- native.dynamic. The direct namespace uses the "direct mapping" feature of JNA in order to be as efficient and arity and type safe as possible. However, it does not support varargs functions since they require reflection and dynamic translation of the parameters. That's what the dynamic namespace is for: It can map any C function into clojure, even vararg functions like printf but at a higher cost in call time and less safety (it's easy to crash the jvm by sending the wrong type or number of parameters). Access to global variables through the JNA Pointer class is also available in the dynamic namespace. The library is available from github: http://github.com/bagucode/clj-native and clojars: http://clojars.org/clj-native Example usage of the direct namespace can be found here: http://github.com/bagucode/clj-native/blob/master/src/examples/c_lib.clj Please report issues or make requests to my github account or by mail. Enjoy! /Markus -- You 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
Achieving high performance, mutable primitives?
Hi, I just ran these two microbenchmarks, where I attempted to measure the overhead in Clojure's loop-recur form as compared to just mutating an array. ;;loop-recur (5300 msecs) (time (dotimes [n 5000] (loop [accum (int 0) i (int 0)] (if (< i 5) (recur (+ accum i) (inc i)) accum ;;int-array (2910 msecs) (time (dotimes [n 5000] (let [a (int-array 1)] (dotimes [i 5] (aset a 0 (+ i (aget a 0))) Because of these results, I think it's worthwhile to be able to access a mutable location directly from within Clojure, such as a mutable primitive. Right now, I'm making do with a set of macros for creating and manipulating 1 element arrays. But this incurs a cost of creating those arrays when I really just want a mutable primitive. What is everyone's opinion on this? Are mutable primitives still seen as unnecessary? Or are they seen as necessary but not an immediate concern? -Patrick -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Achieving high performance, mutable primitives?
On Sat, Mar 13, 2010 at 1:59 PM, CuppoJava wrote: > Hi, > I just ran these two microbenchmarks, where I attempted to measure the > overhead in Clojure's loop-recur form as compared to just mutating an > array. > > ;;loop-recur (5300 msecs) > (time > (dotimes [n 5000] >(loop [accum (int 0) i (int 0)] > (if (< i 5) >(recur (+ accum i) (inc i)) >accum > ; ~720ms (time (dotimes [n 5000] (loop [accum (int 0) i (int 0)] (if (< i (int 5)) (recur (+ accum i) (inc i)) accum You have to remember that even number literals need to be type-hinted. David -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Achieving high performance, mutable primitives?
BTW your "5" literal is boxed, which is causing slowness: user> (time (dotimes [n 5000] (loop [accum (int 0) i (int 0)] (if (< i (int 5)) (recur (+ accum i) (inc i)) accum "Elapsed time: 861.027 msecs" On Mar 13, 10:59 am, CuppoJava wrote: > Hi, > I just ran these two microbenchmarks, where I attempted to measure the > overhead in Clojure's loop-recur form as compared to just mutating an > array. > > ;;loop-recur (5300 msecs) > (time > (dotimes [n 5000] > (loop [accum (int 0) i (int 0)] > (if (< i 5) > (recur (+ accum i) (inc i)) > accum > > ;;int-array (2910 msecs) > (time > (dotimes [n 5000] > (let [a (int-array 1)] > (dotimes [i 5] > (aset a 0 (+ i (aget a 0))) > > Because of these results, I think it's worthwhile to be able to access > a mutable location directly from within Clojure, such as a mutable > primitive. > > Right now, I'm making do with a set of macros for creating and > manipulating 1 element arrays. But this incurs a cost of creating > those arrays when I really just want a mutable primitive. > > What is everyone's opinion on this? Are mutable primitives still seen > as unnecessary? Or are they seen as necessary but not an immediate > concern? > > -Patrick -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: binary representation + operators
On 12 March 2010 23:26, Scott wrote: > How do I write a function 'bit' that converts an integer to binary > representation: > > (bit 0) -> 2r0 > (bit 1) -> 2r1 > (bit 2) -> 2r10 > (bit 3) -> 2r11 I understand that you want a way to obtain a string representation of a number in binary. I think you need to dispatch on class: (Integer/toBinaryString (int 5)) ; => "101" (Integer/toBinaryString (Integer. 5)) => "101" (Long/toBinaryString (long 5)) ; => "101" (Long/toBinaryString (Long. (long 5))) ; => "101" (.toString (bigint 5) 2) ; the "2" indicates the radix; => "101" (.toString (BigInteger. "5") 2) ; => "101" As far as I can tell, you can't use the int/long method with bigints or the other way around. If you'd like to add the "2r" in front, just use str: (str "2r" "101") ; => "2r101" > As well, as function 'bit-concat' with the following behavior: > > (bit-concat 2r1 2r00) -> 2r100 > (bit-concat 2r0 2r00) -> 2r000 > (bit-concat 2r011 2r1100) -> 2r000 I'd prefer to have bit-concat operate on actual numbers, not on strings; you can convert the result later. To that end, here's a possible solution (I'm *sure* there must be a better way... but it works): (let [ls (zipmap (map #(loop [n % r 1] (if (zero? n) r (recur (dec n) (* 2 r (range 0 128)) (map inc (range 0 128)))] (defn bit-length [n] (if (zero? n) 0 (condp = (class n) Integer(ls (Integer/highestOneBit n)) Long (ls (Long/highestOneBit n)) BigInteger (.bitLength n) (comment ; this returns true (every? #(== (bit-length %) (.bitLength %)) (map bigint (range 0 1000 (defn bit-concat [n m] (bit-or (bit-shift-left n (bit-length m)) m)) This will work as expected unless you use unboxed ints: user> (bit-shift-left (int 1) 63) -2147483648 user> (bit-shift-left (Integer. 1) 63) 9223372036854775808 user> (bit-shift-left (long 1) 128) 340282366920938463463374607431768211456 user> (bit-shift-left (long 1) 200) 1606938044258990275541962092341162602522202993782792835301376 user> (class (bit-shift-left (long 1) 200)) java.math.BigInteger Sincerely, Michał -- You 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
Good practice for documenting structmaps?
Is there a good practice for documenting the structure basis object for structmaps? As I'm using more Clojure code on a production, I'm finding it useful to document structmaps, but the only way I can find to do it is using the following pattern to add the doc meta to a var: (def #^{:doc "..."} mystruct (create-struct :name :description)) I'm not sure the actual basis object ( I think clojure.lang.PersistentStructMap$Def) implements IObj to be able to hold its own metadata. I've found some interest in the idea of adding doc-string to defstruct: http://www.mail-archive.com/clojure@googlegroups.com/msg14121.html -- You 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: Something similar to (match) from scheme?
thanx, that's a start. It seems that plt-scheme's match is a bit more powerful, but I think I can manage with this as well. So far the biggest annoyance is the fact that I can match a number or a string, but not a symbol (I can in :when condition, I know...) which is something I can live with. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Something similar to (match) from scheme?
I just found clojure.contrib.types match which maybe fits more with what I'm trying to do... I'll check it out tomorrow, almost 3am here... -- You 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: proposal for core arithmatic functions
On Sat, Mar 13, 2010 at 9:32 AM, Jonathan Shore wrote: > Hi, > > I've been evaluating clojure with a bias around performance (I do a lot of > numerical work). I don't need to the metal, but want to see that > fundamental operations are comparable to java in performance and that > performance can be had not at the expense of conciseness. In particular, > I've noted that arithmetic such as: > > (+ a b c d) > > is not equivalent to: > > (+ (+ (+ a b) c) d) > > in performance, because the former form applies + on a list or array form (I > forget which). This is regardless of whether all of the above values have > primitive type hints. At least this is what I observe in debugging (correct > me if I am wrong). > > Could + and other operators be changed to a macro mapping rather than the > current defn, mapping the argument list to a binary expression tree (+ (+ (+ > ... instead of the list style application (I'm guessing yes, not being > familiar with CL-style macros). Yes. It's a simple matter of changing the current run-time reduce in (defn + ...) to a compile-time reduce: ([x y & more] (reduce (fn [a b] `(+ ~a ~b)) (cons x (cons y more -Per -- You 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: proposal for core arithmatic functions
On Sat, Mar 13, 2010 at 3:03 PM, Konrad Hinsen wrote: > On 13 Mar 2010, at 03:32, Jonathan Shore wrote: > >> Could + and other operators be changed to a macro mapping rather than the >> current defn, mapping the argument list to a binary expression tree (+ (+ >> (+ ... instead of the list style application (I'm guessing yes, not being >> familiar with CL-style macros). > > This would not be a good idea for the arithmetic functions in clojure.core, > as macros come with their own restrictions. For example, if + were a macro, > you couldn't pass it as an argument to map, reduce, or apply. All of these > occur very frequently. I wrote my reply to him before drinking coffee, so I hadn't considered this (obvious) issue. Common Lisp's has compiler macros. These are macros associated with a function which will be called only when calls to the function are resolvable at compile time. While nicer than plain macros (as you can still treat the function as a first-class value at run time) they are still not semantically transparent because of the possibility of var rebinding. -Per -- You 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: proposal for core arithmatic functions
As a mea culpa for my earlier stupidity, here's a proposed solution that is semantically transparent if somewhat inelegantly brute force in its approach: http://gist.github.com/331211 If need be, it could also define entries for :inline and :inline-entries for the auto-generated arity overloads. -Per On Sat, Mar 13, 2010 at 3:23 PM, Per Vognsen wrote: > On Sat, Mar 13, 2010 at 3:03 PM, Konrad Hinsen > wrote: >> On 13 Mar 2010, at 03:32, Jonathan Shore wrote: >> >>> Could + and other operators be changed to a macro mapping rather than the >>> current defn, mapping the argument list to a binary expression tree (+ (+ >>> (+ ... instead of the list style application (I'm guessing yes, not being >>> familiar with CL-style macros). >> >> This would not be a good idea for the arithmetic functions in clojure.core, >> as macros come with their own restrictions. For example, if + were a macro, >> you couldn't pass it as an argument to map, reduce, or apply. All of these >> occur very frequently. > > I wrote my reply to him before drinking coffee, so I hadn't considered > this (obvious) issue. > > Common Lisp's has compiler macros. These are macros associated with a > function which will be called only when calls to the function are > resolvable at compile time. While nicer than plain macros (as you can > still treat the function as a first-class value at run time) they are > still not semantically transparent because of the possibility of var > rebinding. > > -Per > -- You 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
Zip function
Hello, I'm new to Clojure, but in other languages, zip is a workhorse, and I didn't find it, so I (defn zip [& ss] (partition (count ss) (apply interleave ss))) but because I didn't find it, I am suspicious: is there a better way? Marmaduke ps. As a first-poster: thanks to Rich Hickey and Stuart Halloway for the language and the book, respectively. -- You 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
Newbie question: Why does clojure prefer java.lang.Exception?
Greetings everyone! I am currently beginning to learn clojure, and here's one thing that I don't quite understand, that many exceptions thrown by clojure are the most generic java.lang.Exception's (e.g. when a symbol cannot be resolved). Why aren't more specific exception classes used, like clojure.lang.SymbolResolutionException? (Having a more specific exception class seems useful when doing exception handling.) As far as I know, clojure throws exceptions defined in the standard Java library only, like the IllegalStateException when updating refs outside a transaction. So there are no appropriate exception classes for some errors occurred in clojure, which may be the reason it falls back to java.lang.Exception. Is the standard-exception-only thing intentional? If so, would you please tell me the rationale behind such a decision? I have only played with clojure for one day, so there's a huge possibility that I missed or misunderstood something. Please enlighten me. Thanks in advance. :) Regards, Ruochen -- You 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: quote versus backquote
Thank you, this has been very helpfull. The reason I came across this problem is that I never intended to evaluate the symbols in the expression trees. I rather wanted to use them to represent symbolic constants in an abstract expression tree. I am now convinced that using keywords throughout is the better approach. Thanks, Felix On 12 Mrz., 15:01, Konrad Hinsen wrote: > On 12.03.2010, at 10:32, Felix Breuer wrote: > > > I guess I have to rephrase my previous questions to make them more > > clear: Why was this particular behavior chosen? What is the benefit of > > having quote and syntax-quote behaving differently in this regard? > > Quote and syntax-quote serve very different purposes, despite the similar > name an a superficial resemblance in functionality. > > Quote is for writing unevaluated literals. You just want nothing changed in > its argument, which is exactly what it does. > > Syntax-quote is used for writing code templates, mostly inside macro > definitions. In that situation, you want symbols be resolved in namespaces, > just as they would if the form being constructed were used literally in the > same place. To make code templates work correctly across namespaces > (typically a macro is expanded in another namespace than the one it was > defined in), it is thus preferable to have symbols converted to their > namespace-qualified counterparts. > > You might want to look at this blog post, whose topic is an exceptional > situation where syntax-quote is not the most convenient way to write code > templates: > > http://onclojure.com/2010/02/23/generating-deftype-forms-in-macros/ > > > Suppose I wanted to write my own version of = called (myeql a b) such > > that > > > user> (myeql '(v 1) `(v 1)) > > true > > > I would have to walk the expression tree in both expressions and > > replace all unqualified symbols with the respective qualified symbols. > > How would I go about this? Is there an idomatic way to achieve this? > > I don't see why you would ever want to do this, but here is one approach (not > idiomatic): > - use clojure.walk to apply a transformation all over a form > - for each leaf of the tree, check if it is a symbol and if so, convert it to > its namespace-qualified equivalent. > > What is rather strange in my opinion is the fact that there is no utility > function in clojure. core that does the second step, i.e. there is no > function that will map 'x to `x. However, it is not difficult to write such a > function: > > (defn qualified-symbol > [s] > (symbol (str *ns*) (str s))) > > Konrad. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: bounded memoize
Hello Christophe, On Fri, Mar 12, 2010 at 08:27:15PM +0100, Christophe Grand wrote: > See my memoize5: the call isn't computed inside the swap!s That doesn't mean, that it is not computed several times! user=> (defn f [x] (println "Got" x "from" (Thread/currentThread)) (Thread/sleep 5000) (case x 3 (f 2) 2 (f 1) 1 :done)) #'user/f user=> (def f (memoize5 f)) #'user/f user=> (-> #(do (f 3) (println "Done for" (Thread/currentThread))) Thread. .start) (Thread/sleep 2500) (-> #(do (f 3) (println "Done for" (Thread/currentThread))) Thread. .start) Got 3 from # Got 3 from # Got 2 from # Got 2 from # Got 1 from # Got 1 from # Done for # Done for # Hmm? Wasn't f supposed to memoized? The problem is, that the call to f is not guarded. > Since you use a lock I think some clever combination of memoized functions > can create a deadlock. No. In the protected area we simply create a promise and fire off a thread, which does the computation. Then we return immediatelly. So no deadlock possibility here. However we trade one lock for the „other“ (the promise). What is the possibility of a deadlock here? Well, the computation of f never completes. But this is not a problem of memoize. The only way memoize could cause a problem here is that the computation of f somehow calls f again with the same arguments. Then it would deadlock on the promise, but without memoize we would also have a infinite loop here... Sincerely Meikel -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Leiningen, Clojure and libraries: what am I missing?
Hi, On Thu, Mar 11, 2010 at 01:32:36PM -0800, Phil Hagelberg wrote: > Historically this has been because calculating the classpath couldn't > be done in Clojure itself since it needed to be done before the JVM > booted. Having to figure this kind of thing out in a shell script or > in elisp is a headache if the rules are not simple. But now with the > subclassloader approach that lein and mvn use it's less of an issue. > But it would mean deprecating the pure-elisp swank launcher, and I > don't know how it would affect other tools (IDEs, etc), so I'm still > hesitant. I think this is a typical emacs misconception. Vim is an editor. Why should it have to know how a JVM classpath works? Setting this up is the responsibility of the developer. Put everything in lib/? No problem. Let maven/gradle/lein handle the classpath? No Problem. Have an esoteric shell script doing some voodoo incatations? No Problem. Putting this logic into the editor was the failure in the first place. Sincerely Meikel -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: (seq? x) vr.s (not (empty? x))
Hi, On Fri, Mar 12, 2010 at 08:25:23AM +1100, Alex Osborne wrote: > The list equivalent to the vec or set functions is (apply list ...) -- > there's no shorthand for it as you shouldn't be using lists much > explicitly, use a vector instead. In fact there is a short-hand: user=> (seq []) nil user=> (vec []) [] user=> (set []) #{} user=> (sequence []) () Sincerely Meikel -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Achieving high performance, mutable primitives?
I see, so that's what I was missing. Thanks for your help! -Patrick -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: filter sequence until false result
I think what you want is take-while instead of filter: (take-while %(< % 20) primes) -Matt -- You 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: filter sequence until false result
Hmm.. I should re-read messages before sending them. The correct code is: (take-while #(< % 20) primes) -- You 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: Zip function
Hi, On Sat, Mar 13, 2010 at 06:55:56AM -0800, Marmaduke wrote: > I'm new to Clojure, but in other languages, zip is a workhorse, and I > didn't find it, so I > > (defn zip [& ss] > (partition (count ss) (apply interleave ss))) > > but because I didn't find it, I am suspicious: is there a better way? (defn zip [& colls] (apply map vector colls)) Sincerely Meikel -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Zip function
In clojure map works like zipWith. So you can pass to it vector if you want just plain zip: (map vector colls) That makes making a special named function unnesessary. On Mar 13, 6:55 am, Marmaduke wrote: > Hello, > > I'm new to Clojure, but in other languages, zip is a workhorse, and I > didn't find it, so I > > (defn zip [& ss] > (partition (count ss) (apply interleave ss))) > > but because I didn't find it, I am suspicious: is there a better way? > > Marmaduke > > ps. As a first-poster: thanks to Rich Hickey and Stuart Halloway for > the language and the book, respectively. -- You 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: bounded memoize
Hi Meikel, On Sat, Mar 13, 2010 at 10:51 PM, Meikel Brandmeyer wrote: > On Fri, Mar 12, 2010 at 08:27:15PM +0100, Christophe Grand wrote: > > > See my memoize5: the call isn't computed inside the swap!s > > That doesn't mean, that it is not computed several times! > I agree: it can be concurrently computed several times (but a given thread would only compute it at most once). I'm sory: I read too quickly and didn't understand that you were concerned about the computation happening only once for all threads. > > Since you use a lock I think some clever combination of memoized > functions > > can create a deadlock. > > No. In the protected area we simply create a promise and fire off a > thread, which does the computation. Then we return immediatelly. So no > deadlock possibility here. However we trade one lock for the „other“ > (the promise). What is the possibility of a deadlock here? Well, the > computation of f never completes. But this is not a problem of memoize. > The only way memoize could cause a problem here is that the computation > of f somehow calls f again with the same arguments. Then it would > deadlock on the promise, but without memoize we would also have a > infinite loop here... > You're right of course. I apologize. As a minor note: couldn't a future replace your promise? Or couldn't you get rid of the other thread and deliver the promise in the same thread but outside of the (locking ..) form? Hmm or even a delay!? Ok I tried to used delays. So I slightly modified my memoize5 (see memoize6) and I built on that a memoize7 which enforces (through delays) that a value is onlycomputed once (except if the strategy previously removed it from the cache of course). Do you see a problem in my latest implementation? http://gist.github.com/330644#LID153 Thank you, Christophe -- You 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: binary representation + operators
java to the rescue! Thanks to all for your suggestions Scott On Mar 13, 3:45 pm, Michał Marczyk wrote: > On 12 March 2010 23:26, Scott wrote: > > > How do I write a function 'bit' that converts an integer to binary > > representation: > > > (bit 0) -> 2r0 > > (bit 1) -> 2r1 > > (bit 2) -> 2r10 > > (bit 3) -> 2r11 > > I understand that you want a way to obtain a string representation of > a number in binary. I think you need to dispatch on class: > > (Integer/toBinaryString (int 5)) ; => "101" > (Integer/toBinaryString (Integer. 5)) => "101" > (Long/toBinaryString (long 5)) ; => "101" > (Long/toBinaryString (Long. (long 5))) ; => "101" > > (.toString (bigint 5) 2) ; the "2" indicates the radix; => "101" > (.toString (BigInteger. "5") 2) ; => "101" > > As far as I can tell, you can't use the int/long method with bigints > or the other way around. > > If you'd like to add the "2r" in front, just use str: > > (str "2r" "101") ; => "2r101" > > > As well, as function 'bit-concat' with the following behavior: > > > (bit-concat 2r1 2r00) -> 2r100 > > (bit-concat 2r0 2r00) -> 2r000 > > (bit-concat 2r011 2r1100) -> 2r000 > > I'd prefer to have bit-concat operate on actual numbers, not on > strings; you can convert the result later. To that end, here's a > possible solution (I'm *sure* there must be a better way... but it > works): > > (let [ls (zipmap (map #(loop [n % r 1] > (if (zero? n) >r >(recur (dec n) (* 2 r > (range 0 128)) > (map inc (range 0 128)))] > (defn bit-length [n] > (if (zero? n) > 0 > (condp = (class n) > Integer(ls (Integer/highestOneBit n)) > Long (ls (Long/highestOneBit n)) > BigInteger (.bitLength n) > > (comment > ; this returns true > (every? #(== (bit-length %) (.bitLength %)) > (map bigint (range 0 1000 > > (defn bit-concat [n m] > (bit-or (bit-shift-left n (bit-length m)) > m)) > > This will work as expected unless you use unboxed ints: > > user> (bit-shift-left (int 1) 63) > -2147483648 > user> (bit-shift-left (Integer. 1) 63) > 9223372036854775808 > user> (bit-shift-left (long 1) 128) > 340282366920938463463374607431768211456 > user> (bit-shift-left (long 1) 200) > 1606938044258990275541962092341162602522202993782792835301376 > user> (class (bit-shift-left (long 1) 200)) > java.math.BigInteger > > Sincerely, > Michał -- You 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
extending protocol
Is there a way to say that a protocol extends another protocol or interface? I.e. can i specify that a given protocol must also support the "seq" method from clojure.lang.Seqable? -- You 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: bounded memoize
On Mar 13, 4:51 pm, Christophe Grand wrote: > My variations on memoize use a single atom: your bounded-memoize id roughly > equivalent to my memoize2 + fifo-strategy, > seehttp://gist.github.com/330644#LID19. I finally found the time to fully read your gist, and I see you are indeed doing the same there. It's just a little less obvious due to the indirection introduced by strategies. > Two quick notes: > * a PersistentQueue is a better fit there (conj at one end, pop/peek at the > other) than a vector, > * by padding it to the desired length (capacity) with dummy items, you are > sure that the queue (or the vector) is always full, so you always have to > remove an item: no more need for the (> (count v) capacity) test. Agree, this simplifies the code a bit, and once we reach full capacity, the "if" will always be true anyway. > That's why Meikel tests twice if the value is already in the cache (the > first time outside of a transactio, the second time inside) and why I > introduce hit-or-assoc in memoize4/memoize5. Still, with bad luck or just enough concurrency, simultaneous calls to memoize6 with the same args can result in multiple computations, as the computation (apply f args) is done outside of the swap: (let [ret (if-let [e (find (cached @mem) args)] (val e) (apply f args)) m (swap! mem hit-or-assoc args ret)] This gap shrinks when using memoize7 thanks to the use of delays, but it is not completely closed and can still lead to multiple delays of the same computation. If we want to get rid off this gap and make it truely atomic, we have to make the decision whether or not to compute inside the swap! block. My memoizer with the hard-coded fifo strategy thus turns into something like this: (defn bounded-memoize [f capacity] (let [mem (atom [{} []])] (fn [& args] (deref ((first (swap! mem #(if (contains? (first %) args) % (let [new-cache (assoc (first %) args (delay (apply f args))) new-v (conj (second %) args)] (if (> (count new-v) capacity) [(dissoc new-cache (first new-v)) (subvec new-v 1)] [new-cache new-v]) args) Using a padded queue (and getting rid of the anonymous % param names), it can be (slightly) simplified to: (defn bounded-memoize [f capacity] (let [mem (atom [{} (into clojure.lang.PersistentQueue/EMPTY (repeat capacity :dummy))])] (fn [& args] (deref ((first (swap! mem (fn [[m q :as cache]] (if (contains? m args) cache [(dissoc (assoc m args (delay (apply f args))) (peek q)) (-> q pop (conj args))] args) -- You 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: bounded memoize
On Mar 14, 11:57 am, Eugen Dück wrote: > This gap shrinks when using memoize7 thanks to the use of delays, but > it is not completely closed and can still lead to multiple delays of > the same computation. If we want to get rid off this gap and make it Actually, I take that back. The delay might be created multiple times, but only one of them will be deref'ed (multiple 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
Re: extending protocol
aria42 a écrit : Is there a way to say that a protocol extends another protocol or interface? I.e. can i specify that a given protocol must also support the "seq" method from clojure.lang.Seqable? No. There is no hierarchy to protocols. This fits pretty well with the dynamic nature of Clojure, in my opinion: all checks of the type "does this value fit with that function" are done at runtime. Konrad __ Information provenant d'ESET NOD32 Antivirus, version de la base des signatures de virus 4942 (20100313) __ Le message a été vérifié par ESET NOD32 Antivirus. http://www.eset.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: proposal for core arithmatic functions
Jonathan Shore a écrit : I don't really share your worries at this time because the kind of performance problem you describe can always be fixed in a later optimized implementation. Perhaps not, but most of my work would have to be done in Java, which for me would be unacceptabe. I'm thinking Clojure is premature for my work at the moment. I am in a similar situation in that most of my computing needs involve number crunching. However, my experience (after 15 years of using Python as my main programming language) is that I can always concentrate time-critical code in a very few routines that I can then optimize by switching to a more performance-oriented languange (Pyrex for Python, probably Java for Clojure). That's why I am not worried about such issues at the moment. I am interested in Clojure for large-scale program structure and for dealing with concurrency, which I think are harder problems than optimizing an inner loop. Of course I am not claiming that this is good for everyone, I am just pointing out why I think Clojure is of interest for number crunchig right now. I recognize that Clojure is a smaller effort. It may well be that Exactly, and that comes with good and bad aspects, as so often. Th good part is that Clojure is much more innovative than anything designed by a committee could ever be, in particular in the way it deals with concurrency. I could be wrong, but would think that: *static* *public* *int* intCast(Object x){ *if*(x *instanceof* Number) *return* ((Number) x).intValue(); *return* ((Character) x).charValue(); } the "if" statement is not going to be optimised away by JIT. (This is what gets called on the literals). The JIT compiler does special-casing of functions for particular argument types. I don't know if it handles that particular kind of optimization, but it's not impossible. That is actually something I worry more about than raw performance, in the long run. Portable performance optimization seems pretty much impossible in any JVM language. Konrad. __ Information provenant d'ESET NOD32 Antivirus, version de la base des signatures de virus 4942 (20100313) __ Le message a été vérifié par ESET NOD32 Antivirus. http://www.eset.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: bounded memoize
Hi Christophe, your fifo-strategy (the one that uses "identity" as the hit method) does not work: user=> (def g (memoize7 identity (fifo-strategy 3))) #'user/g user=> (g 1) 1 user=> (g 1) java.lang.IllegalArgumentException: Wrong number of args passed to: core$identity (NO_SOURCE_FILE:0) You have to use something like #(first %&) instead of identity. memoize7 looks fine to me in terms of avoiding extra computation. I'm not sure though why memoize6 exists as a fn in its own right. I guess you wouldn't use it without something like delays, as the whole point of memoize is to avoid multiple costly computations of the same thing, and memoize6 does not always do that, unless you give it a fn f that takes care of it, as memoize7 does. If you don't rely on memoize6, you can write memoize7 even more compact than memoize6, like this: (defn memoize7-variant ([f] (memoize7-variant f [{} identity (fn [mem args] mem) assoc])) ([f [init cached hit assoc]] (let [mem (atom init)] (fn [& args] (deref ((cached (swap! mem (fn [mem] (if (contains? (cached mem) args) (hit mem args) (assoc mem args (delay (apply f args))) args)) It's more compact, as we do the contains? (or in your original version: "find") check only once inside the swap! function. This has the (admittedly not really huge) added benefit that we don't create multiple delays in the case of "bad luck", as mentioned in my earlier post. Any downsides to this? Cheers Eugen On Mar 14, 9:26 am, Christophe Grand wrote: > Hi Meikel, > > On Sat, Mar 13, 2010 at 10:51 PM, Meikel Brandmeyer wrote: > > On Fri, Mar 12, 2010 at 08:27:15PM +0100, Christophe Grand wrote: > > > > See my memoize5: the call isn't computed inside the swap!s > > > That doesn't mean, that it is not computed several times! > > I agree: it can be concurrently computed several times (but a given thread > would only compute it at most once). > I'm sory: I read too quickly and didn't understand that you were concerned > about the computation happening only once for all threads. > > > > Since you use a lock I think some clever combination of memoized > > functions > > > can create a deadlock. > > > No. In the protected area we simply create a promise and fire off a > > thread, which does the computation. Then we return immediatelly. So no > > deadlock possibility here. However we trade one lock for the „other“ > > (the promise). What is the possibility of a deadlock here? Well, the > > computation of f never completes. But this is not a problem of memoize. > > The only way memoize could cause a problem here is that the computation > > of f somehow calls f again with the same arguments. Then it would > > deadlock on the promise, but without memoize we would also have a > > infinite loop here... > > You're right of course. I apologize. > As a minor note: couldn't a future replace your promise? Or couldn't you get > rid of the other thread and deliver the promise in the same thread but > outside of the (locking ..) form? > Hmm or even a delay!? > > Ok I tried to used delays. So I slightly modified my memoize5 (see memoize6) > and I built on that a memoize7 which enforces (through delays) that a value > is onlycomputed once (except if the strategy previously removed it from the > cache of course). > > Do you see a problem in my latest > implementation?http://gist.github.com/330644#LID153 > > Thank you, > > Christophe -- You 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