Re: CLR questions
First of all, MonoDevelop should be able to load the .sln Ok, I'll have a look at that. I currently know nothing of .NET or mono, so it's all news to me :) As far as XNA...last I heard XNA did not have any support for emit, and as such is incapable of running any sort of jit code. Basically all .NET code has to be ahead-of-time compiled to run a XBOX via XNA. It's the same limitation that IronPython has (http://ironpython.codeplex.com/wikipage?title=FAQ). Ok, so for XBox stuff, ScalaCLR or F# would probably be more practical. That's unfortunate, but I'm not way too surprised. Thanks for the info! -- You 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: CLR questions
As far as XNA...last I heard XNA did not have any support for emit, and as such is incapable of running any sort of jit code. Basically all .NET code has to be ahead-of-time compiled to run a XBOX via XNA. It's the same limitation that IronPython has (http://ironpython.codeplex.com/wikipage?title=FAQ). Ok, so for XBox stuff, ScalaCLR or F# would probably be more practical. That's unfortunate, but I'm not way too surprised. Thanks for the info! And, as a lovely self-reply, replace that last practical with possible. I think that's more accurate. -- You 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
CLR questions
I have two (apparently unrelated) questions about ClojureCLR. First, does Clojure 1.2 build under mono? The clojure-clr tree only appears to have a .sln file; is there some sane way to convert that to a Makefile or a shell script that can be used under *nix? Secondly, has anybody tried deploying a clojure-based app under XNA (the XBox API)? I've seen some basic howtos for F#-based XNA development; I'd be interested in hearing about anybody's experience doing this with Clojure. Thanks for any input. -- You 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: Game development in Clojure
How would that have helped? The problem lay in the fact that there could be many subclasses of Document, but only one specific subclass, Attachment, could go into the attachments[] field. So if we had to split the code into two files, we'd have class Attachment(Document) # -- attachment.py needs to import from document.py ... and class Document def create_attachment self.attachments += Attachment.new() # -- document.py needs to import from attachment.py What python allows to break the circular dependency is function-level imports: attachment.py: from document import Document class Attachment(Document): pass document.py: class Document(object): def create_attachment(self): from attachment import Attachment self.attachments += Attachment.new() I don't think clojure has anything like this; it looks like imports are at the file-level, rather than the function level as in python. Perhaps there is a way though? -- You 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: Help speed up an inner loop?
(defn countnl-lite [#^bytes buf] (areduce buf idx count (int 0) (if (= (clojure.lang.RT/aget buf idx) 10) (unchecked-add count 1) count))) Key points are initializing count to a primitive integer and directly calling clojure's aget to avoid an unnecessary integer cast. Are you using clojure 1.2? If I try to set count to be (int 0) rather than 0, I get this error: Exception in thread main java.lang.RuntimeException: java.lang.IllegalArgumentException: recur arg for primitive local: count must be matching primitive Even if I replace inc with the unchecked-add, or cast the result of the inc to be int (replace (inc count) with (int (inc count)) ) it gives me that error. Sort of strange... -- You 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: Help speed up an inner loop?
Replace also (unchecked-add count 1) with (unchecked-add count (int 1)) (this should get easier in 1.3) That didn't change anything for my tests, but this code: (defn countnl [#^bytes buf] (areduce buf idx count (int 0) (if (= (aget buf idx) 10) (unchecked-add count 1) count))) does 34ms runs (the .java code does 20ms runs on the same machine). The biggest things that make a difference are replacing (inc count) with (unchecked-add count 1), initializing count to (int 0) rather than 0, and getting rid of the (let [nl (byte 0)]...). I was a bit disappointed that the let statement was so expensive, since I really prefer seeing a variable to a magic number. Has somebody written a macro that can be used to rewrite code replacing variable references with their constant values? It would be of limited use (constants only), but it would make the code prettier :) For posterity, here are some variations on countnl and their timings on my machine: all runs are invoked with this command: java -server -cp clojure.jar clojure.main iterate.clj; clojure.jar is from the clojure-1.2.zip distribution (defn countnl [#^bytes buf] (let [nl (byte 10)] (areduce buf idx count 0 (if (= (aget buf idx) nl) (inc count) count Wanted 16777216 got 16777216 bytes Elapsed time: 184.172834 msecs Got 65875 nls Wanted 16777216 got 16777216 bytes Elapsed time: 193.546018 msecs Got 64995 nls Wanted 16777216 got 16777216 bytes Elapsed time: 142.546453 msecs Got 65677 nls Wanted 16777216 got 16777216 bytes Elapsed time: 135.843933 msecs Got 66117 nls Wanted 16777216 got 16777216 bytes Elapsed time: 134.882156 msecs Got 65449 nls Wanted 16777216 got 16777216 bytes Elapsed time: 134.864881 msecs Got 65393 nls Wanted 16777216 got 16777216 bytes Elapsed time: 134.854118 msecs Got 65065 nls Wanted 16777216 got 16777216 bytes Elapsed time: 134.82848 msecs Got 65346 nls Wanted 16777216 got 16777216 bytes Elapsed time: 134.803702 msecs Got 65783 nls Wanted 16777216 got 16777216 bytes Elapsed time: 134.832489 msecs Got 65566 nls (defn countnl [#^bytes buf] (let [nl (byte 10)] (areduce buf idx count (int 0) (if (= (aget buf idx) nl) (inc count) count Wanted 16777216 got 16777216 bytes Elapsed time: 238.409697 msecs Got 65698 nls Wanted 16777216 got 16777216 bytes Elapsed time: 208.872818 msecs Got 65381 nls Wanted 16777216 got 16777216 bytes Elapsed time: 88.786986 msecs Got 65358 nls Wanted 16777216 got 16777216 bytes Elapsed time: 88.76816 msecs Got 65686 nls Wanted 16777216 got 16777216 bytes Elapsed time: 88.899431 msecs Got 65683 nls Wanted 16777216 got 16777216 bytes Elapsed time: 88.783275 msecs Got 65491 nls Wanted 16777216 got 16777216 bytes Elapsed time: 88.735416 msecs Got 65749 nls Wanted 16777216 got 16777216 bytes Elapsed time: 88.762987 msecs Got 65837 nls Wanted 16777216 got 16777216 bytes Elapsed time: 88.749591 msecs Got 65759 nls Wanted 16777216 got 16777216 bytes Elapsed time: 88.72971 msecs Got 65366 nls (defn countnl [#^bytes buf] (areduce buf idx count (int 0) (if (= (aget buf idx) 10) (inc count) count))) Wanted 16777216 got 16777216 bytes Elapsed time: 185.465613 msecs Got 65344 nls Wanted 16777216 got 16777216 bytes Elapsed time: 186.856418 msecs Got 65529 nls Wanted 16777216 got 16777216 bytes Elapsed time: 73.778183 msecs Got 65662 nls Wanted 16777216 got 16777216 bytes Elapsed time: 73.675509 msecs Got 65034 nls Wanted 16777216 got 16777216 bytes Elapsed time: 73.674777 msecs Got 65459 nls Wanted 16777216 got 16777216 bytes Elapsed time: 73.630553 msecs Got 65172 nls Wanted 16777216 got 16777216 bytes Elapsed time: 73.668685 msecs Got 64939 nls Wanted 16777216 got 16777216 bytes Elapsed time: 73.74801 msecs Got 65462 nls Wanted 16777216 got 16777216 bytes Elapsed time: 73.699187 msecs Got 65602 nls Wanted 16777216 got 16777216 bytes Elapsed time: 73.611555 msecs Got 64937 nls (defn countnl [#^bytes buf] (areduce buf idx count (int 0) (if (= (aget buf idx) 10) (unchecked-add count 1) count))) Wanted 16777216 got 16777216 bytes Elapsed time: 82.865761 msecs Got 65266 nls Wanted 16777216 got 16777216 bytes Elapsed time: 34.228646 msecs Got 65522 nls Wanted 16777216 got 16777216 bytes Elapsed time: 33.989741 msecs Got 65537 nls Wanted 16777216 got 16777216 bytes Elapsed time: 33.947045 msecs Got 65688 nls Wanted 16777216 got 16777216 bytes Elapsed time: 33.941481 msecs Got 65395 nls Wanted 16777216 got 16777216 bytes Elapsed time: 33.952149 msecs Got 65822 nls Wanted 16777216 got 16777216 bytes Elapsed time: 33.972258 msecs Got 65495 nls Wanted 16777216 got 16777216 bytes Elapsed time: 33.903989 msecs Got 65244 nls Wanted 16777216 got 16777216 bytes Elapsed time: 33.927276 msecs Got 65331 nls Wanted 16777216 got 16777216 bytes Elapsed time: 33.917789 msecs Got 65470 nls (defn
Re: Help speed up an inner loop?
This one is quite good for me. (defn countnl [#^bytes buf] (let [nl (int 10)] (areduce buf idx count (int 0) (if (== (int (aget buf idx)) nl) (unchecked-inc count) count It appears that == is not resolved for bytes. So converting to int works fine. aha, converting to int works for me as well. With bytes it triggers the reflection warning and takes minutes to run. with the int conversion, it runs in an average of 28ms (just a little over java). Here's something really strange: I de-inlined the newline int, so my function looks like this: (defn countnl [#^bytes buf] (let [nl (int 10)] (areduce buf idx count (int 0) (if (== (int (aget buf idx)) nl) (unchecked-add count (int 1)) count On my machine, this is running in 19.6ms (after the warmup it's really constant). That's the exact speed as the java code, which is really cool. it actually works the same way if you just replace the inlined 10 with (int 10), and it makes it just as fast as the explicit looping code below. Somehow on my earlier tests the let binding was really slowing things down, but in this latest function it seems to have no effect. weird... In this situation, inlining (int 10) does not buy much. interesting; for me replacing the 10 with (int 10) brings my times from 28.7ms to 19.6ms. This one, though, is even faster and should be not far from the java one, if you want to try it. (defn countnl [#^bytes buf] (let [nl (int 10) n (int (alength buf))] (loop [idx (int n) count (int 0)] (if (zero? idx) count (let [idx (unchecked-dec idx)] (if (== (int (aget buf idx)) nl) (recur idx (unchecked-inc count)) (recur idx count))) It would be interesting to know why it is nearly twice as fast as the areduce version on my computer. That runs in 21.3ms for me, which actually makes it a tiny bit slower than the code above (and slightly slower than the java code). -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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
Help speed up an inner loop?
Just to try to see if clojure is a practical language for doing byte-level work (parsing files, network streams, etc), I wrote a trivial function to iterate through a buffer of bytes and count all the newlines that it sees. For my testing, I've written a C version, a Java version, and a Clojure version. I'm running each routine 10 times over a 16MB buffer read from /dev/urandom (the buffer is refreshed between each call to the newline counting function). With gcc -O0, I get about 80ms per 16MB buffer. With gcc -O3, I get ~14ms per buffer. With javac (and java -server) I get 20ms per 16MB buffer. With clojure, I get 105ms per buffer (after the jvm warms up). I'm guessing that the huge boost that java and gcc -O3 get is from converting per-byte operations to per-int ops; at least that ~4x boost looks like it would come from something like that. Is that an optimization that is unavailable to clojure? The java_interop doc makes it sound like java and clojure get the exact same bytecode when using areduce correctly, so maybe there's something I could be doing better. Here are my small programs; if somebody could suggest improvements, I'd appreciate them. iterate.clj: (set! *warn-on-reflection* true) (import java.io.FileInputStream) (def *numbytes* (* 16 1024 1024)) (defn countnl [#^bytes buf] (let [nl (byte 10)] (areduce buf idx count 0 (if (= (aget buf idx) nl) (inc count) count (let [ifs (FileInputStream. /dev/urandom) buf (make-array Byte/TYPE *numbytes*)] (dotimes [_ 10] (let [sz (.read ifs buf)] (println Wanted *numbytes* got sz bytes) (let [count (time (countnl buf))] (println Got count nls) Iterate.java: import java.io.FileInputStream; class Iterate { static final int NUMBYTES = 16*1024*1024; static int countnl(byte[] buf) { int count = 0; for(int i = 0; i buf.length; i++) { if(buf[i] == '\n') { count++; } } return count; } public static final void main(String[] args) throws Throwable { FileInputStream input = new FileInputStream(/dev/urandom); byte[] buf = new byte[NUMBYTES]; int sz; long start, end; for(int i = 0; i 10; i++) { sz = input.read(buf); System.out.println(Wanted + NUMBYTES + got + sz + bytes); start = System.currentTimeMillis(); int count = countnl(buf); end = System.currentTimeMillis(); System.out.println(counted + count + nls in + (end-start) + msec); } input.close(); } } iterate.c: #includesys/types.h #includesys/stat.h #includesys/time.h #includestdlib.h #includeunistd.h #includestdio.h #includefcntl.h int countnl(char *buf, int sz) { int i; int count = 0; for(i = 0; i sz; i++) { if(buf[i] == '\n') { count++; } } return count; } int main() { int fd = open(/dev/urandom, O_RDONLY); const int NUMBYTES = 16*1024*1024; char *buf = (char*)malloc(NUMBYTES); int sz; struct timeval start, end; int i; for(i = 0; i 10; i++) { sz = read(fd, buf, NUMBYTES); printf(Wanted %d bytes, got %d bytes\n, NUMBYTES, sz); gettimeofday(start, 0); int count = countnl(buf, sz); gettimeofday(end, 0); printf(counted %d nls in %f msec\n, count, (float)(end.tv_sec-start.tv_sec)*1e3 + (end.tv_usec-start.tv_usec)/1e3); } free(buf); close(fd); return 0; } -- You 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 get Clojure.Contrib in my Classpath?
java -classpath C:\Program Files\Clojure\clojure.jar;C:\Program Files\Clojure\clojure-contrib-1.1.0.jar clojure.main This starts the repl without a problem, but still, any attempt to use a class or function from the contrib library fails, for example, running this at the repl... I'm not sure about windows, but under *NIX the classpath is colon separated. Maybe using a colon between the two jars instead of a semicolon would help. -- You 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 get Clojure.Contrib in my Classpath?
I had already tried using a colon as the separator, but it gave an error. I've also noticed that if neither path resolves to a file, it also errors, so it's finding clojure-contrib-1.1.0.jar. Can you use it with (use 'clojure.contrib.duck-streams) ? Both ways work for me, but it's the only other thought I have. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Parallel activities
When you send-off an action to an agent, that agent gets is allocated a thread for at least the duration of that action. So using send-off on long-running actions to two agents will result in those actions being run in parallel. Ok, I re-read the docs on agents, and it looks like they don't do what I was thinking they do. One thread acts on an agent at once; I somehow missed that. I was thinking that multiple sends could run on one agent at once, which just isn't the case. And finally, there's really nothing wrong with using (.start (Thread. myfn)), if that accomplishes exactly what you need. I'm guessing that's what I'll wind up doing. I know it's not clojure's style, but it just seems like there should be some core macro (dothread ...) that puts the body into a (.start (Thread. ...)) call. I guess I'll write one :) --Chouser http://joyofclojure.com/ Reading through it right now. Very nice book so far, but I'm really looking forward to chapters 9 and 10 :) -- You 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
Parallel activities
What is the clojure idiom for running multiple (in this case IO bound) functions simultaneously? My use case is the parallel activities are coordinated, basically running in lockstep. I've been using (.start (Thread. myfn)). It works, but I'm wondering if there's a better way. The data shared between the threads is stored in an agent, which sort of suggests send-off to me, but I can't find any reason to think that send-off runs everything in parallel. Any thoughts would be welcome. -- You 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
QCon video download
Does anybody have a download link for the QCon talk that is linked from the clojure front page? I tend to use platforms where Flash support is even worse than normal, whereas mplayer tends to be very good at playing videos on every machine I use. -- You 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: QCon video download
If you watch the http traffic, e.g. in firebug, you'll see it makes a request to: http://flv.thruhere.net/presentations/09-mar-persistentdatastructures.flv You'll have to find the slides on the qcon homepage if you want to follow. Thanks! -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Augmenting the defn attr-map
The official docs for this are at: http://clojure.org/ special_forms#let . That's a great link. Thanks! --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Augmenting the defn attr-map
(defh a [b:String [c:Double :as list:java.util.List] {d:java.util.Random :d}] (.toCharArray b) (.size list) (.floatValue c) (.nextInt d)) What's that :as in the [ c:Double :as list:java.util.List ] vector? --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~---
Augmenting the defn attr-map
I'd like to add a :signature entry to the attr-map of defn, that provides a haskell-style type signature to functions of the single-arglist-body form. I find the the normal way of providing hints to a function: (defn [ #^Class1 var1 #^Class2 var2 #^Class3 var3] ... ) is way too noisy, and the variables get lost between the types. What I'd like instead is to be able to specify the signature in the function metadata: (defn {:signature [ Class1 Class2 Class3 ReturnType ]} [ var1 var2 var3 ] ...) I've written a little patch to defn that annotates the arguments correctly (I think). I'm not sure where the metadata for marking up a function's return type goes (Is it on the (cons `fn fdecl) part?), but it probably wouldn't be hard if I knew what I was doing :) Anyhow, a revised defn (I've called it defn+ to avoid clashes) is as follows: (defn zip [ a b ] (map vector a b)) (def #^{:doc Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata :arglists '([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body)+ attr-map?])} defn+ (fn defn+ [name fdecl] (let [m (if (string? (first fdecl)) {:doc (first fdecl)} {}) fdecl (if (string? (first fdecl)) (next fdecl) fdecl) m (if (map? (first fdecl)) (conj m (first fdecl)) m) fdecl (if (map? (first fdecl)) (next fdecl) fdecl) fdecl (if (vector? (first fdecl)) (if (:signature m) ; we'll apply the types in the signature vector as the ; :tag metadata for each argument (list (cons (apply vector (for [[ tag var ] (zip (:signature m) (first fdecl))] (with-meta var {:tag tag}))) (rest fdecl))) (list fdecl)) fdecl) m (if (map? (last fdecl)) (conj m (last fdecl)) m) fdecl (if (map? (last fdecl)) (butlast fdecl) fdecl) m (conj {:arglists (list 'quote (sigs fdecl))} m)] (list 'def (with-meta name (conj (if (meta name) (meta name) {}) m)) (cons `fn fdecl) (. (var defn+) (setMacro)) Is this something that people would think is worthwhile? I really prefer haskell's type signatures to clojure's inline hints, but maybe it's just something that people get used to. Anyhow, my first attempt at macro hacking, so kind criticism would also be welcome w.r.t. style, correctness, etc. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Augmenting the defn attr-map
- There's already a lot of moving parts to type hinting, so adding this optional approach into defn seems like it'd lead to unintended consequences. That said, there's absolutely nothing wrong with an alternative def form (defh? as in 'define hinted fn') -- there's plenty of them throughout contrib and elsewhere. Yeah, I tried to slip my change into a place in defn that probably wouldn't hurt anything, but I'm still not sure what the full consequences of my change are. I'm far from a clojure expert :) - Remember destructuring, and along with that, one of the nice thing about in-place hints, as opposed to a separate definition of expected types, is that the definitions can be sparse, e.g.: (defn foo [{blah :foo #^MyType mt-obj :bar} a b c] ...) It doesn't look like your macro supports hinting destructured args (understandably enough, doing so given the :signatures approach would likely be very difficult). I didn't put it in yet, but I was thinking of just having nil in the type vector for unhinted variables, so you could have (defn foo {:signature [ String String nil ]} [ a b c ] ...) and then c wouldn't be hinted. I hadn't thought of destructuring at all; I'm guessing that it could be done with (defn foo {:signature [{:bar Mytype} nil nil nil]} [{blah :foo mt-obj :bar} a b c] ...) but that's getting pretty ugly on its own. I'm not sure if it would be a win to try to do anything fancy like that. I'm also not sure what the destructuring assignment syntax is for maps right now, so what I wrote might be total nonsense, syntactically. I hope the idea is clear, anyhow. - The thing I don't like about the current type hints is (IMO) the distracting quality of '#^'. What about something like: (defh foo [String:s unhinted-arg {int:a :a}] ...) or (defh foo [s:String unhinted-arg {a:int :a}] ...) That's far more visually-appealing to me, and has the nice advantages of being inline in the case of destructuring and supporting sparse hinting easily. I'll bet the macro would end up being pretty simple, as well. I'd hate to see somebody do it, but it's currently valid to define variables with colons in them, so there could be code out in the wild with those definition forms already. Other than that, I like the looks of it. I think the macro would be easy as well, so long as you're comfortable munging variable names :) --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~---
zipping together two lists
Most languages I've used define a zip method, where you can take two lists and get a list of the pairs of elements in those lists. So, (zip '(1 2 3) '(4 5 6)) would give ([1 4] [2 5] [3 6]). Does clojure have a core function like that? I've been poking around, but all I'm finding is zipmap, which is close but it builds a map instead of a list of pairs. Writing my own isn't a big deal, but it seems like something that has to be in the core somewhere. --~--~-~--~~~---~--~~ You 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: zipping together two lists
map can do this. user (map vector '(1 2 3) '(4 5 6)) ([1 4] [2 5] [3 6]) Yeah, that works pretty well. Thanks! --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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 is this using reflection?
I thought it might be fun to try out the new repl-utils expression-info fn on this. Is this just in source control, or is it in a release? I'm using 1.0.0, and I don't seem to have that function. So first I had to recreate your 'import' line (you might consider including this kind of detail next time you post a question): Yeah, sorry about that. I'll remember next time. Well, that seems to have done it. Using that style in the original expression, we get: (defn searcher-path [#^IndexSearcher searcher] (let [#^FSDirectory fsdir (.. searcher getIndexReader directory) #^String path (.. fsdir getFile getPath)] path)) That compiles without reflection warnings. I thought I had tried this and gotten an error for it; I must have made a typo and assumed it was an invalid thing to do. It's certainly working now :) Where can I get more info on the expression-info call? A google search for expression-info and clojure gives a pdf on multiple dispatch and nothing else. Note also that hinting 'path' as 'String' doesn't really do any good when all we do is return it: That's really strange. The clojure compiler doesn't put types on functions when the only value returned from a function has an explicit type? user= (expression-info '(searcher-path nil)) nil If you want to promise that 'searcher-path' will always return a String so that the compiler can make further type deductions based on that, you need to hint the function itself: (defn #^String searcher-path [#^IndexSearcher searcher] (let [#^FSDirectory fsdir (.. searcher getIndexReader directory)] (.. fsdir getFile getPath))) user= (expression-info '(searcher-path nil)) {:class java.lang.String, :primitive? false} In the type hinting page, it says type hits can be applied to function parameters, let-bound names, var names and expressions. Is the #^String here being applied to a var name (searcher-path)? It wasn't obvious to me that one could do that, although I guess functions names are variables just like any other names in the system. --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~---
Why is this using reflection?
I have a function to get the path out of a lucene searcher (documentation at http://lucene.apache.org/java/2_3_2/api/core/org/apache/lucene/search/IndexSearcher.html). The searcher has a Reader, which has a Directory. The Directory is abstract, but in my case I know that it's a FSDirectory, so I declare fsdir, and then use its getFile and getPath. The actual code I'm using is: (defn searcher-path [ #^IndexSearcher searcher ] (let [fsdir #^FSDirectory (.. searcher getIndexReader directory) path #^String (.. fsdir getFile getPath) ] path)) When I compile this with warn-on-reflection, I get that getField and getPath cannot be resolved. Am I doing the hinting wrong somehow? I do have imports in my file for IndexSearcher and FSDirectory, so I'm not sure what I'm missing. I've also tried this with nested lets, but that didn't help either (as expected). --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Using generics
I have a java class whose constructor expects (among other things) a BlockingQueueLong. It's easy to create a BlockingQueue in clojure (obviously), but I can't figure out the syntax to specialize it to the Long type. Is this possible, or does it even make sense? I seem to recall that generics are just hints for the java compiler and not actually enforced by the runtime, which would imply that clojure has no need to support them. Is that the case? --~--~-~--~~~---~--~~ You 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: Using generics
user= (show Class) === public final java.lang.Class === [ 0] static forName : Class (String) [ 1] static forName : Class (String,boolean,ClassLoader) [ 2] asSubclass : Class (Class) [...] nil user= (show Class 2) #Method public java.lang.Class java.lang.Class.asSubclass(java.lang.Class) This shows that the entry point is at some level really expecting a Class and returning a Class. Yeah, that makes sense. Thanks! --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: ns :use with :rename
Here's the correct syntax: (ns namespace (:use [other-namespace :rename {existing newname}])) aha, brackets. Is there a plan to flesh out the API page to have more examples of things like that? As it stands, I think the API page is probably great for somebody who needs a reminder, but for a newbie, it could probably be a little more friendly. --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~---
ns :use with :rename
Is there an example of using :rename in a :use in the ns macro? I'm trying to get it to work, but the best I can come up with is: (ns namespace (:use other-namespace :rename { :existing :newname })) and when compiling, I get ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.IFn. I'm not sure what's being turned into a boolean or what should be an IFn, but if I get rid of everything between :rename and ), it compiles. --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~---
compilation and classpath
I'm having some trouble getting clojure to generate .class files. I have a directory layout like this: test/ main.clj where main.clj is the same file as from http://clojure.org/compilation, but with the 'clojure.examples.hello replaced with 'test.main . I've tried running clojure a few different ways: from the parent dir of the test dir, as java -cp ~/src/clojure/clojure.jar:`pwd`/ clojure.main from within the test dir, as java -cp ~/src/clojure/clojure.jar:`pwd`/.. In both cases, I can successfully (use 'test.main) and call (-main foo), and it works, but when I try to call (compile 'test.main) I get java.io.IOException: No such file or directory (main.clj:1). What do I need to do to get compilation to work? --~--~-~--~~~---~--~~ You 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: compilation and classpath
You probably need to set (and create!) the correct compilation (output) directory. This defaults to a classes directory as a subdirectory of your current working directory. So if you had: And this worked! Now that I'm looking for the *compile-path* variable, I see that it's mentioned in the compilation page. I guess I skimmed a little too lightly :) Thanks a ton! --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: String.getBytes does not translate to byte[]?
Well, under the covers the str function applies the java toString method to any passed in object and hence the result could for some reason be different to the original String object passed in. I think this could occur if the object subclasses String, but has a different representation (i.e a different toString method). Are you able to post what s contains when this happens? You could try printing s in your calling function and then also in the defmethod, e.g; (defmethod t-str String [s] (prn cls: (class s) s: s chars: (vec s Maybe that'll shed some light? I thought I sent this to the list, but I think I just sent it to a single person, so I'm trying again... Ok, here's a stripped down set of code that has the problem. It does require that erlang be installed with java support. I couldn't figure out a way to duplicate the problem without it, unfortunately. To test this out, first start erlang like this: erl -setcookie cookie -sname e...@localhost Then, run the attached demo.clj. Once that's started (it won't print anything, so just give it a sec to get running), run the following from the erlang REPL: { echo, e...@localhost } ! { self(), hi there }. and then, after the demo.clj has exited, (fun() - receive X - X after 0 - nil end end)(). As the code is submitted, you will get a reply that looks like 172,237,0,5,117,114,0,2,91,66,172,243,23,248,6,8,84,224, 2,0,0,120,112,0,0,0,8,104,105,... If you replace the (let [ inside s ...]) with (let [ inside (str s) ...]) and rerun the test, you will get the string hi there, as a binary. On the clojure side, the following is printed with [ inside s ]: I was given a class java.lang.String Chars are [\h \i \space \t \h \e \r \e] Given string is 'hi there' Bytes length is 8 OtpBinary size is 35 with [ inside (str s) ] I was given a class java.lang.String Chars are [\h \i \space \t \h \e \r \e] Given string is 'hi there' Bytes length is 8 OtpBinary size is 8 So, I'm hoping this gives somebody an idea, because I'm stumped. --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~--- demo.clj Description: Binary data
Re: String.getBytes does not translate to byte[]?
I guess that if you enable reflection warnings, you'll get a warning on the line where you invoke the constructor. I think the reflective dispatch doesn't pick the good constructor and invokes OtpErlangBitstr(Object) instead of OtpErlangBitstr(byte[]). Thus your byte[] is serialized and the 35 above is the length of the serialized array. A type hint on s should fix the issue: (defmethod to-otp String [ #^String s ] (OtpErlangBinary. (.getBytes s utf-8))) Ok, that worked, but I don't understand why. How does forcing the type of s to be String cause the dispatch to use the byte[] constructor instead of the Object constructor? This would make sense if we were somehow coercing the return value of .getBytes to be a byte[] instead of an Object, but I don't see how the type checker is calling any constructor other than a byte[] constructor when that's the return value of getBytes already. Does this have anything to do with the fact that (class (first (.getBytes hi))) gives java.lang.Byte instead of just plain byte? I had noticed that (and thus the subject of this topic), but in my smaller tests it didn't seem to matter. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: String.getBytes does not translate to byte[]?
I guess that if you enable reflection warnings, you'll get a warning on the line where you invoke the constructor. As a bit of an aside, is there a reason that using multimethods with class-based dispatch doesn't add type hints by itself? It seems sort of strange that it's necessary to define your methods with (defmethod name Class [ #^Class arg ] ...) instead of just being able to do (defmethod name Class [ arg ] ...). --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: String.getBytes does not translate to byte[]?
It's a type hint, it's not a type coercion. Without the type hint, the compiler doesn't know the type of s, so it can't find the .getBytes method (nor, of course, its return type) and, in doubt, picks the broader constructor: OtpErlangBinary(Object). With the type hint, the compiler know that s must be treated as a String, it find .getBytes, sees that it returns a byte[] and is able to select the right constructor for OtpErlangBinary. Is the OtpErlangBinary constructor that's being used actually determined at compile time, rather than at run time? --~--~-~--~~~---~--~~ You 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 -~--~~~~--~~--~--~---
String.getBytes does not translate to byte[]?
I'm trying to encode a java string into utf-8 for encapsulation within an OtpErlangBinary (http://erlang.org/doc/apps/jinterface/java/com/ericsson/otp/erlang/OtpErlangBinary.html). When I try to construct an OtpErlangBinary from the results of String.getBytes(encoding), I get bad data. A string (pure ascii) with 20 characters becomes a 47-byte OtpErlangBinary, and none of the bytes in that binary seem to correspond to the bytes of the string. The simple function that I have looks like this: (defmethod to-otp String [ s ] (new OtpErlangBinary (.getBytes s utf-8))) And the OtpErlangBinary gets 47 bytes of data for a 20 byte string. However, if I change that code to read: (defmethod to-otp String [ s ] (new OtpErlangBinary (.getBytes (str s) utf-8))) (notice the (str s)), the code works. It seems really strange to me that this should happen, but I don't know clojure well enough to determine what's going on under the hood. Is there some way to dump the java code equivalent of those two functions, so I can compare them? I've tried making a minimal test case for converting strings into OtpErlangBinaries, but I can't get this bug to manifest in any circumstances other than this one program. Any tips for debugging would be much appreciated. I'm running clojure 1.0.0, with java 1.6.0, and erlang jinterface 1.4. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: String.getBytes does not translate to byte[]?
Maybe there's something about the particular [ s ] object that you're passing in? I believe that you're right; in general, the getBytes seems to work. It is just in this one freakish case that it doesn't, but I have no idea how to tell what's special about my string. I'm not exactly proficient in Java, and I'm a complete clojure newbie, so I really have no idea how to proceed with debugging this. Under what circumstances would (str s) give something different from s, when (.getClass s) gives java.lang.String? Also, sorry for the horrible subject line; that was my initial guess, and I had a big email written up about it, but then I started testing my assumptions and they were all garbage. I rewrote the email, but forgot about the subject... --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---