2009-12-18
| 00:20 | scottj_ | Am I missing something or does clojureql not have an equivalent of limit? |
| 00:21 | polypus | does the order of definition of defmethods have any effect on dispatch? |
| 00:28 | alexyk | how do you compare strings? |
| 00:30 | alexyk | ,(< "a" "b") |
| 00:30 | clojurebot | java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number |
| 00:30 | kylesmith | ,(.compareTo "a" "b") |
| 00:30 | clojurebot | -1 |
| 00:31 | alexyk | thx! |
| 00:32 | alexyk | where does compareTo come from? |
| 00:32 | alexyk | ah, ok . |
| 00:33 | chouser | polypus: no, I don't think so. |
| 00:33 | chouser | polypus: if there's any ambiguity, it must be resolved with 'prefer' |
| 00:34 | alexyk | I compare pairs of form [string vector], by longer vectors first, then ties broken by alphabetic order of strings. This works but is ugly: (sort (fn [[k1 v1][k2 v2]] (let [len1 (count v1) len2 (count v2)] (if (> len1 len2) true (if (< len1 len2) false (.compareTo k1 k2))))) coll) ; ways to improve? |
| 00:34 | polypus | chouser: ty |
| 00:38 | chouser | alexyk: did you try a default sort? |
| 00:39 | alexyk | chouser: it does the opposite: by keys and small lengths |
| 00:39 | chouser | ah |
| 00:39 | alexyk | I'd reverse it. but then alphabetic order is broken |
| 00:39 | chouser | yes |
| 00:43 | chouser | maybe (sort (fn [[k1 v1][k2 v2]] (let [len1 (count v1) len2 (count v2) c1 (compare len1 len2)] (if (zero? c1) (compare k1 k2) c1))) coll) |
| 00:43 | chouser | hardly better though, if it even works |
| 00:43 | alexyk | chouser: cutier |
| 00:46 | chouser | (sort-by (fn [[k v]] [(- (count v)) k]) coll) ? |
| 00:48 | polypus | ,(doc prefer) |
| 00:48 | clojurebot | I don't understand. |
| 00:48 | chouser | ,(doc prefers) |
| 00:48 | clojurebot | "([multifn]); Given a multimethod, returns a map of preferred value -> set of other values" |
| 00:48 | chouser | ,(doc prefer-method) |
| 00:48 | clojurebot | "([multifn dispatch-val-x dispatch-val-y]); Causes the multimethod to prefer matches of dispatch-val-x over dispatch-val-y when there is a conflict" |
| 00:48 | chouser | there it is. sorry. |
| 00:49 | chouser | alexyk: you saw that sort-by? |
| 00:49 | chouser | biab |
| 00:49 | alexyk | hah |
| 00:49 | polypus | no worries. i was wondering about the conflict bit. are you explicitly told by clojure aout conflicts? |
| 00:50 | polypus | s/aout/about |
| 00:50 | alexyk | interesting -- will try after re-vectoring seconds, they were seqs and it takes forever for counts to get retaken every time |
| 00:58 | defn | how do you use 1.1.0 with technomancy's swank? |
| 01:10 | scottj_ | defn: copy it to ~/.swank-clojure/clojure-1.0.0.jar I think |
| 01:11 | defn | wish there was a way to choose |
| 01:11 | defn | or a var to set |
| 01:36 | chouser | polypus: yes, Clojure will complain when a multimethod is called if the dispatch result is ambiguous. |
| 01:48 | alexyk | is ArraySeq usually counted? |
| 01:50 | alexyk | I did (->> ... (frequencies) (sort) as the second component above, and it takes forever to sort with my comparator above taking (count <of that>). Should I have added ... (vector)? |
| 01:51 | alexyk | Without (vector), the type is ArraySeq; with (vector), it's PersistentVector. On both toy examples say counted? => true. I wonder what happens when they come from lazy data. |
| 01:51 | alexyk | I have 3.5 million pairs with those seconds, and it takes more than an hour already to sort. |
| 02:06 | polypus | chouser: ty |
| 03:07 | defn | is freenode still acting weird? |
| 03:40 | triyo | I see there is a bean function, is there a to-bean function of some sort that does the opposite? |
| 04:01 | LauJensen1 | triyo: Did you look in contrib, there's a jmx module I think |
| 04:02 | LauJensen1 | http://github.com/richhickey/clojure-contrib/blob/master/src/clojure/contrib/jmx.clj |
| 04:03 | triyo | LauJensen1: hmm, that mbeans. :) |
| 04:04 | LauJensen1 | oh, sorry |
| 04:04 | triyo | no wrorries |
| 05:45 | octe | i was looking at http://github.com/richhickey/clojure/blob/1.1.x/changes.txt but i don't see anythign about defmulti.. didn't the signature for it change? |
| 05:45 | octe | between 1.0 and 1.1 |
| 06:07 | triyo | I'm confused, when is the right time/place to use the "do" form? |
| 06:12 | fanatico | when you're calling a function for its side effect, and want to return a different value. |
| 06:13 | Raynes | triyo: In places like an if expression, where you want to call functions for side effects, but want to return a different value than the one those functions return. |
| 06:15 | triyo | for example like this snippet: http://gist.github.com/259443 its nothing but full of side-effects... should there be a do there |
| 06:15 | Raynes | ,(if false 3 (do (+ 2 2) (* 3 3) 5)) ; Useless example. |
| 06:15 | clojurebot | 5 |
| 06:16 | triyo | Raynes: if expression is the only place where I do know how to use it and where it makes sense |
| 06:16 | Raynes | If I don't /have/ to use it, I don't. |
| 06:17 | triyo | Raynes: for example, would you use it in my snippet gist above? |
| 06:18 | triyo | around the doto all way to the end |
| 06:18 | Raynes | Nope. |
| 06:19 | triyo | ok, thats the same feeling I had.. just trying to make sure I don't use it unnecessarily. |
| 08:25 | fliebel | Why doesn't Clojure have objects? |
| 08:26 | fogus | It has objects all over the place ;) |
| 08:28 | fliebel | like? |
| 08:29 | fogus | Do you mind rephrasing the question? Do you mean to ask why it's not object-oriented? |
| 08:29 | fliebel | You mean because every seq is in fact a java class? |
| 08:29 | fliebel | yea, that is more or less what I mean |
| 08:31 | fliebel | I understand it's not good from the functional immutable point of view, but I guess it would make java interop a lot easier. |
| 08:33 | karmazilla | dot-syntax is simple, calls into java are wrapper free, and it's easy to implement interfaces with proxy |
| 08:33 | fogus | RH has talked about this in many places, so I probably would not do him justice in paraphrasing. However, the basic point is that traditional OO is not conducive to concurrent programming. |
| 08:34 | fogus | fliebel: What do you see as the hard points on interop? |
| 08:36 | fliebel | fogus: Nothing specific… It's just that for me it's a pain to work with those java libraries. And since Clojure has almost no stdlib on its own, for almost any non trivial task you would have to do some java stuff… |
| 08:39 | fogus | fliebel: Without knowing your problem-space it's tough to know how interop is failing you, but I do not agree that interop is required outside of toy problems. There are countless examples of very tough problems solved by Clojure core libs alone. |
| 08:41 | fliebel | for example, this simple command: Runtime.getRuntime().exec("ls") translates into (.exec (java.lang.Runtime/getRuntime) "ls") and then I still have to find out how to create a reader to get the output… |
| 08:42 | fogus | fliebel: Maybe I'm being dense, but I'm not sure how Clojure being OO helps in this case |
| 08:43 | fliebel | fogus: not in this case, but then I never tried to write a Clojure applet… |
| 08:43 | karmazilla | fliebel: there's shell-out in contrib |
| 08:44 | fogus | What he said ^^^^^^ |
| 08:45 | fliebel | karmazilla: I know... |
| 08:46 | chouser | I think Clojure not being object *oriented* is more about the idiomatic way to solve problems than it is about the lack of any particular feature. |
| 08:47 | fliebel | Okay, it might be a bad idea to go oo, but I do think java interop is a pain, at least for me it is. |
| 08:49 | karmazilla | "Runtime.getRuntime().exec("ls")" is more about Java inter-operating with C, isn't it? |
| 08:51 | karmazilla | so it's more like Java being a pain (and this pain leaking through in Clojure) than Java interop per se. |
| 08:53 | fliebel | karmazilla: that might be part of the problem... |
| 08:57 | fliebel | but why can't it be like ((java.lang.Runtime.getRuntime) exec "ls"), or whatever… just some more java-ish(without changing order and thinking about dot vs slash.) |
| 09:01 | fogus | fliebel: Clojure as a Lisp follows the prefix notation -- in the case of interop that function position is a method. It's a uniform syntax |
| 09:04 | Raynes | Clojure isn't supposed to be 'javaish'. |
| 09:04 | Raynes | It's quite a bit Clojureish. |
| 09:17 | murbank | Do chunked sequences make expressions no longer strictly lazy? So (take 5 (expensive-io-function-returning-seq)) might make more expensive io evaluations than strictly necessary? |
| 09:25 | chouser | murbank: possibly, but it's generally controlled by the seq-generator. |
| 09:25 | chouser | so if expensive-io-function-returning-seq knows it is expensive and laziness is important, it can simple return a non-chunked seq and all is well. |
| 09:48 | murbank | chouser: Are new "primitive" sequences chunked by default? |
| 09:49 | chouser | murbank: only a few are so far. seqs of vectors being the most notable. also 'range' |
| 09:51 | murbank | chouser: But the intention is that many more are to be added right? |
| 09:51 | chouser | I'm not sure. I wouldn't expect line-seq to go chuncked, for example. But I don't know of any specific plans one way or another. |
| 10:14 | fliebel | What is the correct way to send off some function for which I don't care about the return value? I guess it's something like an atom, agent, ref, whatever, but I don't really understand those. |
| 10:22 | chouser | fliebel: perhaps 'future' |
| 10:23 | rhickey | yes, future, just ignore its return |
| 10:25 | fliebel | thanks |
| 10:36 | rhickey | yay |
| 10:36 | stuartsierra | readme typo: missing colon after "To Run" |
| 10:39 | chouser | also in readme, under Futures "They are away" should be "a way" |
| 10:39 | stuartsierra | chouser: you mean changes.txt, right? |
| 10:40 | chouser | er. right. |
| 10:41 | stuartsierra | rhickey: mind if I fix up the formatting in changes.txt? Stuff like breaking lines at 70 characters. |
| 10:42 | rhickey | stuartsierra: no, go ahead, thanks |
| 10:42 | stuartsierra | ok |
| 10:48 | rhickey | stuartsierra: could you also add that add-watcher and remove-watcher are gone, but can be implemented in terms of add-watch and remove-watch? |
| 10:48 | stuartsierra | rhickey: sure |
| 10:48 | rhickey | thanks |
| 10:49 | chouser | Repl and Script are missing from Deprecated |
| 10:51 | stuartsierra | chouser: ok, will mention that too |
| 11:07 | stuartsierra | Can I associate a commit with multiple tickets? |
| 11:11 | chouser | I think so. Just list them all in the commit msg |
| 11:11 | stuartsierra | ok |
| 11:12 | stuartsierra | rhickey: done, #229 ready to test |
| 11:55 | efarrar | hello |
| 11:55 | rhickey | stuartsierra: your patch file seems to include some of my patches |
| 11:56 | stuartsierra | oh, drat, I patched from master, didn't I |
| 11:56 | rhickey | ah, yup |
| 11:56 | stuartsierra | ok, trying again... |
| 11:56 | rhickey | I've touched 1.1.x, so make sure you have the latest |
| 11:57 | stuartsierra | got ti |
| 11:57 | stuartsierra | got it |
| 11:58 | stuartsierra | rhickey: ok, new patch up |
| 12:04 | rhickey | stuartsierra: applied and pushed - thanks! |
| 12:04 | stuartsierra | You're welcome! |
| 12:41 | cemerick | stuartsierra: I must be missing something about the complexity of integrating JUnit <-> clojure.test. Isn't it just a matter of generating one JUnit testcase that straps up clojure.test? |
| 12:43 | stuartsierra | cemerick: If you only want a single pass/fail for all your Clojure tests, yes. |
| 12:44 | cemerick | oh, you're aiming for full correspondence in the resulting report |
| 12:45 | stuartsierra | Otherwise, what's the point? |
| 12:46 | cemerick | well, the OP in that thread was just looking to have the clojure tests invoked as part of the default test run. I didn't think proper correspondence was an objective. |
| 12:46 | stuartsierra | I suppose so. |
| 12:46 | chouser | I'm useing clojure.test inside a junit suite in clojure |
| 12:47 | stuartsierra | chouser: how? |
| 12:47 | chouser | top-level java file for the annotation stuff |
| 12:48 | chouser | then a macro that does gen-class for one junit test per clojue.test fn |
| 12:48 | stuartsierra | Ah, I see. |
| 12:48 | chouser | the reports aren't terribly pretty |
| 12:48 | chouser | I've been hoping to look at the new junit stuff for clojure.test |
| 12:48 | stuartsierra | It's in 1.1; haven't played with it much myself. |
| 12:48 | cemerick | I guess I have really low expectations for test reporting. :-) |
| 12:49 | jasapp | does anyone know if there is anything like CL's hyperspec-lookup for clojure? |
| 12:49 | the-kenny | jasapp: (doc fun) |
| 12:50 | stuartsierra | Not quite the same. |
| 12:50 | stuartsierra | There's a javadoc lookup function in contrib. |
| 12:51 | jasapp | I have the javadoc lookup, and it's nice |
| 12:51 | jasapp | I was just looking for something similar for clojure |
| 12:51 | stuartsierra | (doc f) gets you the same thing as the Clojure API docs, except for special forms. |
| 12:51 | clojurebot | Excuse me? |
| 12:52 | jasapp | ok |
| 12:52 | jasapp | I'm not sure why I didn't think of that |
| 12:52 | replaca | jasapp: find-doc also exists |
| 12:52 | replaca | when you don't know the exact form |
| 12:52 | cemerick | this is interesting: http://code.google.com/p/terrastore/ |
| 12:52 | replaca | *symbol name |
| 12:53 | replaca | rhickey: are you in channel? |
| 12:54 | rhickey | replaca: yup |
| 12:55 | replaca | rhickey: so I was thinking that since autodoc doesn't support branches yet, I could do a stopgap by putting the 1.1 doc up on tomfaulhaber.github.com/clojure and then we'd have poor man's branch support |
| 12:55 | replaca | how's that sound? |
| 12:56 | replaca | (not that master and 1.1 have diverged yet) :) |
| 12:58 | rhickey | replaca: the API doc was always advertised as being about the latest, I'm ok with that until we have branch support |
| 12:59 | rhickey | we can work on putting metadata for :introduced-in for 1.2+ |
| 12:59 | hiredman_ | I thought the api was always advertised as being about the release |
| 13:00 | replaca | rhickey: ok, cool. I'll relax about that then. I think I'm about a month away from branch support (I'm doing some cleanup and trying to turn autodoc into a library that others can use right now) |
| 13:00 | replaca | hiredman_: I'm not sure we made any declaration at all :) |
| 13:00 | chouser | replaca: I noticed that the namespace is in both the path and the fragment of the doc urls |
| 13:01 | rhickey | the clojure.org API page always said latest |
| 13:01 | replaca | chouser: I don't understand what you mean? |
| 13:01 | hiredman_ | ok |
| 13:01 | replaca | chouser: oh, yeah I do. Yeah, that's probably unnecessary |
| 13:02 | replaca | "for historical reasons" |
| 13:02 | replaca | :-0 |
| 13:02 | replaca | :) |
| 13:04 | replaca | rhickey: I should probably add some words to the top of the API page emphasizing that this documents the master branch |
| 13:06 | rhickey | used to say: "It is generated from the source and reflects the current SVN version." |
| 13:06 | replaca | I'll add similar verbiage for the moment |
| 13:14 | rowth | llastlog changes |
| 13:14 | rowth | gah, sorry |
| 13:19 | replaca | rhickey: how about :introduced-in and :modified-in so that we can reflect APIs that have changed reasonably (:modified-in could be a vector) |
| 13:21 | rhickey | replaca: they sound fine, if somewhat verbose |
| 13:22 | replaca | rhickey: yeah, I have no strong opinion on the names. whatever feels easiest to you when working on core.clj |
| 13:41 | bagucode | technomancy: ping |
| 13:55 | StartsWithK | gen-class will lift all constructors from the base class, is this feature of any use to any one? |
| 13:56 | hiredman_ | lift? |
| 13:56 | StartsWithK | copy contructor signatures to gen-classed class |
| 13:56 | technomancy | bagucode: pong |
| 13:57 | StartsWithK | i was doing a sketch for joint java-clojure compiler (like the one groovy has) so first step is to generate .java stubs for all gen-class classes |
| 13:57 | StartsWithK | then i would compile java side with them, remove stubs and recompile clojure part |
| 13:58 | StartsWithK | this way in the same compile module you can have java side using clojure generated classes and clojure depending on java side |
| 13:59 | StartsWithK | the problem is constructor lifting, i can't generate the stub if the base is still in .java file |
| 13:59 | hiredman_ | hmmm |
| 13:59 | StartsWithK | at least i can't generate correct constructors |
| 13:59 | bagucode | technomancy: hey. I just sent you a bunch of github noob messages :) I'm curious about some common practices and stuff. |
| 14:00 | technomancy | bagucode: this is a pretty good overview of how I like to keep feature work in a separate branch until it's ready: http://wiki.github.com/dchelimsky/rspec/topic-branches |
| 14:01 | hiredman_ | gen-class in generally is kind of distasteful, I'm not sure why it does the lifting, must be something to do with the init stuff on the clojure side |
| 14:01 | StartsWithK | so, maybe lifting could be removed in favore of explicit constructor declaration |
| 14:01 | StartsWithK | joint java -clojure compiler imho is bether option to have |
| 14:01 | technomancy | bagucode: thanks for the patches; I hope to have time to look at them soon. |
| 14:03 | StartsWithK | yes, and i think there were several reports of gen-classes class not working, it happened i think when lifted constructor clashed with custom declaration or something like that |
| 14:05 | chouser | Aren't the ctors are lifted so you can dynamically add functionality? |
| 14:05 | bagucode | technomancy: Thanks. I'll read up on that link. My master now is just the first change I did to compile.clj to support native code. I didn't want to touch that again until you had a look at it and maybe merged it to leiningen proper so I made a new branch for the generic os detection support and passing of jvm flags to a forked process. Guess I got that right then :) |
| 14:06 | chouser | StartsWithK: like :init and :post-init |
| 14:06 | technomancy | bagucode: sounds like a winner. |
| 14:06 | StartsWithK | chouser: i don't know why is it doing it, but, couldn't you have same effect with manual lifting |
| 14:06 | stuartsierra | Yes, the gen-class'd constructor needs to call init, set up state, etc. |
| 14:07 | StartsWithK | hmm |
| 14:08 | StartsWithK | but still, :constructor could be made explicit and mandatory in all cases |
| 14:08 | stuartsierra | That would be a nuisance. |
| 14:08 | StartsWithK | for what? |
| 14:08 | stuartsierra | Me. ;) |
| 14:08 | StartsWithK | i't looks like most gen-class is used to generate beans or similar things for servlets and such |
| 14:09 | StartsWithK | and they need default ctor to work |
| 14:10 | StartsWithK | if one could simply drop bunch of java scala and clojure file in same src/ dir and just complile them without any extra work on his part |
| 14:10 | StartsWithK | that would be a huge benefit for ide makers |
| 14:11 | stuartsierra | Not gonna happen any time soon. |
| 14:11 | StartsWithK | groovy can do that, and they now have joint java/scala/groovy compiler, scala has joint java/scala compiler |
| 14:11 | StartsWithK | only thing stoping clojure from this is ctor lifting |
| 14:12 | stuartsierra | Do they generate stub .java source? That's the part that sounds weird to me. |
| 14:12 | StartsWithK | stuartsierra: goovy generates stubs, scala generates bytecode |
| 14:12 | StartsWithK | r* |
| 14:12 | StartsWithK | my java/clojure compiler works like groovy implementation |
| 14:13 | StartsWithK | its a three stage compilation, but is fully automatic and transparent for the user |
| 14:13 | hiredman_ | I think the real issue is that clojure's compiler is same world and loads all the code it generates |
| 14:14 | stuartsierra | Yes, so you always have to compile Java code first. |
| 14:14 | StartsWithK | hiredman_: not a problem realy, only thing needed is to load .clj manualy, macroexpand while counting gen-class and gen-interface (deftype in new branc) as special forms |
| 14:14 | StartsWithK | then collect bodies of gen-class declarations |
| 14:15 | hiredman_ | StartsWithK: well then do that |
| 14:15 | hiredman_ | if it is such a not a problem |
| 14:15 | stuartsierra | But gen-class is a function - it can be called anywhere, any time. |
| 14:15 | StartsWithK | stuartsierra: yes, java must be compiled first |
| 14:15 | StartsWithK | its a macro, and it will not do anything if *compile-files* is not true |
| 14:16 | stuartsierra | But how can you do macroexpansion without evaluating code? |
| 14:17 | chouser | we have a dependency chain like this java -> clojure -> java -> C++ |
| 14:17 | chouser | is that what you're looking for? |
| 14:17 | StartsWithK | i can't, but i don't need to do much, most thing are simple ignored (like (new Foo) will never be called) |
| 14:18 | StartsWithK | chouser: something like that, but lets saj Foo.java will use Bar that is gen-classed, and Baz.java will use Bar, and you have them in the same lib |
| 14:18 | hiredman_ | if clojure's compiler did not try to load java classes it would be possible to compile clojure first |
| 14:19 | StartsWithK | joint compiler will resolve that without any problems |
| 14:19 | stuartsierra | But what you're proposing is not really a joint compiler, just running separate compilers in a particular order. |
| 14:19 | StartsWithK | well that is what joint compiler does |
| 14:20 | stuartsierra | I think a joint compiler would have to understand both Java and Clojure syntax, so it can resolve symbols in both languages. |
| 14:20 | StartsWithK | hiredman_: it can work, no code will be executed, only evaluated, but the problem is, you can't know ctor of a class that is not compiled jet, so stub can't be generated |
| 14:21 | StartsWithK | not realy, it only needs to provide all the classes from both laguages when they are doing there compile phase |
| 14:22 | StartsWithK | (in compiled form or as stubs) |
| 14:22 | chouser | wait, you're trying to make gen-class work on a class that doesn't exist yet? |
| 14:22 | chouser | I mean, extending a class that doesn't exist yet |
| 14:22 | StartsWithK | yes, yes |
| 14:22 | chouser | the ctor is the least of your problems. |
| 14:22 | StartsWithK | it will be compiled by the java compiler |
| 14:23 | StartsWithK | ctor is my only problem :) |
| 14:23 | chouser | gen-class generates a method for every public method of every class it's extending |
| 14:24 | StartsWithK | uff |
| 14:25 | StartsWithK | with the same signature as the base? |
| 14:26 | StartsWithK | then that is not the problem i think |
| 14:26 | StartsWithK | as all publics from base would be visible any way |
| 14:26 | StartsWithK | but ctors would not be lifted |
| 14:26 | chouser | not if base doesn't exist |
| 14:27 | chouser | how do you discover the public methods of a non-existant class? |
| 14:27 | chouser | conversly, why is the solution we're already using insufficient such that all this effort is required? |
| 14:27 | StartsWithK | i don't, but i dont care, it must be in class path, on it must be in javac stage compiled with other classes |
| 14:28 | StartsWithK | i only need to generate stub "public Foo extend Bar .." as a string and save it in .java file for javac consumation |
| 14:28 | StartsWithK | class* |
| 14:35 | StartsWithK | this is http://is.gd/5sFXc explanation of hov groovy will do it, process is simple and it works on clojure if stub that is generated dosn't lift any ctors from the base class when :constructors in not defined |
| 14:36 | chouser | if you have each module declare its dependencies, then there is no problem at all, things just get built in the right order. |
| 14:36 | stuartsierra | Mixed-language projects are hard enough *without* cyclical dependencies. |
| 14:36 | StartsWithK | sure, if you want to place Foo.java in one module bar.clj in another and Baz.java in third and do manula dependency resolvig that way |
| 14:37 | headius | http://weblogs.java.net/blog/forax/archive/2009/12/18/tailcall-anyone |
| 14:38 | StartsWithK | stuartsierra: yes, so maybe it could get easier with things like this |
| 14:38 | headius | should take you guys about 5 minutes to toss the extra bytecode in |
| 14:38 | stuarthalloway | groovy: undisputed champ for those who like cross-language cyclical dependencies :-) |
| 14:39 | StartsWithK | circular dependency can't be resolved in any language, so it will fail as usual |
| 14:39 | StartsWithK | joint compiler is not a wizzard |
| 14:40 | technomancy | headius: yow! what are the chances of that getting mainlined? |
| 14:40 | headius | I feel like there's a good chance |
| 14:40 | chouser | headius: how many -to-JVM-bytecode compilers do you have your fingers in? |
| 14:40 | headius | given the pushback to late 2010 |
| 14:40 | technomancy | talking with John Rose at JRubyconf made me think odds weren't good, but that seemed to be only due to a lack of manpower. if the code's there and working... |
| 14:40 | headius | chouser: um...three or four of my own making, is that what you mean? |
| 14:40 | headius | technomancy: exactly |
| 14:41 | chouser | headius: heh. yeah. |
| 14:41 | headius | it wouldn't just be useful for FP either...we could eliminate pure overhead" stack frames from our call stacks with it |
| 14:41 | StartsWithK | stuarthalloway: scala suports joint java/scala compilation too |
| 14:41 | headius | reflection could emit wide opcodes to remove themselves from backtraces |
| 15:03 | somnium | is there a particular function/method to call that coverts '? to _QMARK_ |
| 15:05 | hiredman_ | somnium: it's in the compiler |
| 15:05 | chouser | ,(clojure.lang.Compiler/munge "true?") |
| 15:05 | clojurebot | "true_QMARK_" |
| 15:05 | somnium | munge! |
| 15:05 | somnium | awesome, thanks |
| 15:05 | hiredman_ | what does the "wide" bytecode instruction do? |
| 15:05 | stuartsierra | The most important function after "foo". |
| 15:14 | hiredman_ | clojurebot: unix? |
| 15:14 | clojurebot | Titim gan éirí ort. |
| 15:14 | hiredman_ | clojurebot: unix is<reply>it's a UNIX system! I know this! |
| 15:15 | hiredman_ | clojurebot: unix is <reply>it's a UNIX system! I know this! |
| 15:15 | clojurebot | Ik begrijp |
| 15:15 | clojurebot | This is a test. |
| 15:16 | scellus | ,(sort [5 4 3 2 1 Float/NaN 1 2 3 4 5]) |
| 15:16 | clojurebot | (1 2 3 4 5 NaN 1 2 3 4 5) |
| 15:17 | scellus | (not totally unheard of, python is similar) |
| 15:19 | doublindirection | how does clojure handle uncaught exceptions? they do not seem to "bubble up" to the repl |
| 15:19 | hiredman_ | I really don't understand Compiler.java |
| 15:20 | chouser | doublindirection: I think they do bubble up to the repl. what are you seeing? |
| 15:20 | hiredman_ | doublindirection: it depends on the context |
| 15:20 | hiredman_ | threads/agents/etc |
| 15:21 | doublindirection | nothing unless I add a (try catch) and printing it |
| 15:21 | doublindirection | but it is happening in a thread ... |
| 15:21 | the-kenny | doublindirection: Exceptions aren't thrown across threads |
| 15:21 | the-kenny | They pop up in the *inferior lisp* buffer if you use swank-clojure |
| 15:22 | the-kenny | Exceptions in the repl-thread pop up in the repl |
| 15:22 | hiredman_ | ,(future (throw (Exception.))) |
| 15:22 | clojurebot | #<core$future_call$reify__7719@1f87b38: :pending> |
| 15:22 | hiredman_ | … |
| 15:22 | the-kenny | ,(throw (Exception.) |
| 15:22 | clojurebot | EOF while reading |
| 15:22 | the-kenny | ,(throw (Exception.)) |
| 15:22 | clojurebot | java.lang.Exception |
| 15:22 | doublindirection | i looked in *the inferior lisp*, nothing there |
| 15:23 | doublindirection | but it has to do with the threading |
| 15:23 | chouser | right, exceptions aren't printed by default except in a repl thread. |
| 15:24 | chouser | so if you start your own thread and throw something there, you won't find out about it automatically. |
| 15:24 | chouser | depending on how you start the thread, clojure may have some handy ways for you to find out about the exception. |
| 15:25 | the-kenny | chouser: Huh? Exceptions thrown in some thread pop up in my *inferior lisp* |
| 15:25 | doublindirection | the thread is a jms onMessage handler, who knows what happens |
| 15:26 | chouser | the-kenny: I don't use emacs. But if you do (def x (future (throw (Exception.)))) you see that exception? |
| 15:26 | the-kenny | chouser: wait |
| 15:27 | doublindirection | exception does not show in my emacs |
| 15:27 | the-kenny | chouser: No, but (.start (Thread. #(throw (Exception.))) pops up in *inferior lisp* |
| 15:27 | the-kenny | Maybe futures are handled differently? |
| 15:28 | chouser | the-kenny: hm, I guess you're right. |
| 15:30 | hiredman_ | you can set an exception handler for threads |
| 15:30 | hiredman_ | possibly the execturor future uses sets one |
| 15:34 | Licenser_ | aloa |
| 15:38 | jweiss | i am looking for some macro examples that might help me - i write test automation software which requires me to support lots of different versions of our product. so my code (java) inevitably has lots of subclasses and overrides. i imagine the (a?) clojure way to do this is just patch the code with a macro? is there another way? |
| 15:39 | stuartsierra | jweiss: Dynamic binding. |
| 15:42 | jweiss | stuartsierra: what about the case in java where i just want to override one line of a method, so i abstract it out into a protected method and override that method? |
| 15:43 | defn | doug mcillroy patented macros |
| 15:43 | defn | he also could set file permissions with a magnet and a pin |
| 15:45 | stuartsierra | same thing, just override a function with a different binding |
| 15:46 | jweiss | stuartsierra: i was hoping not to have to give these functions names. since they wouldn't be their own function if it wasn't for the needing to override it |
| 15:47 | hiredman_ | defn: asm macros maybe |
| 15:47 | cp2 | defn: what a noob, real programmers use C-x M-c M-butterfly |
| 15:47 | jweiss | was thinking of a form like (deprecated x y z) where x y z are the things i'm changing |
| 15:47 | jweiss | or maybe deprecated is not the right name, but you get the idea |
| 15:47 | the-kenny | cp2: Hah... I love to hang out with people who understand this joke :D |
| 15:48 | cp2 | ^_^ |
| 15:48 | stuartsierra | jweiss: Well, you can't really change something unless you can refer to it... |
| 15:49 | jweiss | stuartsierra: yeah i meant i'd mark it my enclosing it in another form, and then a macro could replace the form with a new one |
| 15:49 | jweiss | s/my/by/ |
| 15:49 | stuartsierra | got to go |
| 15:50 | jweiss | k |
| 15:52 | defn | cp2: hehe check out: http://www.cs.dartmouth.edu/~sinclair/doug/ |
| 15:52 | defn | Doug McIlroy can address 8 terabytes of RAM with only 32 bits |
| 15:53 | defn | and RE: ASM macros: Doug McIlroy thinks asm is for sissies. |
| 15:54 | the-kenny | Emacs can save files where bits have three states: 0, 1 and something between. |
| 15:57 | cp2 | hehe defn |
| 16:00 | Licenser__ | has someone has made any experience with clojure and sockets? |
| 16:01 | alexyk | chouser: you da man |
| 16:02 | KirinDave_ | Licenser__: Like, raw sockets or just network stuff? |
| 16:02 | alexyk | the sort-by of the pairs finished in 300 secs, while sort with comparator in 5500 secs |
| 16:02 | Licenser__ | KirinDave_: 'just network stuff' so to say :P |
| 16:02 | jweiss | ,(doc source) |
| 16:02 | clojurebot | "clojure.contrib.repl-utils/source;[[n]]; Prints the source code for the given symbol, if it can find it. This requires that the symbol resolve to a Var defined in a namespace for which the .clj is in the classpath. Example: (source filter)" |
| 16:02 | KirinDave_ | Licenser__: The Peepcode is fairly good. |
| 16:03 | alexyk | apparently sort-by calls its by only once per element, effectively performing Schwarzian transform? |
| 16:03 | KirinDave_ | Licenser__: Also, I wrote an example bit of code that's smaller. Let me get the link for you. |
| 16:03 | Licenser__ | KirinDave_: there is one about clojure & network? |
| 16:03 | Licenser__ | All examples I found were so simple and trivialized that they were kind of useless or even wrongisch |
| 16:03 | hiredman_ | http://github.com/hiredman/clojurebot/blob/master/hiredman/http_server.clj |
| 16:03 | KirinDave_ | Licenser__: The peepcode stuff uses duck-streams to write a simple MUD. |
| 16:03 | hiredman_ | server socket |
| 16:04 | Licenser__ | hiredman_: yes it is pretty cool but the client part isn't :P |
| 16:04 | KirinDave_ | Licenser__: http://kirindave.tumblr.com/post/272596413/clojure-chat-server-1 |
| 16:04 | hiredman_ | Licenser__: huh? |
| 16:04 | chouser | alexyk: I'm surprised it was that much faster. |
| 16:05 | Licenser__ | well I find it at times very unnice to read from the socket, I've had the problem that line-seq's on a socket keep spitting out nil's and prevent the socket from closing |
| 16:05 | chouser | alexyk: sort-by *could* do a Schwarzian transform, but looking at it's definition I don't think it currently does. |
| 16:05 | hiredman_ | Licenser__: well they would |
| 16:06 | Licenser__ | yea I found that ugly .P |
| 16:06 | hiredman_ | anyway, http_server has only serversocket, no client stuff |
| 16:06 | alexyk | chouser: I also used it to sort by a function of the vector, and it was still very fast, hence I thought it only computes the by once, vs sort which apparently evaluates it for every comparison. But it's all speculation. |
| 16:06 | hiredman_ | which is why I said "huh?" |
| 16:06 | Licenser__ | I had so much fin defining a network connection by reducing over the seq of lines it spits out - I found it beautiful but it didn't worked as I wanted .P |
| 16:07 | hiredman_ | well, you are computer programmer, make it do what you want |
| 16:07 | Licenser__ | hiredman_: it's my plan :P just I learned that in clojure realms there are a lot people that have more experience so I see if someone knows tons of more stuff then me - especially when it gets all javaish like sockets :P |
| 16:08 | Licenser__ | it helps against triplicated code but if most peopel played with server sockets I'll just make something nice to work with the reading part ^^ |
| 16:08 | alexyk | I have a general question: so far, I keep all my clojure code as repl snippets, with def vars all around, reflecting a data mining session. Now if I want to place it into a maven dir structure and e.g. compile, it tries to eval each top level thing. Which is silly. How can I refactor things to (a) still allow easy copy-paste into repl in the same way (b) keep lein compile or mvn compile's dirty little hands off my def's? |
| 16:09 | Licenser__ | alexyk: create a mdef macro that does nothing when in marvin and works as def if not? |
| 16:10 | hiredman_ | alexyk: that is what def is |
| 16:10 | somnium` | Licenser__: marvin? |
| 16:10 | Licenser__ | I like the robot! |
| 16:10 | somnium` | :-) |
| 16:10 | hiredman_ | if you want to def something, and not have the code run until you call it, that is called a "function" |
| 16:10 | hiredman_ | there is a special "defn" form for that |
| 16:11 | chouser | alexyk: it's not silly, it's optimization. You're doing all your computation at compile time, saving the end-user from having to do any at all! |
| 16:11 | alexyk | ah, somnium! Q for you: I hate java.util.Date, can there be a flag in congomongo to convert all dates to joda-time upon receipt from mongo-java? |
| 16:11 | hiredman_ | chouser: nah, he will do it at compile time and at runtime |
| 16:12 | somnium` | alexyk: yeah, but you have to kind of hack on the driver |
| 16:12 | chouser | hiredman_: oh. I guess you're right. :-/ |
| 16:12 | alexyk | hiredman_: so if I replace a def by a defn, i.e. creating a parameterless fun, will it run as (fenvar) ? |
| 16:12 | alexyk | (funvar) I meant, kind of |
| 16:13 | hiredman_ | alexyk: have you gone all this time without writing functions? |
| 16:13 | somnium` | alexyk: i.e, proxy a Transformer and fire it into bytes |
| 16:13 | alexyk | hiredman_: a few, but I rarely need them so far |
| 16:13 | hiredman_ | well start writing |
| 16:13 | somnium` | alexyk: actually, could probably wrap it in a macro to make it stupid simple |
| 16:13 | alexyk | hiredman_: the question is, I have a series of interactive computations I check. |
| 16:13 | alexyk | I need to see and refer to them by names. |
| 16:14 | hiredman_ | write a function to check them |
| 16:14 | alexyk | think R. |
| 16:14 | somnium` | alexyk: Ill look into it |
| 16:14 | alexyk | it's a statistics session... |
| 16:15 | alexyk | somnium`: yeah, I was so aggravated by juDate/effin' Calendar so that I'm now mapping all juDate's into joda-time DateTimes upon fetch. |
| 16:15 | alexyk | which is clearly duplication |
| 16:15 | alexyk | mongo people said they don't want any external deps, hence no joda-time, but it's "easy to serialize any type of your own" |
| 16:15 | chouser | alexyk: I suppose you could have a macro that emits a 'def' but without a body if *compile-files* is ture. |
| 16:16 | alexyk | chouser: interesting |
| 16:16 | alexyk | somnium`: another issue: even if you fetch :only [:x], you get :_ns and :_id, which I always dissoc around fetch. |
| 16:17 | alexyk | is there a flag to supporess :_ns and :_id? |
| 16:17 | alexyk | suppress |
| 16:18 | alexyk | KirinDave_: how do you insert gists into tumblr? |
| 16:18 | the-kenny | alexyk: There's a "embed" function on the gist site |
| 16:18 | the-kenny | You can just copy the html and insert it into the post |
| 16:19 | somnium` | alexyk: mongo *always* adds those keys, need them for save/update |
| 16:19 | alexyk | nice |
| 16:19 | the-kenny | alexyk: But they don't show up without javascript |
| 16:19 | somnium` | alexyk: could patch :only to take them off I suppose, but cant stop mongo from sending them |
| 16:19 | alexyk | somnium`: well I often don't plan upon returning the stuff to mongo, saving a transform as a new collection |
| 16:20 | alexyk | somnium`: erally would like a flag :really-only or something, meaning no return to mongo |
| 16:20 | alexyk | and hence no ns/id |
| 16:20 | somnium` | :really-only, I like it |
| 16:20 | alexyk | :) |
| 16:22 | alexyk | somnium`: basically it would just drop ns/id, saving a (map #dissoc (fetch :coll :only [:x]) :_ns :_id) wrapper |
| 16:22 | hiredman_ | why not put the id stuff in metadata? |
| 16:22 | somnium` | hmm, maybe a :no-mongo-keys flag? |
| 16:23 | alexyk | hiredman_: interesting angle |
| 16:23 | alexyk | somnium`: sure... and also "mongo-as |
| 16:23 | alexyk | -metadata |
| 16:23 | alexyk | then :) for a choice |
| 16:23 | somnium` | hiredman_: no way to make metadata play nice with the .java driver :( |
| 16:23 | doublindirection | is there a way to specify "throws SomeException" with :gen-class :methods? |
| 16:24 | hiredman_ | somnium`: but you already have a clojure layer betweeb clojure and the java right? |
| 16:24 | somnium` | Im kind of hacking on a clojure version but am handicapped by my total unfamiliarity with nio |
| 16:25 | alexyk | I can see how, if you really want to pu |
| 16:25 | alexyk | |
| 16:25 | hiredman_ | the clojure layer can do a transform |
| 16:25 | alexyk | update mongo, you grab metadata back |
| 16:25 | somnium` | hiredman_: yes, but for performance it tries not to do much, just expose the api sanely |
| 16:25 | somnium` | but it would be possible |
| 16:25 | somnium` | alexyk: the fork is in your hands |
| 16:25 | alexyk | somnium`: after the PhD is in my hands next year :) |
| 16:26 | alexyk | then I can even juggle with forks |
| 16:26 | alexyk | for my clojure is hard at work with what is got... :) |
| 16:27 | somnium` | oh well, mongo is still kind of alpha until it gets concurrent reads anyway :) |
| 16:28 | somnium` | alexyk: at least Ill be able to claim congo's been used by academics once you get your degree |
| 16:29 | alexyk | I thought about sharing with Haskell, which got no mongo srivers yet. But it has for couchdb and tokyo cabinet, but without JSON and shell, I can't fathom those beasts no more. |
| 16:29 | somnium` | ? |
| 16:29 | Licenser__ | Hmm running in open doors here, but did everyone ever think about making a good documentation system for Clojure? |
| 16:29 | somnium` | how can you do anything with couchdb but not JSON? |
| 16:29 | alexyk | somnium`: after 6 months in scala, I added clojure, we'll see how it morphs. So far. clojure is best for data mining, and mongo is my store, with 100 gb of graph transforms. |
| 16:30 | Licenser__ | I mean the doc strings are nice for hints but in the long run they can't replace a real documentation |
| 16:30 | alexyk | somnium`: I mean, with a shell. I didn't look too deep into it, but I need a mongo-liek shell to inspect, not a curl client. |
| 16:30 | somnium` | ah |
| 16:34 | jweiss | can someone recommend a way to write a clojure function like (defn myoldfn [] (do (mythis) (mythat) (myother) ) and then write mynewfn so that it reads basically as "call myoldfn but instead of mythat do myanotherThing"? |
| 16:35 | jweiss | i'd like to keep the original function's steps written in order, in the fn, for readability |
| 16:35 | alexyk | somnium`: are there any shells for couchdb or tokyo cabinet comparable to mongo? |
| 16:35 | Chousuke | couldn't you parametrise myoldfn on mythat? :/ |
| 16:36 | jweiss | Chousuke: yeah, but then the steps are written out of order |
| 16:36 | jweiss | i want to keep it readable |
| 16:36 | Chousuke | out of order? |
| 16:36 | Chousuke | btw, the do in your example is redundant. |
| 16:36 | jweiss | it would execute in the right order or course, but mythat would be actually defined outside the function |
| 16:37 | Chousuke | defn bodies already have an implicit do |
| 16:37 | jweiss | Chousuke: sorry was just pseudocode |
| 16:37 | Chousuke | hmm |
| 16:37 | Chousuke | well, you can use binding I suppose |
| 16:37 | jweiss | Chousuke: i can't think of a way to do that and still keep the original fn as just a straightforward list of things to do |
| 16:38 | KirinDave_ | alexyk: "How do you insert gists into tumblr?" |
| 16:38 | KirinDave_ | alexyk: You use the raw HTML view. |
| 16:38 | KirinDave_ | It's very bad that they let you do it, tbh |
| 16:38 | KirinDave_ | But you can put any script tag in. |
| 16:38 | jweiss | oh wait Chousuke i think i get it |
| 16:38 | Chousuke | jweiss: aren't you overdoing it a bit though? :/ |
| 16:38 | alexyk | KirinDave_: I use markdown plugin for MarsEdit and Tumblr, usually |
| 16:38 | jweiss | (defn mynewfn (binding mythat (fn ... ))) |
| 16:38 | KirinDave_ | alexyk: I do not. |
| 16:39 | jweiss | Chousuke: yeah maybe |
| 16:39 | KirinDave_ | alexyk: I just use the web interface (mostly the bookmarklet) for 90% of my stuff |
| 16:39 | Chousuke | jweiss: if the issue is with the order of defns, you can always declare a function first and define it later |
| 16:40 | jweiss | Chousuke: no that's not it, but in my domain i'm constantly sort of "patching" functions but i still need to keep the old ones around, and it gets totally unreadable |
| 16:40 | alexyk | somnium`: I tried googling for "couchdb shell"and only curl I see |
| 16:40 | jweiss | factoring out tiny bits into smaller fn's |
| 16:40 | alexyk | so a non-starter for me |
| 16:40 | Chousuke | jweiss: hm. |
| 16:40 | jweiss | was hoping macros or bindings could let me keep the original function looking basically the same |
| 16:41 | jweiss | without copy/pasting |
| 16:41 | KirinDave_ | So, is there documentation anywhere on the cont-m monad? |
| 16:41 | KirinDave_ | I really am having trouble understanding it. |
| 16:41 | KirinDave_ | And the base documentation is kinda sparse |
| 16:41 | Chousuke | jweiss: so you want a template for a function and then create functions based on replacing parts of that function? |
| 16:42 | jweiss | Chousuke: yep |
| 16:42 | Chousuke | jweiss: maybe you could make a function that takes a map of functions as a parameter. |
| 16:42 | jweiss | so somehow i need to mark the forms that need replacing |
| 16:42 | dysinger | KirinDave Jim Duey has some tutorials on it. |
| 16:42 | Chousuke | jweiss: and then just pass in different function maps to it. |
| 16:42 | Chousuke | yielding new functions. |
| 16:42 | KirinDave_ | dysinger: Could you point me to a link? |
| 16:42 | dysinger | http://intensivesystems.net/tutorials/cont_m.html |
| 16:43 | KirinDave_ | Damn |
| 16:43 | jweiss | Chousuke: but again, that still involves taking the template apart too, doesn't it? |
| 16:43 | KirinDave_ | I just cannot navigate that guy's site. |
| 16:43 | KirinDave_ | I keep going to it and failing to read it. |
| 16:43 | Chousuke | jweiss: well the "template" would become a function that takes the values from the map and does something with them |
| 16:44 | jweiss | Chousuke: yeah but i was hoping that my original unpatched template would remain intact. to do what you're saying, i'd have to refactor it |
| 16:44 | jweiss | and pull out all the parts that get overridden |
| 16:45 | jweiss | and put them into that map |
| 16:45 | Chousuke | yeah. |
| 16:45 | Chousuke | you can also make the "generic" parts into a macro |
| 16:46 | Chousuke | then your original function is just one expansion of that macro. |
| 16:47 | jweiss | Chousuke: hm, that might be ok, at least macroexpand should show me an easier to read fn |
| 16:48 | Chousuke | I can give only very general advice, but when writing a macro you're basically designing a new syntax for writing these functions (whatever they are) |
| 16:48 | Chousuke | so make the most out of it |
| 16:51 | somnium`` | alexyk: Im not too familiar with couch, Ive only used futon |
| 16:52 | jweiss | Chousuke: seems like i need the source fn here |
| 16:52 | alexyk | somnium``: is futon as convenient as mongo client? |
| 16:52 | somnium`` | alexyk: but Im sure there are people here who are quite knowledgeable |
| 16:53 | somnium`` | alexyk: its a web app, not really comparable I guess |
| 16:53 | alexyk | knowledgeable people: does couchdb have a shell where you can easily inspect data? |
| 16:53 | alexyk | :) |
| 16:55 | danlarkin | Greetings clojurecrats! I'm back with another connundrum: why do these following two expressions not behave the same? |
| 16:55 | danlarkin | ,(let [f #(compare (:x %1) (:x %2))] (= {{:x 1 :name "juan"} 1} (sorted-map-by f {:x 1 :name "dan"} 1))) |
| 16:55 | clojurebot | true |
| 16:55 | danlarkin | ,(let [f #(compare (:x %1) (:x %2))] (= (sorted-map-by f {:x 1 :name "dan"} 1) {{:x 1 :name "juan"} 1})) |
| 16:55 | clojurebot | false |
| 16:57 | hiredman | I wonder if clojars could have an rss feed |
| 16:58 | Chousuke | danlarkin: why does the first one return true... huh. weird. |
| 16:59 | hiredman | non-semetrical equality |
| 16:59 | hiredman | it happens |
| 16:59 | danlarkin | it shouldn't! (imo) |
| 16:59 | hiredman | correct |
| 17:01 | chouser | alexyk: I just put together a down-and-dirty, mutable-array-based schwarzian transform sort, and I can't get it to beat clojure's sort-by |
| 17:02 | danlarkin | can't figure out why = isn't commutative from a quick browse of the java code |
| 17:03 | chouser | alexyk: which is interesting because the keyfn I'm testing it on is the one I gave you, where it's creating a 2-element vector for every call. |
| 17:04 | Chousuke | danlarkin: did you check both sorted-map and the persistent map? |
| 17:04 | technomancy | is there a trick to creating a clojure map from a java.util.Map? |
| 17:04 | Chousuke | technomancy: (zipmap (keys themap) (vals themap)) perhaps? |
| 17:05 | Chousuke | maybe even just (into {} themap) |
| 17:05 | technomancy | Chousuke: oh wow; into works great |
| 17:05 | technomancy | thanks |
| 17:05 | chouser | I would have that that was sufficiently expensive for the transforming sort to win |
| 17:05 | technomancy | that'll clean things up nicely |
| 17:06 | alexyk | chouser: in my case, vectors are really vectors of pairs, and I sort by e.g. sum of the second elements. E.g. [["bob [[1 1] [2 3] [3 2] [4 2]]] ["alice [[0 2][3 2][5 5]]] ...] |
| 17:07 | danlarkin | Chousuke: well PersistentTreeMap doesn't implement equiv or equals, so that'd fall back to APersistentMap |
| 17:07 | hiredman | fyi Properties implement java.util.Map |
| 17:07 | alexyk | hence sort-by, blazing fast on such 3.5 million pairs, is just: (sort-by (fn [[k v]] [(- (apply + (map second v))) k]) sper-days) |
| 17:08 | alexyk | chouser: following your trick |
| 17:09 | danlarkin | Chousuke: and clojure.core/= uses clojure.lang.Util/equiv for comparison, which uses IPersistentCollection.equiv |
| 17:09 | danlarkin | and that's where I lose it |
| 17:09 | alexyk | I was really surprised by speed, unless the map/fn is computed only once |
| 17:11 | hiredman | I think you are following the wrong direction |
| 17:11 | hiredman | I would check the equiv on sorted maps |
| 17:12 | danlarkin | but it's when the non-sorted map comes first that = is wrong |
| 17:13 | somnium`` | alexyk: what is the average num of keys in the maps youre crunching? |
| 17:13 | somnium`` | alexyk: the ones coming from the db I mean |
| 17:14 | hiredman | danlarkin: but sorted-map was added later so it's equivilance semantics are more likely to need some adjusting |
| 17:14 | alexyk | somnium``: from 1 to 30,000 currently |
| 17:14 | alexyk | each element, 3-10 million elements per coll |
| 17:14 | alexyk | brb |
| 17:15 | hiredman | huh |
| 17:15 | hiredman | ~def sorted-map |
| 17:16 | somnium`` | alexyk: egads, youre storing objects with 30,000 keys? |
| 17:16 | hiredman | hmmm |
| 17:18 | danlarkin | the counts don't even have to be the same: |
| 17:18 | danlarkin | ,(let [f #(compare (:x %1) (:x %2))] (= {{:x 1 :name "juan"} 1} (sorted-map-by f {:x 1} 1))) |
| 17:18 | clojurebot | true |
| 17:19 | chouser | ,(map first (sorted-map-by #(compare (:x %1) (:x %2)) {:x 1 :name "dan"} 1)) |
| 17:19 | clojurebot | ({:x 1, :name "dan"}) |
| 17:19 | chouser | ,(map first (sorted-map-by #(compare (:x %1) (:x %2)) {:x 1 :name "dan"} 1 2 3 4 5)) |
| 17:19 | clojurebot | (2 {:x 1, :name "dan"}) |
| 17:19 | chouser | oh, wait. |
| 17:19 | somnium`` | is there a summary of performance characteristics for ArrayMap vs. StructMap vs. HashMap vs. DynamicType anywhere+ (creation, look-up, etc.) ? |
| 17:19 | chouser | sorry, I was off the tracks there. |
| 17:21 | chouser | ah, there it is. |
| 17:21 | danlarkin | right, so I think the problem must live in APersistentMap: |
| 17:21 | danlarkin | ,(let [f #(compare (:x %1) (:x %2))] (.equiv {{:x 1 :name "juan"} 1} (sorted-map-by f {:x 1} 1))) |
| 17:21 | clojurebot | true |
| 17:21 | chouser | ,(get (sorted-map-by #(compare (:x %1) (:x %2)) {:x 1 :name "dan"}) {:x 1 :name "anything at all"}) |
| 17:21 | clojurebot | java.lang.IllegalArgumentException: No value supplied for key: {:x 1, :name "dan"} |
| 17:22 | chouser | ,(get (sorted-map-by #(compare (:x %1) (:x %2)) {:x 1 :name "dan"} 1) {:x 1 :name "anything at all"}) |
| 17:22 | clojurebot | 1 |
| 17:22 | danlarkin | ah ha |
| 17:22 | chouser | sorted maps use the comparator to find the value |
| 17:23 | chouser | perhaps they should do a final equality check of the key before succeeding? |
| 17:23 | chouser | or perhaps not. I dunno. |
| 17:23 | danlarkin | well it seems like they ought to |
| 17:24 | danlarkin | at least it seems tome that the current behavior is wrong |
| 17:24 | chouser | well, this seems wrong too but has been ruled Not A Bug: |
| 17:24 | chouser | ,{:a 1 :a 2 :a 3} |
| 17:24 | clojurebot | {:a 1, :a 2, :a 3} |
| 17:25 | danlarkin | yeah but that's in such a corner case |
| 17:25 | chouser | using a comparator for sorted-map-by that claims two values are equal when they are not seems like a corner case too, doesn't it? |
| 17:26 | danlarkin | I don't want the comparator to be used for equality, just sorting :) |
| 17:26 | Chousuke | isn't the sorting ... right. |
| 17:26 | reify | what clojure-contrib branch is recommended for clojure 1.x ? |
| 17:27 | chouser | reify: master, I think. for now. :-) |
| 17:27 | reify | i get these errors when compiling clojure-contrib with a clojure-1.1.jar: java.lang.NoSuchMethodError: clojure.lang.RestFn: method <init>()V not found (PrettyWriter.clj:17) |
| 17:28 | chouser | reify: "ant clean" first |
| 17:29 | reify | i swore I did that, thanks, that worked |
| 17:30 | chouser | reify: that's my job: telling you what you already know. |
| 17:30 | chouser | :-) |
| 17:31 | danlarkin | so my workaround right now is to make sure the order to clojure.core/= always puts the sorted-map first... do you think this is worthy of escalating? (I do) |
| 17:32 | chouser | sure. I just wouldn't be shocked if the answer is "well, don't do that" |
| 17:32 | danlarkin | I hate those answers :( |
| 17:33 | alexyk | somnium``: sorry, each object has usually one key. The value may be a longish vector or submap, tho. |
| 17:34 | hiredman | ~RestFn |
| 17:34 | clojurebot | Gabh mo leithscéal? |
| 17:34 | hiredman | ~clojure.lang.RestFn |
| 17:34 | clojurebot | ant clean and rebuild contrib |
| 17:35 | somnium`` | alexyk: congo creates hash-maps by default, but would be pretty easy to add an array-map flag for smallish maps. |
| 17:37 | chouser | technomancy: is it too hard to make your comparator only return 0 when keys are equal? |
| 17:38 | chouser | except I've gotta run, so we can pretend that was rhetorical. :-) |
| 17:38 | danlarkin | chouser: I assume you meant me :) |
| 17:38 | somnium`` | does the reader decide between array-map/hash-map by just counting key-value pairs? |
| 17:38 | chouser | danlarkin: right! sorry! |
| 17:38 | chouser | technomancy: sorry! |
| 17:39 | chouser | somnium``: reader always uses array-map, I believe. assoc/dissoc count keys and switch formats appropriately. |
| 17:39 | chouser | uh. except I'm wrong. |
| 17:39 | somnium`` | hmm |
| 17:40 | somnium`` | ? :) |
| 17:41 | chouser | well, I do have to go. Ignore what I said. :-P |
| 17:48 | mabes | is there a way to require/use all of clojure/contrib? I would like to use (find-doc) on all of it... |
| 18:28 | joshua-choi | Hey, is there a better way to add an object x to the beginning of a vector v than (vec (cons v x))? |
| 18:29 | hiredman | I don't imagine so |
| 18:30 | hiredman | you could implement your own type of vector that allowed adding to the front some how |
| 18:31 | hiredman | for key 0 return x else return element key - 1 from vector v |
| 18:32 | joshua-choi | Well, I'm not sure I want to go that far |
| 18:32 | joshua-choi | I'm worried that with vec and cons, though, creating a sequence from a vector, and then a new vector from the sequence would be more inefficient than may be necessary |
| 18:32 | Chousuke | you could pester chouser to finish the finger tree implementation and make a deque :P |
| 18:32 | hiredman | vectors were not designed with effecient adding tothe front in mind |
| 18:33 | joshua-choi | Yeah...maybe I should try to change my logic so I don't have to add to a vector's beginning, ugh |
| 18:34 | chouser | there's a PersistentQueue if you just want to always add to the right and take from the left. |
| 18:34 | joshua-choi | In clojure.core? |
| 18:34 | hiredman | ,(conj clojure.lang.PersistentQueue/EMPTY 1) |
| 18:34 | clojurebot | (1) |
| 18:34 | hiredman | ,(conj clojure.lang.PersistentQueue/EMPTY 1 2) |
| 18:34 | clojurebot | (1 2) |
| 18:35 | hiredman | ,(peak (conj clojure.lang.PersistentQueue/EMPTY 1 2)) |
| 18:35 | clojurebot | java.lang.Exception: Unable to resolve symbol: peak in this context |
| 18:35 | hiredman | ,(peek (conj clojure.lang.PersistentQueue/EMPTY 1 2)) |
| 18:35 | clojurebot | 1 |
| 18:35 | joshua-choi | I had no idea that this data structure existed |
| 18:35 | Chousuke | it's not very well documented :/ |
| 18:36 | hiredman | I think rhickey has some (evil?) mastermind plans for queues |
| 18:39 | joshua-choi | Ah, I just came up with a way to avoid adding to a vector's beginning; I guess that's best |
| 18:39 | joshua-choi | I've got another question though |
| 18:39 | joshua-choi | According to http://gnuvince.wordpress.com/2009/05/11/clojure-performance-tips, using destructuring in let (and so, probably fn too) is pretty slow |
| 18:39 | joshua-choi | That post was from earlier this year; is it still the case? |
| 18:40 | joshua-choi | Should I avoid destructuring lets in loops, etc? |
| 18:42 | the-kenny | joshua-choi: Only if you have a real bottleneck at this point in your code |
| 18:42 | danlarkin | joshua-choi: measure and THEN optimize :) |
| 18:42 | the-kenny | first: write it beautiful, if it's to slow, write it faster |
| 18:42 | the-kenny | s/to/too/ |
| 18:44 | joshua-choi | Yeah, that makes sense |
| 18:44 | joshua-choi | I have no idea have to measure though |
| 18:44 | joshua-choi | I'm not experienced with profiling Clojure, or anything for that matter |
| 18:45 | hiredman | it's a complex macro |
| 18:45 | the-kenny | joshua-choi: Just write your code.. if you don't notice that the code is too slow, there's no need to change the code for more speed |
| 18:49 | ubii | anyone using clojure for web development? |
| 18:50 | the-kenny | ubii: Yeah, some people here. Just ask your question :) |
| 18:51 | ubii | what framework(s) are most folks using and how production ready are they? |
| 18:51 | the-kenny | ubii: I think compojure is the most prominent framework here. http://clojars.org is running on it |
| 18:53 | mtm | chouser: you're to the point of picking a title and cover for the book? Sounds like you're almost done... (rubs hands gleefully in anticipation) |
| 18:54 | ubii | out of the frameworks that I look at so far, compojure looks the most interesting |
| 18:55 | tomoj | compojure is changing currently I think? |
| 18:55 | ubii | in what way? |
| 18:56 | tomoj | being refactored I think |
| 18:56 | ubii | ah |
| 18:56 | tomoj | dunno how far away that stuff is from master |
| 18:57 | ubii | one thing that I am trying to get a better grasp on is the server side of things, such as how to best deploy multiple sites on a single server |
| 18:59 | tomoj | I guess that kind of thing is java's problem |
| 18:59 | ubii | as well, as which web/app server(s) to, in order to maximize scalability |
| 18:59 | ubii | understood |
| 18:59 | tomoj | I don't know much about that yet either |
| 18:59 | hiredman | you can always proxy requests via apache |
| 19:00 | tomoj | I asked before whether there is a need to run multiple instances of the application on a single server (like we have in ruby), and the answer was 'no' |
| 19:01 | tomoj | I guess because java can actually do threading |
| 19:01 | hiredman | yeah, there isn't, but it makes it easier |
| 19:01 | hiredman | makes it |
| 19:01 | tomoj | wait, what? |
| 19:01 | tomoj | that only sounds harder to me |
| 19:01 | hiredman | compojure has the run script right? for developement that launches with jetty? |
| 19:02 | hiredman | (it's been a while) |
| 19:02 | hiredman | so you do that once per site, each site gets a port, set up the forwarding in an apache config |
| 19:02 | ubii | if for example, say I have different sites, running on the same server, do each of them run under their own JVM? |
| 19:02 | hiredman | it's not perfect by along shot, but it is dead simple |
| 19:03 | tomoj | right, that sounds easy |
| 19:03 | tomoj | I meant how like with ruby we might proxy apache/nginx to multiple running copies of the application even on the same server |
| 19:03 | tomoj | only have to do one here, I think |
| 19:09 | ubii | just trying to get some idea of what type of memory resources each site might require, using something like compojure |
| 19:09 | hiredman | compojure has a google group |
| 19:12 | ubii | np, I can pop on #compojure and ask |
| 19:14 | ubii | was just trying to get a feel for what most folks were using and how to best setup multiple sites up on a single server |
| 19:14 | ubii | thx |
| 19:55 | defn | how do you get a coll you turned into a transient back? |
| 19:55 | hiredman | (doc persistent!) |
| 19:55 | clojurebot | "([coll]); Returns a new, persistent version of the transient collection, in constant time. The transient collection cannot be used after this call, any such use will throw an exception." |
| 19:56 | defn | awesome thanks |
| 19:58 | defn | what is [b] in clojure? |
| 19:58 | Chousuke | a vector of one element? |
| 19:58 | defn | ,(doc chunk) |
| 19:58 | clojurebot | "([b]); " |
| 19:58 | Chousuke | aha. :D |
| 19:58 | hiredman | yep |
| 19:58 | Chousuke | good documentation. don't ask me. |
| 19:59 | Chousuke | it means the function takes one argument, named b :P |
| 19:59 | Chousuke | whatever that is. |
| 19:59 | defn | bahaha |
| 19:59 | defn | goddamnit |
| 19:59 | hiredman | ,(alter-meta! #'chunk assoc :arglists _ |
| 19:59 | clojurebot | EOF while reading |
| 19:59 | hiredman | ,(alter-meta! #'chunk assoc :arglists _) |
| 19:59 | clojurebot | java.lang.Exception: Unable to resolve symbol: _ in this context |
| 19:59 | hiredman | ,(alter-meta! #'chunk assoc :arglists '_) |
| 19:59 | clojurebot | {:ns #<Namespace clojure.core>, :name chunk, :file "clojure/core.clj", :line 446, :arglists _} |
| 19:59 | hiredman | (doc chunk) |
| 19:59 | clojurebot | "_; " |
| 19:59 | defn | ah i see |
| 20:02 | defn | map and filter use the chunk stuff |
| 20:02 | defn | cool |
| 20:04 | ericlavigne | Just installed NetBeans+Enclojure but Clojure isn't one of the options for new project types. Have I configured wrong, or should I be creating a Java project and putting Clojure source in it? |
| 20:54 | devlinsf | Is is possible to get bug fixes in for 1.1? |
| 20:55 | hiredman | I would imagine so |
| 20:55 | devlinsf | I have a fix for 128 |
| 20:55 | devlinsf | just posted |
| 20:56 | devlinsf | Can someone review? |
| 21:18 | hiredman | // int WIDE = 196; // NOT VISITED |
| 21:18 | hiredman | :( |
| 21:21 | devlinsf | ??? |
| 21:22 | hiredman | WIDE is the bytecode the experimental jvm uses to annotate tail calls |
| 21:23 | hiredman | and WIDE is commented out in the source of Opcodes.java in the asm library |
| 21:27 | devlinsf | Oh |
| 21:28 | devlinsf | So no TCO? |
| 21:29 | hiredman | I don't know the asm lib too well |
| 21:32 | hiredman | uncommenting it and trying to use wide just gives me a NPE |
| 21:32 | devlinsf | Hmmm |
| 21:34 | alexyk | how do I take last N elements of a collection? |
| 21:35 | devlinsf | currently not supported |
| 21:35 | alexyk | grrr |
| 21:35 | devlinsf | I'd do this |
| 21:36 | devlinsf | (defn take-last [n coll] (drop (- (count coll) n) coll)) |
| 21:36 | devlinsf | Gonna talk about that fn for 1.2 |
| 21:36 | alexyk | nice |
| 21:36 | devlinsf | We'll see where it goes |
| 21:36 | hiredman | ,((comp first drop-while) (comp (parial = 6) count) (iterate rest (range 10))) |
| 21:36 | clojurebot | java.lang.Exception: Unable to resolve symbol: parial in this context |
| 21:36 | hiredman | ,((comp first drop-while) (comp (partial = 6) count) (iterate rest (range 10))) |
| 21:36 | clojurebot | (0 1 2 3 4 5 6 7 8 9) |
| 21:37 | hiredman | bleh |
| 21:37 | alexyk | may call it tail as well |
| 21:37 | hiredman | ,((comp first drop-while) (comp (partial not= 6) count) (iterate rest (range 10))) |
| 21:37 | clojurebot | (4 5 6 7 8 9) |
| 21:37 | devlinsf | Yeah, expect there already is drop-last |
| 21:37 | hiredman | ,((comp first drop-while) (comp (partial not= 6) count) (iterate rest (range 1000))) |
| 21:37 | clojurebot | (994 995 996 997 998 999) |
| 21:37 | devlinsf | maybe alias it as tail? |
| 21:37 | alexyk | and alias take as head |
| 21:38 | alexyk | unless it's taken |
| 21:38 | devlinsf | ~head |
| 21:38 | clojurebot | No entiendo |
| 21:38 | devlinsf | NOpe |
| 21:42 | defn | alexyk: you coulkd just reverse it |
| 21:42 | defn | could just* |
| 21:43 | alexyk | true too |
| 21:43 | defn | ,(take 10 (reverse (range 0 21))) |
| 21:43 | clojurebot | (20 19 18 17 16 15 14 13 12 11) |
| 21:43 | defn | i like reverse the most -- seems easiest to understand |
| 21:43 | defn | im not sure about its effect on performance, though |
| 21:43 | alexyk | defn: then reverse again |
| 21:44 | hiredman | also the worst O |
| 21:44 | devlinsf | hiredman: true |
| 21:44 | hiredman | clojurebot: the most horrible thing? |
| 21:44 | clojurebot | most horrible thing is http://tinyurl.com/b65o8e |
| 21:44 | alexyk | hiredman: yours is Greek to me :) |
| 21:45 | alexyk | what's comp first drop-while do? |
| 21:45 | devlinsf | (first (drop-while ... |
| 21:47 | alexyk | right, still it's puzzling. |
| 21:48 | defn | the loop seems ugly |
| 21:48 | defn | err, look ugly in *my* opinion |
| 21:48 | alexyk | how do you limit the size of output by clojure repl? |
| 21:48 | defn | looks* |
| 21:48 | defn | alexyk: good question, id be interested to know that |
| 21:48 | alexyk | trying to depuzzle hiredman's stuff from the tail produced a sea of numbers |
| 21:49 | jasapp | alexyk: do you mean *print-length*? |
| 21:49 | alexyk | ah |
| 21:49 | jasapp | (set! *print-length* 10) |
| 21:49 | hiredman | (iterate rest (range 3)) => ((0 1 2 ) (1 2) (2) () ...) |
| 21:49 | devlinsf | \me wants to slap the "lisp w/o parens" crowd |
| 21:50 | devlinsf | There |
| 21:50 | jasapp | I've always wondered how to do that |
| 21:50 | devlinsf | /me |
| 21:50 | jasapp | sweet |
| 21:51 | jasapp | heh |
| 21:51 | defn | jasapp: nice |
| 21:51 | defn | thanks |
| 21:51 | alexyk | hiredman: what's ...? I'm afraid for my repl |
| 21:52 | jasapp | it just prints ...'s |
| 21:52 | hiredman | it goes on forever |
| 21:52 | hiredman | hmmm |
| 21:52 | hiredman | actually |
| 21:52 | defn | clojurebot: sotto voce is <reply>shhhh! |
| 21:52 | clojurebot | Alles klar |
| 21:52 | hiredman | nuts, mine depends on count |
| 21:53 | hiredman | so mine is n*n'ish |
| 21:53 | alexyk | yeah, it's darn many numbers it generates |
| 21:53 | jasapp | I thought most structures held their count somewhere |
| 21:53 | hiredman | not seqs |
| 21:54 | defn | ,(doc ref-max-history) |
| 21:54 | clojurebot | "([ref] [ref n]); Gets the max-history of a ref, or sets it and returns the ref" |
| 21:59 | alexyk | hmm: |
| 21:59 | alexyk | .(doc take-last) |
| 21:59 | alexyk | ,(doc take-last) |
| 21:59 | clojurebot | "([n coll]); Returns a seq of the last n items in coll. Depending on the type of coll may be no better than linear time. For vectors, see also subvec." |
| 22:00 | devlinsf | Hmmm? |
| 22:00 | alexyk | rhickey beamed it from the future |
| 22:00 | alexyk | hot-loaded erlang-style into clojurebot by the firedman of 2012 :) |
| 22:01 | devlinsf | Still confused |
| 22:01 | alexyk | me too |
| 22:01 | jasapp | that makes three of us, at least |
| 22:02 | alexyk | I found it by trying to load devlinsf's take-last into the current ns, got confict with clojure.core/that |
| 22:02 | devlinsf | I could swear this wasn't there yesterday.... |
| 22:02 | devlinsf | Oh well |
| 22:02 | devlinsf | Musta made a mistake |
| 22:41 | joshua-choi | ,(syntax-quote conj) |
| 22:41 | clojurebot | java.lang.Exception: Unable to resolve symbol: syntax-quote in this context |
| 22:42 | joshua-choi | Is there a form for syntax quoting, like (quote x)? |
| 22:44 | hiredman | there maybe a dummy stubbed out in core, but syntax quote is currently a reader macro, so having it won't work like that |
| 22:45 | joshua-choi | I see |
| 22:46 | joshua-choi | But, I could do |
| 22:46 | joshua-choi | ,(first `(conj)) |
| 22:46 | clojurebot | clojure.core/conj |
| 22:46 | joshua-choi | but it looks messy |
| 22:47 | joshua-choi | Is there a better way? |
| 22:47 | hiredman | ,(resolve 'conj) |
| 22:47 | clojurebot | #'clojure.core/conj |
| 22:47 | joshua-choi | Excellent; would that work in macros? |
| 22:47 | hiredman | you could also just |
| 22:48 | hiredman | ,`conj |
| 22:48 | clojurebot | clojure.core/conj |
| 22:49 | joshua-choi | Well, it's in a function: it's an argument whose value (a symbol) needs to be resolved |
| 22:49 | hiredman | … |
| 22:49 | hiredman | actually resolve resolves to the var |
| 22:50 | hiredman | resolved or namespace qualified? |
| 22:50 | hiredman | resolve resolves, and ` namespace qualifies, not resolves |
| 22:50 | joshua-choi | Well, namespace qualified, but like syntax quoting—which implies sort of resolving, right? |
| 22:51 | hiredman | maybe "quasi-resolving" |
| 22:52 | joshua-choi | I need it in a function that looks like this: (f [name] [(keyword name) (something name)]) so that (f 'conj) -> [:conj 'clojure.core/conj] |
| 22:54 | hiredman | ,(ns-map *ns*) |
| 22:54 | clojurebot | {sorted-map #'clojure.core/sorted-map, read-line #'clojure.core/read-line, re-pattern #'clojure.core/re-pattern, keyword? #'clojure.core/keyword?, val #'clojure.core/val, ProcessBuilder java.lang.ProcessBuilder, chunked-seq? #'clojure.core/chunked-seq?, Enum java.lang.Enum, find-protocol-impl #'clojure.core/find-protocol-impl, SuppressWarnings java.lang.SuppressWarnings, *compile-path* #'clojure.core/*compile-path*, max-k |
| 22:54 | hiredman | hmmm |
| 22:55 | hiredman | are you sure you want the namespace qualified symbol and not the var? |
| 22:55 | joshua-choi | Well, the var would work too, come to think of it |
| 22:56 | joshua-choi | Yes, using var works! Excellent, thanks for the help |
| 22:56 | hiredman | ,(reduce #(conj %1 (keyword (name (key %2))) (val %2)) {} (ns-map *ns*)) |
| 22:56 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword |
| 22:57 | hiredman | ,(reduce #(conj %1 [(keyword (name (key %2))) (val %2)]) {} (ns-map *ns*)) |
| 22:57 | clojurebot | {:StackTraceElement java.lang.StackTraceElement, :unchecked-inc #'clojure.core/unchecked-inc, :ArithmeticException java.lang.ArithmeticException, :import #'clojure.core/import, :deliver #'clojure.core/deliver, :symbol #'clojure.core/symbol, :vals #'clojure.core/vals, :print-doc #'clojure.core/print-doc, :select-keys #'clojure.core/select-keys, :re-matcher #'clojure.core/re-matcher, :rand #'clojure.core/rand, :deref #'cloj |
| 22:57 | hiredman | anyway, resolve will get you the var |