2010-09-05
| 03:53 | LauJensen | Good morning all |
| 03:53 | Raynes | Morning. |
| 04:12 | LauJensen | bozhidar: What we were seeing last night, was probably a bug in Awesomes event reporting, as soon as I moved the program to Windows everything worked and the layout resized as expected |
| 04:13 | bozhidar | LauJensen: I wouldn't have thought of that |
| 04:13 | bozhidar | but it's nice to hear you figured it out |
| 04:13 | LauJensen | 'awesome' is a hack :| |
| 04:13 | bozhidar | awesome - the tiling WM I presume? |
| 04:14 | LauJensen | Yea |
| 04:14 | LauJensen | At least I assume its responsible for sending the event |
| 04:14 | bozhidar | I don't think so |
| 04:15 | bozhidar | I think that X handles this directly |
| 04:15 | bozhidar | but awesome might be consuming something that it shouldn't |
| 04:16 | bozhidar | but then again - this is just a guess, I am far from an X event handling expert :-) |
| 04:17 | LauJensen | I think if you read about the design goals of X, it wouldn't be a stretch to imagine that it outsources event handling |
| 04:17 | hiredman | I have heard of tiling window managers and swing not interacting well |
| 04:18 | LauJensen | This might be one such case |
| 04:35 | tnoborio | Hello all. |
| 04:36 | tnoborio | (File. _nil_ "fname") raise no exception, but why (File. nil "fname") raise exception "More than one matching method found"? |
| 04:36 | tnoborio | (def _nil_ nil) |
| 04:36 | tnoborio | I wonder this behavior. |
| 04:37 | LauJensen | ,(java.io.File. _nil_ "fname") |
| 04:37 | clojurebot | java.lang.Exception: Unable to resolve symbol: _nil_ in this context |
| 04:37 | tnoborio | ,(def _nil_ nil) |
| 04:37 | clojurebot | DENIED |
| 04:39 | tnoborio | Why not the same behavior? |
| 04:39 | tnoborio | (File. nil "file path"), (File. _nil_ "file path") |
| 04:40 | tnoborio | _nil_ is defined nil, or return of function. |
| 04:41 | LauJensen | Good question |
| 04:53 | LauJensen | Ive had this problem a couple of times now. I have a namespace, which when evalled in the REPL works as expected, but when compiled it throws an Illegal state exception saying spit is already defined in another namespace, which it isnt |
| 04:53 | LauJensen | Anybody tried that? |
| 05:03 | tnoborio | That's right, I tried code, |
| 05:05 | LauJensen | fixed, I had put a :use where a :require belonged :) |
| 05:05 | LauJensen | hiredman: Have you got an idea about tnoborios problem above? |
| 05:06 | tnoborio | I put gisthub. http://gist.github.com/565876 |
| 05:19 | tnoborio | I think Its related java.io.File have 2 constructor, File(String parent, String child) and File(File parent, String child), and parent allow null. |
| 05:35 | _ulises- | morning |
| 06:18 | fullets | b |
| 06:35 | bartj | converting this java code - IOUtils.copy(inputStream, writer); |
| 06:35 | bartj | to Clojure I do: (IOUtils/copy input-stream writer) |
| 06:36 | bartj | But, I am almost certain that there is no way I can get the contents of the writer back |
| 06:36 | bartj | because copy returns a void |
| 06:36 | fullets | (let [writer (new StringWriter)] (IOUtils/copy input-stream writer) (str writer)) ? |
| 06:38 | bartj | fullets, let me try that... |
| 06:40 | bartj | fullets, that works, thanks! |
| 06:41 | bartj | though, I thought that would not be possible, because Clojure is immutable |
| 06:42 | fullets | Clojure's variables/data-types are immutable, but Clojure doesn't make mutable Java types immutable. |
| 06:43 | fullets | ,(doto (new java.util.ArrayList) (.add "foo") (.add "bar")) |
| 06:43 | clojurebot | #<ArrayList [foo, bar]> |
| 06:48 | bartj | fullets, yeah thanks! |
| 06:48 | bartj | fullets, writing/converting Java code to Clojure is so un-intuitive (functionally) |
| 06:50 | Chousuke | you pretty much need to rethink the whole thing :P |
| 06:51 | Chousuke | you can translate java into clojure if you're in a hurry but the result won't be spectacularly beautiful :) |
| 06:53 | bartj | Chousuke, it is outright ugly :) |
| 06:56 | bartj | I also reckon I am doing something wrong, which makes it look ugly |
| 06:58 | raek | bartj: you might want to check out clojure.java.io: http://clojure.github.com/clojure/clojure.java.io-api.html |
| 06:58 | raek | it has a copy function |
| 06:58 | Chousuke | bartj: well if you're just writing "java in clojure" it won't look good no matter what you do :P |
| 06:59 | bartj | for eg, I will give an example below which I think is ugly and there must be a better way to do it: |
| 06:59 | bartj | statusCode = obj1.method1().method2().method3() -> this is in Java |
| 06:59 | bartj | and to convert it to Clojure, I do something like: |
| 06:59 | bartj | obj2 (.method1 obj1) |
| 06:59 | bartj | statusCode (.method2 obj2) |
| 07:00 | bartj | is there any better way to do the above |
| 07:00 | mrBliss | (.. obj1 method1 method2 method3) |
| 07:00 | Chousuke | I prefer (-> obj .method1 .method2 .method3) |
| 07:00 | bartj | Chousuke, that seems great! |
| 07:01 | bartj | mrBliss, thanks |
| 07:01 | Chousuke | (fewer parens than the java line :P) |
| 07:01 | bartj | haha |
| 07:02 | Chousuke | if the methods take args you can do (-> obj (.method args) .method2 ...) |
| 07:02 | raek | also, don't mix InputStreams/OutputStreams (which are byte-oriented) with Readers/Writers (which are character-oriented) |
| 07:02 | Chousuke | and you can also use clojure functions or macros in ->. |
| 07:03 | Chousuke | which is why I prefer it over .. |
| 07:04 | bartj | -> and ->> are the only macros that I know good enough to use frequently (apart from #_) |
| 07:04 | sexpbot | java.lang.Exception: Can't take value of a macro: #'clojure.core/and |
| 07:04 | Chousuke | bartj: I'm sure you're using defn, and, or and when pretty often too :) |
| 07:05 | bartj | ok maybe amongst the exotic(!) ones |
| 07:05 | Chousuke | fn is actually a macro too but that's a secret :P |
| 07:10 | bartj | I also have some "doto" in the code |
| 07:10 | bartj | is that preferable over "->" or "->>" |
| 07:11 | mrBliss | they're not interchangeable |
| 07:12 | mrBliss | ->(>) applies the next function to the result of the previous and doto applies every function to the first argument |
| 07:12 | sexpbot | java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$-GT- |
| 07:13 | Raynes | Be careful with those exceptions. They're collectible. |
| 07:15 | bartj | mrBliss, yes, thanks, I guess I was a bit over-zealous |
| 07:51 | Licenser | ->(doc some) |
| 07:51 | sexpbot | => ------------------------- clojure.core/some ([pred coll]) Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example thi... http://gist.github.com/565974 |
| 07:52 | Vinzent | Hello all. I need an advice about macros. How can I access parameters of function that defined in macros? |
| 07:54 | Vinzent | e.g. I have something like (defmacro defaction [name params] `(defn ~name ~params)) and need generate code to process or examine fn parameters |
| 08:11 | ssideris | Licenser: hello... I've tried running your swing example with the temperature conversions |
| 08:12 | ssideris | and it seems that you have changed the clj-swing api a bit since you wrote this, right? |
| 08:14 | ssideris | (i'm referring to the example at your blog) |
| 08:14 | ssideris | great work with clj-swing by the wa |
| 08:14 | ssideris | y |
| 08:16 | ssideris | I'd be interested to contribute some code for tables, but I'm still working on learning clojure |
| 09:31 | LauJensen | clojurebot: contribute is http://clojure.org/contributing |
| 09:31 | clojurebot | Ik begrijp |
| 09:31 | LauJensen | clojurebot: contribute is http://clojure.org/contributing |
| 09:31 | clojurebot | Ack. Ack. |
| 09:31 | LauJensen | clojurebot: contribute is http://clojure.org/contributing |
| 09:31 | clojurebot | 'Sea, mhuise. |
| 09:31 | LauJensen | clojurebot: contribute is http://clojure.org/contributing |
| 09:31 | clojurebot | In Ordnung |
| 09:31 | LauJensen | ssideris: see the link above |
| 09:37 | ssideris | thanks |
| 10:34 | Bahman | Hi all! |
| 10:35 | LauJensen | Bada... ehm, .. Hi Bahman :) |
| 10:37 | Bahman | LauJensen: Hey there :-) |
| 11:36 | _na_ka_na_ | hello, are :user/a & ::user/a the same ? |
| 11:37 | chouser | not always |
| 11:38 | chouser | ,::user/a |
| 11:38 | _na_ka_na_ | but if i define a key :user/a .. it gets looked up by ::user/a also |
| 11:38 | clojurebot | :user/a |
| 11:39 | _na_ka_na_ | ,{:a 10 :user/a 20 ::user/a 39} |
| 11:39 | clojurebot | Duplicate key: :user/a |
| 11:39 | chouser | ,(alias 'ccore 'clojure.core) |
| 11:39 | clojurebot | nil |
| 11:39 | chouser | ,::ccore/a |
| 11:39 | clojurebot | :clojure.core/a |
| 11:39 | chouser | ,:ccore/a |
| 11:39 | clojurebot | :ccore/a |
| 11:39 | _na_ka_na_ | ooh hmm subtle difference .. |
| 11:40 | chouser | the double-colon tells the reader to use namespace aliases to resolve the prefix part of the keyword |
| 11:40 | chouser | with a single colon, the prefix part is taken literally, without resolution. |
| 11:41 | kumarshantanu | if I execute (while true) on clojurebot, will it hang? |
| 11:41 | chouser | since 'user is the real name of a namespace, it resolves to itself and thus ::user/a and :user/a mean the same |
| 11:41 | kumarshantanu | afraid of running it in real |
| 11:41 | chouser | kumarshantanu: it should time out after a few seconds. |
| 11:42 | _na_ka_na_ | ,{:a 10 :ccore/a 20 ::ccore/a 39} |
| 11:42 | clojurebot | {:a 10, :ccore/a 20, :clojure.core/a 39} |
| 11:42 | _na_ka_na_ | cool thanks chouser |
| 11:44 | chouser | np |
| 12:04 | tnoborio | The question before, Does anyone have a idea? why raise exception http://gist.github.com/565876 |
| 12:05 | LauJensen | chouser: I'd love to hear your oppinion on tnoborio's problem |
| 12:06 | chouser | tnoborio: the first two File lines would fail at runtime |
| 12:07 | chouser | the third one fails at compile time because the compiler can be certain of the type of the first arg -- specifically, that it's nil |
| 12:10 | tnoborio | the first two File lines success, (File. _nil_ "fname") ; => #<File fname> |
| 12:10 | chouser | hmph. |
| 12:10 | chouser | ok, hang on a sec. |
| 12:10 | tnoborio | (File. (identity nil) "fname") ; => #<File fname> |
| 12:13 | chouser | my repl's broken at the moment. let me fix it and then I'll try to figure out what's going on |
| 12:16 | chouser | interesting. So File has two different ctors that take two args. |
| 12:16 | chouser | the difference is the type of the first arg: String or File |
| 12:17 | chouser | when you pass in nil, which should Clojure use? |
| 12:17 | LauJensen | ,(str nil) |
| 12:17 | tnoborio | I think the compiler need certain of the type, the first File line should be raise error. |
| 12:17 | clojurebot | "" |
| 12:18 | chouser | when you pass a literal nil (File. nil "fname"), the compiler (rightly, I think) complains that it doesn't know which to call. |
| 12:18 | chouser | when you pass something that will return nil at runtime, the compiler at compile time just emits some runtime reflection code. |
| 12:19 | chouser | then when that reflection code runs at runtime, it apparently chooses one of those two ctors without complaint -- but I still don't know which its calling or how it chooses. |
| 12:19 | chouser | tnoborio: I think you may be right, that it ought to complain at runtime in that case. |
| 12:22 | tnoborio | Thanks, understand. |
| 12:23 | Chousuke | I suppose you can't type-hint nil either? :P |
| 12:24 | notsonerdysunny | can I define my own equality function which would be used for comparison in a multi-method? |
| 12:25 | Chousuke | the dispatch function can be anything |
| 12:26 | notsonerdysunny | ,(defn mclass [s] |nil |
| 12:26 | clojurebot | notsonerdysunny: Gabh mo leithscéal? |
| 12:26 | notsonerdysunny | (reverse (loop [ret '() val s] |user> (mclass |
| 12:26 | notsonerdysunny | (if (coll? val) | "132213123") |
| 12:26 | notsonerdysunny | (recur (cons (class val) ret) (first val)) |(java.lang.String) |
| 12:26 | notsonerdysunny | (cons (class val) ret))))) |
| 12:26 | notsonerdysunny | sorry .. |
| 12:27 | notsonerdysunny | ,(defn mclass [s] (reverse (loop [ret '() val s] (if (coll? val) (recur (cons (class val) ret) (first val)) (cons (class val) ret))))) |
| 12:27 | clojurebot | notsonerdysunny: Huh? |
| 12:28 | tnoborio | Or the compiler accept (File. nil "fname") and it matche File(String, String) like (File. (identity nil) "fname"). |
| 12:31 | notsonerdysunny | chosuke .. oh right .. |
| 12:31 | Chousuke | hm |
| 12:32 | notsonerdysunny | ,((defn mclass [s] (reverse (loop [ret '() val s] (if (coll? val) (recur (cons (class val) ret) (first val)) (cons (class val) ret))))) #{'([{1 2}])}) |
| 12:32 | clojurebot | notsonerdysunny: Titim gan éirí ort. |
| 12:32 | chouser | hm. so at runtime, the reflection code runs the first method that matches. |
| 12:32 | Chousuke | notsonerdysunny: instead of using reverse and consing onto a list, you should use a vector as an accumulator instead. |
| 12:32 | chouser | it doesn't appear to make any attempt to discover if there's more than one that would work. |
| 12:33 | Chousuke | or (map (fn [x] (class (if (coll? x) (first x) x))) somecoll) :P |
| 12:39 | notsonerdysunny | Chousuke: my function would return (clojure.lang.PersistentHashSet clojure.lang.PersistentVector clojure.lang.PersistentList clojure.lang.PersistentArrayMap clojure.lang.MapEntry java.lang.Integer) |
| 12:41 | notsonerdysunny | Chousuke: while yours would return (clojure.lang.PersistentList) |
| 12:41 | notsonerdysunny | when the argument is #{['({1 2})]} |
| 12:43 | Chousuke | hmmh |
| 12:46 | Chousuke | oh well, you can still avoid the reverse by using a vector. |
| 12:47 | notsonerdysunny | yea you are right .. |
| 12:47 | Chousuke | the build-list-and-reverse is a CL idiom but it doesn't work in Clojure :) |
| 12:47 | tnoborio | In conclusion, I should understand that the rules should be one? |
| 12:48 | tnoborio | Sorry, bad english. |
| 12:53 | LauJensen | chouser: Judging from the fact that the resulting File object doesnt have a root path, the ctor call is equivalent to (File. "" "file"), so Im thinking nil gets a call from .toString |
| 12:54 | chouser | LauJensen: perhaps, but I think that would be dependant on the ctor itself. |
| 13:01 | edbond | enlive question: how to select ul > li, and li doesn't have class |
| 13:01 | edbond | "title"? |
| 13:03 | tnoborio | Japan time at 2am, good night. |
| 13:03 | edbond | answer: [:ul [:li (but :.title)]], cool |
| 13:10 | LauJensen | edbond: I think you left out the > ? |
| 13:27 | kumarshantanu | is there any short form for (if x x y) ? |
| 13:27 | jkkramer | kumarshantanu: (or x y) |
| 13:28 | kumarshantanu | jkkramer: omg, not sure how I missed that |
| 13:29 | jkkramer | :) |
| 13:40 | jcromartie | If map is lazy, then "chaining" maps together has the effect of only iterating over the "base" collection once, right? |
| 13:41 | LauJensen | right |
| 13:41 | LauJensen | I mean, there's quite possibly some heavy sharing between the collections, but technically you're right |
| 13:42 | jcromartie | that's a *very* cool thing |
| 13:42 | LauJensen | technically, its *ubercool* :) |
| 13:43 | jcromartie | that makes doing any number of maps, essentially, O(N) right? |
| 13:43 | jcromartie | not quite |
| 13:43 | jcromartie | but close enough |
| 13:43 | jcromartie | where N is the size of the collection |
| 13:43 | jcromartie | not the number of maps |
| 13:43 | LauJensen | Not sure, Big O isnt my strong suit |
| 13:49 | jcromartie | well in a really pointless microbenchmark, I have to map over 1 million integers 5 times to double the running times of 1 map over them |
| 13:51 | ssideris | hi, I'm struggling with namespaces a bit |
| 13:51 | ssideris | I'd like to use the Ellipse2D.Float class |
| 13:51 | ssideris | so I have (ns mynamespace (:import (java.awt.geom Ellipse2D))) |
| 13:52 | ssideris | and then I'm trying (Ellipse2D/Float. 10 10 100 100) |
| 13:52 | ssideris | which doesn't work |
| 13:52 | ssideris | it's a bit of an unusual one because it's a nested class |
| 14:00 | LauJensen | ssideris: nested classes are accessed with the $ operator, so outer$inner/method |
| 14:00 | ssideris | oh, thanks"! |
| 14:03 | ssideris | so should this work? (new Ellipse2D$Float 10.0 10.0 100.0 100.0) |
| 14:03 | LauJensen | is Float a class? |
| 14:03 | LauJensen | Or a Method? |
| 14:03 | KirinDave | LauJensen: There is a boxed float class called Float, right? |
| 14:03 | ssideris | this is a Ellipse2D.Float class |
| 14:03 | LauJensen | no idea. But if its a class then (Ellipse2D$Float. 10.0 10.0 ...) should work |
| 14:04 | ssideris | this does not refer to the java.lang.Float |
| 14:04 | ssideris | http://download.oracle.com/javase/6/docs/api/java/awt/geom/Ellipse2D.Float.html |
| 14:05 | ssideris | I import (java.awt.geom Ellipse2D) |
| 14:06 | ssideris | and (Ellipse2D$Float. 10.0 10.0 100.0 100.0) does not work |
| 14:07 | ssideris | it's a very silly way to organise things... but that's how awt is... |
| 14:08 | LauJensen | ,(java.awt.geom.Ellipse2D$Float.) |
| 14:08 | clojurebot | #<Float java.awt.geom.Ellipse2D$Float@0> |
| 14:09 | edbond | LauJensen: works without :>, gladly |
| 14:09 | ssideris | LauJensen: thanks, that works :-) |
| 14:10 | ssideris | it seems that if I don't qualify the name fully, it doesn't |
| 14:11 | LauJensen | ,(import '(java.awt.geom Ellipse2D$Float)) |
| 14:11 | clojurebot | java.awt.geom.Ellipse2D$Float |
| 14:11 | LauJensen | ,(Ellipse2D$Float.) |
| 14:11 | clojurebot | #<Float java.awt.geom.Ellipse2D$Float@0> |
| 14:11 | LauJensen | edbond: it will work, but it can leak |
| 14:11 | LauJensen | Thats the whole point of > |
| 14:13 | LauJensen | ssideris: Did you catch that last import? |
| 14:16 | ssideris | thanks |
| 14:17 | ssideris | as soon as I feel like I have a good grasp of namespaces, I think I'll sit down and write a tutorial about it |
| 14:17 | ssideris | explaining everything in huge detail |
| 14:18 | LauJensen | You have namespace problems as well ? |
| 14:19 | ssideris | i just find use/require/import a bit confusing |
| 14:19 | ssideris | and I think that the current documentation does cover all points |
| 14:19 | ssideris | but a "for dummies" article would be good |
| 14:21 | LauJensen | import is for java classes. use is like require, but it interns all the functions from the namespace your importing in to your current namespace. require does not intern, but supports the :as keyword, (:require something [name :as anothername]) so you can run (anothername/somefn) ... |
| 14:22 | ssideris | yes I have worked out all this by reading here and there and looking at examples |
| 14:23 | ssideris | but I didn't find all this covered in one place |
| 14:23 | ssideris | especially the :as syntax |
| 14:23 | ssideris | i remember looking at code in github, the official api reference, and the wikibooks clojure book to gather all the information i needed |
| 14:24 | LauJensen | ,(doc require) |
| 14:24 | clojurebot | "([& args]); Loads libs, skipping any that are already loaded. Each argument is either a libspec that identifies a lib, a prefix list that identifies multiple libs whose names share a common prefix, or a flag that modifies how all the identified libs are loaded. Use :require in the ns macro in preference to calling this directly. Libs A 'lib' is a named set of resources in classpath whose contents define a library of Cloju |
| 14:25 | LauJensen | try that in your own repl, there's a lot of info |
| 14:27 | ssideris | yes, I've seen this, but I think every case mentioned could benefit from a concrete examples... it would be particularly helpful for novices |
| 14:28 | LauJensen | Well, the last 2 lines are |
| 14:28 | LauJensen | Example : |
| 14:28 | LauJensen | (require '(clojure zip [set :as s])) |
| 14:28 | LauJensen | more complaints you need us to take care of tonight? :) |
| 14:29 | ssideris | look, this is not meant as ill-willed critisism, I greatly appreciate how helpful you guys are in the irc channel (and everywhere else) |
| 14:30 | LauJensen | I know, Im just yanking your chain a little :) |
| 14:30 | ssideris | I'm just saying that (possibly because I'm being a bit thick) I found namespaces a bit tricky to understand |
| 14:31 | ssideris | so as a way to give back, I think I'll try and write something about when I feel a bit more confident |
| 14:31 | LauJensen | No no, I didn't mean to write this off as being easy to grok, Im just saying that the specific info you needed was actually in the require doc-string. I don't know where you could have learned about the $ operator |
| 14:31 | ssideris | $ is actually mentioned in the java_interop documentation :-) |
| 14:34 | LauJensen | Well there you go then, Rich takes care of us |
| 14:40 | ssideris | in Rich we trust |
| 14:41 | LauJensen | Well, no, we review the commit stream :) |
| 14:44 | ssideris | haha |
| 14:50 | ataggart | what is the incantation needed for lein to pull the 1.2.0 compatible contrib jar? |
| 15:16 | kumarshantanu | I want to understand how does this work: (def x #(println "foo")) ((var x)) ((ref x)) ;; var and ref work, but atom doesn't |
| 15:17 | kumarshantanu | what's surprising here is, they don't need a deref @ |
| 15:20 | hiredman | in a time long ago vars and refs were the same thing |
| 15:21 | kumarshantanu | hiredman: I am intrigued why don't they need a deref |
| 15:22 | hiredman | because vars usually hold functions it is useful to have them implement IFn and just pass calls along to the object they hold |
| 15:23 | kumarshantanu | hiredman: ditto for ref? why not for atom? |
| 15:23 | hiredman | no |
| 15:23 | hiredman | as I side vars and refs used to be the same thing |
| 15:23 | hiredman | said |
| 15:24 | hiredman | refs just sort of kept that behaviour, I don't know that you can rely on it continuing to be there |
| 15:25 | hiredman | atoms where created fairly late, after the seperation had already occured so they didn't pickup that piece of left over code |
| 15:27 | kumarshantanu | even more curiously, ((var (var x))) and ((var (ref x))) don't work |
| 15:27 | hiredman | uh |
| 15:28 | kumarshantanu | but ((ref (var x))) and ((ref (ref x))) work fine |
| 15:28 | hiredman | clojurebot: special forms |
| 15:28 | clojurebot | Gabh mo leithscéal? |
| 15:28 | hiredman | clojurebot: jerk |
| 15:28 | clojurebot | I don't understand. |
| 15:28 | hiredman | clojure.org/special_forms |
| 15:28 | hiredman | read the docs before asking a million questions please |
| 15:32 | kumarshantanu | hiredman: okay, and thanks for the pointer |
| 15:33 | Chousuke | kumarshantanu: the ref and var operators look like they're related but they do completely different things :P |
| 15:34 | Chousuke | the way to create a var named foo holding value bar is... (def foo bar) |
| 15:38 | kumarshantanu | Chousuke: I think I am getting it now, but I was surprised in the beginning :) |
| 15:39 | hiredman | ref is function and var is a special form that the reader macro #' turns into |
| 15:41 | Chousuke | I had no idea that the redirection feature of refs was just a leftover though. |
| 15:43 | kumarshantanu | ref seems to be transparent while acting on functions -- ((ref (ref (ref x)))) works |
| 16:02 | LauJensen | hmm, no ring/ring-core has been there for quite some time |
| 16:05 | bobo_ | hm, any project that uses enlive? want to read some source to better understand how i should use it |
| 16:06 | LauJensen | bobo_: bestinclass.dk |
| 16:06 | bobo_ | ah! should have known :-) |
| 16:07 | LauJensen | There are 2 things you can check out. 1) the wordpress import, which uses the selectors, and 2) the site generator which uses templates |
| 16:07 | LauJensen | clojurebot: google github bestinclass.dk |
| 16:07 | clojurebot | First, out of 166 results is: |
| 16:07 | clojurebot | LauJensen's Profile - GitHub |
| 16:07 | clojurebot | http://github.com/LauJensen |
| 16:07 | LauJensen | well, close enough |
| 16:08 | bobo_ | think its mostly the templating i want to read up on now. so il check the site generator |
| 16:08 | LauJensen | k, I think the file is called templates.clj |
| 16:08 | bobo_ | yeh looks like it |
| 16:11 | seangrove | What's the easiest way to start generating charts with clojure? |
| 16:12 | seangrove | I've just lost ~1 hour messing around with the outdated dejcartes |
| 16:12 | bobo_ | think i saw a jfreechart wrapper somewhere |
| 16:13 | bobo_ | ah, that was dejcartes :-p |
| 16:13 | bobo_ | seangrove: incanter perhaps? |
| 16:14 | seangrove | heh, yeah, I'm wondering about just using incanter |
| 16:14 | seangrove | Sounds good, I'll give it a shot |
| 16:14 | seangrove | It just looks like it might take more than an hour to get something up and running |
| 16:14 | seangrove | Happy to give it a try though |
| 16:22 | LauJensen | seangrove: the easiest way is without a doubt Google Charts, close second is JFreeChart |
| 16:26 | ApeShot | every time I take a break from clojure for a few months, I come back and can't remember/figure out where and how everyone is (has to?) set up their project folders so that things will work. Is there a place in the documentation I am missing for how clojure searches and loads classes/clj files? |
| 16:26 | seangrove | What's the "hello world" of an incanter project setup with leinigen? |
| 16:27 | ApeShot | For instance, if I put a clj file which creates a namespace in the lib folder of a swank project, I can't (use 'x) it, but I can if I put the same file in src |
| 16:27 | ApeShot | Does lib only contain jars? |
| 16:27 | technomancy | ApeShot: there are no hard and fast rules, but the convention says that yes, every jar in the lib directory will be put on the classpath |
| 16:28 | technomancy | ApeShot: have you read the Leiningen tutorial? it should help you get through that stuff. |
| 16:28 | technomancy | clojurebot: leiningen tutorial? |
| 16:28 | clojurebot | paredit tutorial is http://p.hagelb.org/paredit-outline |
| 16:28 | technomancy | clojurebot: botsmack! |
| 16:28 | clojurebot | clojurebot evades successfully! |
| 16:28 | technomancy | ... |
| 16:29 | technomancy | clojurebot: leiningen tutorial is at http://github.com/technomancy/leiningen/blob/master/TUTORIAL.md |
| 16:29 | clojurebot | In Ordnung |
| 16:30 | ApeShot | technomancy: Thanks. This looks ultra helpful. |
| 16:30 | ApeShot | technomancy: I guess the source of this question is thus: I work on several projects, and each wants to use an sort of continuously evolving set of libraries. |
| 16:30 | technomancy | ApeShot: look for the "checkout dependencies" feature |
| 16:30 | seancorfield | lein new myproject; cd myproject; lein deps |
| 16:31 | technomancy | ApeShot: can't remember if it's in the tutorial or the readme, but it's designed for that use case |
| 16:31 | bobo_ | technomancy: is that documented somewhere? except for its existance |
| 16:31 | ApeShot | technomancy: ok |
| 16:31 | technomancy | bobo_: lightly-documented, I think |
| 16:31 | technomancy | but on the other hand, there's not a lot to it; it's easy to set up and should just work. |
| 16:32 | seancorfield | "If you create a directory called checkouts in your project root and symlink some other projects into it, Leiningen will allow you to hack on them in parallel. That means changes in the dependency will be visible in the main project without having to go through the whole install/switch-projects/deps/restart-swank cycle" |
| 16:32 | seancorfield | README > FAQ |
| 16:33 | ApeShot | seancorfield: So by this technique, I should create a "apeshotlib" project, even if I never hack on it directly. |
| 16:33 | ApeShot | And symlink it into checkouts |
| 16:34 | technomancy | ApeShot: right; in most cases you have one project that depends on all the others. |
| 16:34 | technomancy | if you don't, you can create a dummy project |
| 16:36 | thunk | Is there a way to get slime to track buffers' namespaces from the (ns ...) form? |
| 16:36 | technomancy | thunk: C-c M-p should do it |
| 16:37 | thunk | technomancy: Ahh, very nice. Thanks |
| 16:39 | technomancy | np |
| 16:47 | ApeShot | Ok, so I put the symlink to the library project in checkouts, but how to I (use '...) a library defined there? |
| 16:47 | ApeShot | I am not sure what path-thingy to specify in the use command (or require, etc) |
| 16:49 | technomancy | ApeShot: that depends on the library. for contrib's io namespace you would have (ns apeshotlib.core\n :use [clojure.contrib.io :only [reader writer]]) ;; etc. |
| 16:51 | ApeShot | Not quite what I mean - suppose I create the apeshot lib, and in it lives src/error.clj which creates an (ns error) |
| 16:51 | ApeShot | How do I refer to that namespace from within another project? |
| 16:51 | ApeShot | after I have symlinked apeshotlib in checkouts |
| 16:51 | technomancy | firstly it should be src/apeshot/error.clj |
| 16:52 | ApeShot | Yes, that was my next question |
| 16:52 | ApeShot | And then it should be (ns apeshot.error) |
| 16:52 | ApeShot | In the file itself? |
| 16:52 | technomancy | right |
| 16:52 | technomancy | and then if you have only a few functions you should put :use [apeshot.error :only [fn1 fn2 fn3]] in the ns form you're using it from |
| 16:53 | ApeShot | technomancy: I think I get it all now. |
| 16:53 | ApeShot | technomancy: thanks! |
| 16:53 | technomancy | if you've got more (or if you foresee adding more) you could do :require [apeshot.error :as error] instead; which means everything you use from that lib would have to be prefixed: error/fn1 error/fn2 etc |
| 16:53 | technomancy | sure |
| 16:54 | ApeShot | I guess all this project discipline pays off in the long run. |
| 16:54 | ApeShot | I am sort of used to just hacking, starting with a "scratch.py" or whatever. |
| 16:54 | ApeShot | And gradually building up what structure a project needs |
| 16:54 | ApeShot | I suppose I could do that here. |
| 16:55 | ApeShot | But then it would be hard to use SLIME to its fullest. |
| 17:07 | technomancy | Man, it's too bad Relevance isn't secretly working on an in-house Clojure web framework, huh? |
| 17:07 | LauJensen | technomancy: ? |
| 17:08 | technomancy | LauJensen: just a silly thread on the mailing list |
| 17:08 | technomancy | http://groups.google.com/group/clojure/browse_thread/thread/32c51ca7ebdbc154 |
| 17:08 | LauJensen | ah |
| 17:09 | ApeShot | Ok, so I've fixed up the library project so that, for isntance, error is located in src/apeshotlib/error.clj and it creates a namespace (ns 'apeshotlib.error). If I start swank in the project directory, I can, for instance, (use 'apeshotlib.error) |
| 17:09 | technomancy | ApeShot: no quote in (ns apeshotlib.error) |
| 17:09 | ApeShot | technomancy: right, type |
| 17:09 | ApeShot | typo. |
| 17:09 | ApeShot | Ok, so in another project, I create a checkouts folder, symlink the apeshotlib project directory, start swank |
| 17:09 | ApeShot | How do I access apeshotlib.error? |
| 17:10 | bobo_ | technomancy: al you know is that they dont admit that they are doing something secret! ;-) |
| 17:10 | ApeShot | (use 'apeshotlib.error) doesn't work, saying it can't find apeshotlib on the class path. |
| 17:10 | ApeShot | Do I symlink the lib project folder in checkouts, or do I symlink the apeshotlib folder under src? |
| 17:11 | technomancy | it should be a symlink of the project root |
| 17:11 | technomancy | bobo_: true! stu is a sneaky guy. |
| 17:12 | chouser | not even that -- we know they don't admit that their secret project is a web framework. This simply raises the question: what *is* their secret project? |
| 17:12 | bobo_ | oh! *plot thickens* |
| 17:12 | ApeShot | technomancy: that is how I have it now. |
| 17:12 | somnium | isn't the main unsolved problem in CS these days creating a web framework better than rails? |
| 17:12 | chouser | heh |
| 17:13 | technomancy | somnium: as long as we've solved naming things and cache expiry. |
| 17:13 | technomancy | naming things: just don't use *jure, and you'll be fine |
| 17:13 | technomancy | cache expiry: use memoize! it'll be simple. |
| 17:13 | technomancy | problems solved. next! |
| 17:14 | ApeShot | technomancy: do I have to do something with apeshotlib's project.clj file? |
| 17:15 | technomancy | ApeShot: shouldn't be necessary. what does lein classpath show in the top-level project? |
| 17:16 | technomancy | if apeshotlib/src isn't in there then it's not going to work. |
| 17:16 | technomancy | ApeShot: could it be a problem with relative symlinks? try an absolute one maybe? |
| 17:16 | ApeShot | It shows apeshotlib/src |
| 17:17 | ApeShot | So maybe it is the relative/absolute symlink thing |
| 17:17 | ApeShot | Or maybe swank-clojure-project isn't grabbing the classpath? |
| 17:17 | ApeShot | The emacs command `swank-clojure-project`, I mean. |
| 17:17 | technomancy | yeah, that wouldn't work |
| 17:17 | ApeShot | Ah |
| 17:18 | technomancy | checkout dependencies are a leiningen feature, not an Emacs feature |
| 17:18 | ApeShot | So what is the right way to start a slime session from a leinigan project? |
| 17:18 | technomancy | so you need to do "lein swank" + M-x slime-connect |
| 17:19 | ApeShot | lein swank is not a task, apparently? |
| 17:19 | bobo_ | ApeShot: you need :dev-dependencies [[swank-clojure "1.2.1"]]) |
| 17:20 | ApeShot | bobo_: thanks, just read that in the FAQ |
| 17:20 | bobo_ | (and then lein deps) |
| 17:20 | technomancy | or if you are on Leiningen 1.3, you can place the swank-clojure jar in ~/.lein/plugins to have it available for all projects |
| 17:21 | ApeShot | This is actually pretty sweet. |
| 17:22 | technomancy | yay \m/ |
| 17:22 | bobo_ | hm, is it only me who thinks it sounds nice to have a lein plugin to add other projects to a project? |
| 17:23 | bobo_ | ie, that symlinks and so on |
| 17:23 | bobo_ | except it isnt realy any so on |
| 17:23 | technomancy | bobo_: lein-search can add to project.clj |
| 17:24 | bobo_ | cool |
| 17:24 | ApeShot | Everything seems to be working now - thanks everyone. |
| 17:25 | technomancy | bobo_: actually if you open the pom inside a lein-created jar it will show the git repo and SHA1 from which the jar was created. |
| 17:26 | technomancy | you could totally use that to check stuff out into checkouts/ |
| 17:26 | bobo_ | intresting |
| 17:57 | seancorfield | technomancy: any thoughts on incorporating some of the more popular plugins directly into lein? |
| 17:57 | technomancy | seancorfield: yeah, lein-search may go into 1.4 |
| 17:58 | seancorfield | any thoughts about lein-run? |
| 17:58 | technomancy | also a candidate |
| 17:59 | technomancy | I think those might be the only generally-applicable ones |
| 17:59 | technomancy | possibly lein-multi, but 1.4 is probably too early for that |
| 17:59 | danlarkin | lein-awesome |
| 17:59 | technomancy | danlarkin: that's already built-in! |
| 17:59 | technomancy | no need for a plugin |
| 18:00 | danlarkin | touché! |
| 18:00 | seancorfield | hmm, i thought i had lein-run in my current test project but i don't and now i can't find it *sigh* time to google again |
| 18:01 | technomancy | seancorfield: upgrade to lein 1.3 and add it to ~/.lein/plugins |
| 18:02 | kumarshantanu | seancorfield: Lein-run 1.0.1-SNAPSHOT has a default alias too -- http://github.com/sids/lein-run |
| 18:02 | seancorfield | it doesn't create ~/.lein by default does it? |
| 18:03 | kumarshantanu | seancorfield: not sure abt ~/.lein |
| 18:04 | technomancy | seancorfield: no, that's all manual right now |
| 18:04 | technomancy | yet another planned 1.4 feature |
| 18:05 | seancorfield | 'k... mkdir -p ~/.lein/plugins and a few cp later i'm in business :) |
| 18:06 | seancorfield | i put robert/hooke in there too |
| 18:06 | technomancy | indispensible chap |
| 18:08 | seancorfield | if i have a task in {project}/leiningen, it doesn't show up in the basic lein list of tasks - is that right? |
| 18:08 | seancorfield | i can run the task and lein help mytask shows the docs from the task |
| 18:08 | technomancy | it should be src/leiningen/mytask.clj |
| 18:09 | seancorfield | yes, it is |
| 18:09 | technomancy | oh... this may have been fixed in the 1.3.1-SNAPSHOT |
| 18:09 | seancorfield | it's actually hello.clj (and it prints hello world) |
| 18:10 | seancorfield | so i can do: lein hello |
| 18:10 | seancorfield | and: lein help hello |
| 18:10 | technomancy | we had some issues with missing nses due to a bug in contrib's find-namespaces lib |
| 18:10 | seancorfield | ah, ok |
| 18:10 | seancorfield | so lein upgrade ? |
| 18:10 | technomancy | upgrade will only get you the latest stable |
| 18:10 | technomancy | you'll need to check it out and look at the build instructions at the bottom of the readme |
| 18:10 | technomancy | or wait a day or two, hopefully |
| 18:11 | seancorfield | oh, ok... i'll just wait |
| 18:11 | seancorfield | i have a big website launch this week so i shouldn't be spending as much time on clojure as i am right now :) |
| 18:11 | seancorfield | post launch, that'll be another matter |
| 18:11 | technomancy | cool |
| 18:12 | technomancy | actually it would be nice to get more help testing this since it's about to be released if you do have the time |
| 18:12 | seancorfield | 'k |
| 18:16 | technomancy | you guys too =) |
| 18:16 | technomancy | I mean, if you've got a moment |
| 18:17 | somnium | is it a sign of over-use of printf-debugging when you use this? (defmacro quietly [& body] `(do (with-out-str (do ~@body)) nil)) |
| 18:21 | technomancy | somnium: it could also be a sign of the fact that c.c.logging doesn't let you set log level at runtime. =\ |
| 18:22 | seancorfield | ok, pulled, built... now where do i put the 1.3.1 snapshot jar? |
| 18:23 | seancorfield | do i just update VERSION at the top of the lein shell script? |
| 18:23 | seancorfield | or is there some magic lein command now i have the new jar? |
| 18:26 | ataggart | technomancy: I'm about to upload a version of c.c.logging that does |
| 18:28 | ataggart | well it's not up yet :) |
| 18:29 | ataggart | and for some reason the generated docs are a mish-mash of old and new names |
| 18:33 | seancorfield | figured it out... copied it to my maven repo manually and then copied the new lein script to /usr/local/bin |
| 18:33 | seancorfield | and i seem to be in business |
| 18:33 | seancorfield | my hello task still doesn't show up in lein help tho' :) |
| 18:38 | seancorfield | i'll have to update my laptop to lein 1.3.1 as well today |
| 20:07 | ssideris | ,(String/format "%02d" 4) |
| 20:07 | clojurebot | java.lang.ClassCastException: java.lang.Integer cannot be cast to [Ljava.lang.Object; |
| 20:07 | ssideris | hm |
| 20:12 | dnolen | ,(String/format "%02d" (to-array [2])) |
| 20:12 | clojurebot | "02" |
| 20:12 | boojum | ,(format "%02d" 4) |
| 20:12 | clojurebot | "04" |
| 20:25 | dberg | (require 'clojure.contrib.str-utils) throws a file not found exception |
| 20:27 | dberg | I installed closure from ubuntu repo and followed the instructions to compile clojure-contrib |
| 20:28 | dberg | any steps I'm missing for clojure-repl to load str_utils? |
| 20:36 | dnolen | dberg: are you using clojure 1.2 ? |
| 20:36 | dberg | dnolen: no, the one in the repository is 1.0 |
| 20:36 | dberg | dnolen: should I remove it and install 1.2 instead? |
| 20:37 | dnolen | dberg: yeah, I would. In 1.2 you can just (require '[clojure.string :as string]) |
| 20:39 | dberg | dnolen: ok, cool, will do that. also noticed that although building clojure-contrib is successful there's an error in the beginning Unable to locate tools.jar. Expected to find it in /usr/lib/jvm/java-6-sun-1.6.0.20/lib/tools.jar |
| 20:39 | dberg | |
| 20:44 | dberg | dnolen: hmmm I didn't have jdk, installed, compiled clojure-contrib but no luck |
| 20:44 | dberg | dnolen: will try version 1.2 |
| 20:45 | dnolen | dberg: so you have the jdk installed now? |
| 20:46 | dberg | dnolen: yes |
| 20:47 | emh | why doesn't the following print multiple lines? |
| 20:47 | emh | (binding [clojure.pprint/*print-miser-width* 1] (pprint (range 10))) |
| 20:49 | emh | ah. *print-right-margin* does what I want |
| 21:00 | alpheus | What project uses defprotocol? I'd like to read some code. |
| 21:16 | chouser | alpheus: http://github.com/Chouser/finger-tree/blob/master/finger_tree.clj |
| 21:17 | alpheus | thank you |
| 21:18 | Raynes | chouser: Did you ever get a chance to look at those yourkit snapshots? |
| 21:58 | chouser | Raynes: I downloaded them and then realized I didn't have yourkit installed. |
| 21:58 | chouser | I may get to them tonight or tomorrow. |
| 21:58 | Raynes | chouser: Alright, thanks. :) |
| 22:53 | chouser | Raynes: this is tough |
| 22:53 | chouser | irclj is one of the namespaces you reload? |
| 22:57 | hugod | is it the permgen space that is growing? |
| 22:58 | chouser | there are many more objects of many types |
| 22:58 | chouser | not sure if that answers the question. |
| 22:58 | hugod | i see permgen growth if I :reload anything with a deftype/defprotocol |
| 22:58 | chouser | but it's not just Class objects that there are more of |
| 23:01 | hugod | presumably, all the "old" objects hang around until they get GC'd |
| 23:02 | chouser | yeah, but I don't know that they'd be included in yourkit's list of objects |
| 23:02 | chouser | I guess I should confirm that before making assumptions. |
| 23:02 | chouser | hm, I wonder if MongoDB is keep a list of Connectors. |
| 23:03 | chouser | ...perhaps if they're not closed? |
| 23:03 | hugod | force gc, reload, force gc, and see what the difference is? |
| 23:04 | chouser | I don't have the code. |
| 23:04 | _mst | jvisualvm lets you diff two memory dumps too, if that helps |
| 23:04 | Raynes | chouser: Irclj is the underlying IRC library. |
| 23:05 | chouser | I'm looking at diffs between snapshots that Raynes took with yourkit. |
| 23:05 | chouser | Raynes: do you have any mongodb connectors that you aren't closing? |
| 23:05 | Raynes | I don't know. I open the DB in core, but I never reload core. I'm not sure how that magic works. |
| 23:06 | Raynes | I can try disabling mongo completely and see what happens. |
| 23:07 | Raynes | But to answer your question specifically, I never close anything. I just mongo! the db in core and then use it in plugins. I'm not sure what all of that is doing under the hood. It's all very implicit and magical. |
| 23:08 | chouser | I barely understand what I'm looking at here, but it does appear that mongo has a hashmap of Connectors, and thats one of the objects you have more of after a reload |
| 23:08 | chouser | I doubt it accounts for all of the increase, though. |
| 23:09 | Raynes | I appreciate you taking a look, either way. |
| 23:09 | Raynes | I suck at profiling. |
| 23:11 | chouser | reference paths to things that there are more of, to see what roots may be hanging onto old values that you don't need. |
| 23:11 | chouser | but the scale of object allocation is hard to deal with. |
| 23:12 | Raynes | Taking out the mongo stuff has no effect. |
| 23:12 | chouser | after reload, you have 34 more array maps. But I don't know how to ask for the paths of any of those 34 from among the 3,180 array maps in total. |
| 23:13 | Raynes | Indeed. |
| 23:14 | Raynes | It's a seriously annoying bug. |
| 23:14 | chouser | well, I don't think this is leading anywhere. |
| 23:14 | Raynes | I wish I knew how long it's been doing this. I never monitored memory usage when I first added reloading, so it could have been doing this all along and I didn't know. |
| 23:15 | chouser | I'd recommend trying to reproduce on a much smaller code base. |
| 23:15 | chouser | yourkit does say these are "live objects", so manual gc shouldn't be required. |
| 23:16 | chouser | so try something simple, with maybe just one lib. snapshot, :reload, snapshot, compare. |
| 23:16 | chouser | if even a simple case shows the problem, it'll be easier to get it accepted as a clojure bug. |
| 23:16 | Raynes | Yeah. It seems with even a single plugin this happens. |
| 23:16 | chouser | if a simple case does NOT show the problem, start scaling up until you see it. |
| 23:16 | Raynes | Just on a smaller basis. |
| 23:18 | Raynes | I actually did a few tests to see if memory usage grew outside of sexpbot when libs were reloaded, but so far, I've not been able to nail anything down. I'll have to try some more difficult tests. |
| 23:18 | Raynes | It could very well be, and probably is a sexpbot bug. I'm just clueless as to what could possibly cause such dramatic memory increases. I'll hunt it down eventually. |
| 23:19 | Raynes | :> |
| 23:19 | Raynes | chouser: I appreciate the advice, and I'll keep you posted on my findings. Thanks a lot for checking those snapshots out. |
| 23:30 | chouser | you're reloading at a REPL, or via an irc command? |
| 23:46 | Raynes | chouser: The latter. |
| 23:48 | Raynes | chouser: If you want to check it out, the relevant function is reload-all! (disregard the bangs in some of the functions, I haven't bothered renaming them) in src/sexpbot/load.clj at http://github.com/Raynes/sexpbot. Any changes I've made since that last push in there should be minor and irrelevant. |
| 23:48 | Raynes | I'm taking off for a little while. |
| 23:48 | technomancy | seancorfield: sorry; had to take off there |
| 23:48 | technomancy | the answer is you don't have to do anything |
| 23:49 | technomancy | just use the lein script from bin/lein in your checkout |
| 23:53 | Bahman | Hi all! |