#clojure logs

2010-09-05

03:53LauJensenGood morning all
03:53RaynesMorning.
04:12LauJensenbozhidar: 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:13bozhidarLauJensen: I wouldn't have thought of that
04:13bozhidarbut it's nice to hear you figured it out
04:13LauJensen'awesome' is a hack :|
04:13bozhidarawesome - the tiling WM I presume?
04:14LauJensenYea
04:14LauJensenAt least I assume its responsible for sending the event
04:14bozhidarI don't think so
04:15bozhidarI think that X handles this directly
04:15bozhidarbut awesome might be consuming something that it shouldn't
04:16bozhidarbut then again - this is just a guess, I am far from an X event handling expert :-)
04:17LauJensenI think if you read about the design goals of X, it wouldn't be a stretch to imagine that it outsources event handling
04:17hiredmanI have heard of tiling window managers and swing not interacting well
04:18LauJensenThis might be one such case
04:35tnoborioHello all.
04:36tnoborio(File. _nil_ "fname") raise no exception, but why (File. nil "fname") raise exception "More than one matching method found"?
04:36tnoborio(def _nil_ nil)
04:36tnoborioI wonder this behavior.
04:37LauJensen,(java.io.File. _nil_ "fname")
04:37clojurebotjava.lang.Exception: Unable to resolve symbol: _nil_ in this context
04:37tnoborio,(def _nil_ nil)
04:37clojurebotDENIED
04:39tnoborioWhy not the same behavior?
04:39tnoborio(File. nil "file path"), (File. _nil_ "file path")
04:40tnoborio_nil_ is defined nil, or return of function.
04:41LauJensenGood question
04:53LauJensenIve 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:53LauJensenAnybody tried that?
05:03tnoborioThat's right, I tried code,
05:05LauJensenfixed, I had put a :use where a :require belonged :)
05:05LauJensenhiredman: Have you got an idea about tnoborios problem above?
05:06tnoborioI put gisthub. http://gist.github.com/565876
05:19tnoborioI 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:18fulletsb
06:35bartjconverting this java code - IOUtils.copy(inputStream, writer);
06:35bartjto Clojure I do: (IOUtils/copy input-stream writer)
06:36bartjBut, I am almost certain that there is no way I can get the contents of the writer back
06:36bartjbecause copy returns a void
06:36fullets(let [writer (new StringWriter)] (IOUtils/copy input-stream writer) (str writer)) ?
06:38bartjfullets, let me try that...
06:40bartjfullets, that works, thanks!
06:41bartjthough, I thought that would not be possible, because Clojure is immutable
06:42fulletsClojure's variables/data-types are immutable, but Clojure doesn't make mutable Java types immutable.
06:43fullets,(doto (new java.util.ArrayList) (.add "foo") (.add "bar"))
06:43clojurebot#<ArrayList [foo, bar]>
06:48bartjfullets, yeah thanks!
06:48bartjfullets, writing/converting Java code to Clojure is so un-intuitive (functionally)
06:50Chousukeyou pretty much need to rethink the whole thing :P
06:51Chousukeyou can translate java into clojure if you're in a hurry but the result won't be spectacularly beautiful :)
06:53bartjChousuke, it is outright ugly :)
06:56bartjI also reckon I am doing something wrong, which makes it look ugly
06:58raekbartj: you might want to check out clojure.java.io: http://clojure.github.com/clojure/clojure.java.io-api.html
06:58raekit has a copy function
06:58Chousukebartj: well if you're just writing "java in clojure" it won't look good no matter what you do :P
06:59bartjfor eg, I will give an example below which I think is ugly and there must be a better way to do it:
06:59bartjstatusCode = obj1.method1().method2().method3() -> this is in Java
06:59bartjand to convert it to Clojure, I do something like:
06:59bartjobj2 (.method1 obj1)
06:59bartjstatusCode (.method2 obj2)
07:00bartjis there any better way to do the above
07:00mrBliss(.. obj1 method1 method2 method3)
07:00ChousukeI prefer (-> obj .method1 .method2 .method3)
07:00bartjChousuke, that seems great!
07:01bartjmrBliss, thanks
07:01Chousuke(fewer parens than the java line :P)
07:01bartjhaha
07:02Chousukeif the methods take args you can do (-> obj (.method args) .method2 ...)
07:02raekalso, don't mix InputStreams/OutputStreams (which are byte-oriented) with Readers/Writers (which are character-oriented)
07:02Chousukeand you can also use clojure functions or macros in ->.
07:03Chousukewhich is why I prefer it over ..
07:04bartj-> and ->> are the only macros that I know good enough to use frequently (apart from #_)
07:04sexpbotjava.lang.Exception: Can't take value of a macro: #'clojure.core/and
07:04Chousukebartj: I'm sure you're using defn, and, or and when pretty often too :)
07:05bartjok maybe amongst the exotic(!) ones
07:05Chousukefn is actually a macro too but that's a secret :P
07:10bartjI also have some "doto" in the code
07:10bartjis that preferable over "->" or "->>"
07:11mrBlissthey're not interchangeable
07:12mrBliss->(>) applies the next function to the result of the previous and doto applies every function to the first argument
07:12sexpbotjava.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$-GT-
07:13RaynesBe careful with those exceptions. They're collectible.
07:15bartjmrBliss, yes, thanks, I guess I was a bit over-zealous
07:51Licenser->(doc some)
07:51sexpbot=> ------------------------- 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:52VinzentHello all. I need an advice about macros. How can I access parameters of function that defined in macros?
07:54Vinzente.g. I have something like (defmacro defaction [name params] `(defn ~name ~params)) and need generate code to process or examine fn parameters
08:11ssiderisLicenser: hello... I've tried running your swing example with the temperature conversions
08:12ssiderisand it seems that you have changed the clj-swing api a bit since you wrote this, right?
08:14ssideris(i'm referring to the example at your blog)
08:14ssiderisgreat work with clj-swing by the wa
08:14ssiderisy
08:16ssiderisI'd be interested to contribute some code for tables, but I'm still working on learning clojure
09:31LauJensenclojurebot: contribute is http://clojure.org/contributing
09:31clojurebotIk begrijp
09:31LauJensenclojurebot: contribute is http://clojure.org/contributing
09:31clojurebotAck. Ack.
09:31LauJensenclojurebot: contribute is http://clojure.org/contributing
09:31clojurebot'Sea, mhuise.
09:31LauJensenclojurebot: contribute is http://clojure.org/contributing
09:31clojurebotIn Ordnung
09:31LauJensenssideris: see the link above
09:37ssideristhanks
10:34BahmanHi all!
10:35LauJensenBada... ehm, .. Hi Bahman :)
10:37BahmanLauJensen: Hey there :-)
11:36_na_ka_na_hello, are :user/a & ::user/a the same ?
11:37chousernot always
11:38chouser,::user/a
11:38_na_ka_na_but if i define a key :user/a .. it gets looked up by ::user/a also
11:38clojurebot:user/a
11:39_na_ka_na_,{:a 10 :user/a 20 ::user/a 39}
11:39clojurebotDuplicate key: :user/a
11:39chouser,(alias 'ccore 'clojure.core)
11:39clojurebotnil
11:39chouser,::ccore/a
11:39clojurebot:clojure.core/a
11:39chouser,:ccore/a
11:39clojurebot:ccore/a
11:39_na_ka_na_ooh hmm subtle difference ..
11:40chouserthe double-colon tells the reader to use namespace aliases to resolve the prefix part of the keyword
11:40chouserwith a single colon, the prefix part is taken literally, without resolution.
11:41kumarshantanuif I execute (while true) on clojurebot, will it hang?
11:41chousersince 'user is the real name of a namespace, it resolves to itself and thus ::user/a and :user/a mean the same
11:41kumarshantanuafraid of running it in real
11:41chouserkumarshantanu: it should time out after a few seconds.
11:42_na_ka_na_,{:a 10 :ccore/a 20 ::ccore/a 39}
11:42clojurebot{:a 10, :ccore/a 20, :clojure.core/a 39}
11:42_na_ka_na_cool thanks chouser
11:44chousernp
12:04tnoborioThe question before, Does anyone have a idea? why raise exception http://gist.github.com/565876
12:05LauJensenchouser: I'd love to hear your oppinion on tnoborio's problem
12:06chousertnoborio: the first two File lines would fail at runtime
12:07chouserthe 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:10tnoboriothe first two File lines success, (File. _nil_ "fname") ; => #<File fname>
12:10chouserhmph.
12:10chouserok, hang on a sec.
12:10tnoborio(File. (identity nil) "fname") ; => #<File fname>
12:13chousermy repl's broken at the moment. let me fix it and then I'll try to figure out what's going on
12:16chouserinteresting. So File has two different ctors that take two args.
12:16chouserthe difference is the type of the first arg: String or File
12:17chouserwhen you pass in nil, which should Clojure use?
12:17LauJensen,(str nil)
12:17tnoborioI think the compiler need certain of the type, the first File line should be raise error.
12:17clojurebot""
12:18chouserwhen you pass a literal nil (File. nil "fname"), the compiler (rightly, I think) complains that it doesn't know which to call.
12:18chouserwhen you pass something that will return nil at runtime, the compiler at compile time just emits some runtime reflection code.
12:19chouserthen 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:19chousertnoborio: I think you may be right, that it ought to complain at runtime in that case.
12:22tnoborioThanks, understand.
12:23ChousukeI suppose you can't type-hint nil either? :P
12:24notsonerdysunnycan I define my own equality function which would be used for comparison in a multi-method?
12:25Chousukethe dispatch function can be anything
12:26notsonerdysunny,(defn mclass [s] |nil
12:26clojurebotnotsonerdysunny: Gabh mo leithscéal?
12:26notsonerdysunny (reverse (loop [ret '() val s] |user> (mclass
12:26notsonerdysunny (if (coll? val) | "132213123")
12:26notsonerdysunny (recur (cons (class val) ret) (first val)) |(java.lang.String)
12:26notsonerdysunny (cons (class val) ret)))))
12:26notsonerdysunnysorry ..
12:27notsonerdysunny,(defn mclass [s] (reverse (loop [ret '() val s] (if (coll? val) (recur (cons (class val) ret) (first val)) (cons (class val) ret)))))
12:27clojurebotnotsonerdysunny: Huh?
12:28tnoborioOr the compiler accept (File. nil "fname") and it matche File(String, String) like (File. (identity nil) "fname").
12:31notsonerdysunnychosuke .. oh right ..
12:31Chousukehm
12:32notsonerdysunny,((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:32clojurebotnotsonerdysunny: Titim gan éirí ort.
12:32chouserhm. so at runtime, the reflection code runs the first method that matches.
12:32Chousukenotsonerdysunny: instead of using reverse and consing onto a list, you should use a vector as an accumulator instead.
12:32chouserit doesn't appear to make any attempt to discover if there's more than one that would work.
12:33Chousukeor (map (fn [x] (class (if (coll? x) (first x) x))) somecoll) :P
12:39notsonerdysunnyChousuke: my function would return (clojure.lang.PersistentHashSet clojure.lang.PersistentVector clojure.lang.PersistentList clojure.lang.PersistentArrayMap clojure.lang.MapEntry java.lang.Integer)
12:41notsonerdysunnyChousuke: while yours would return (clojure.lang.PersistentList)
12:41notsonerdysunnywhen the argument is #{['({1 2})]}
12:43Chousukehmmh
12:46Chousukeoh well, you can still avoid the reverse by using a vector.
12:47notsonerdysunnyyea you are right ..
12:47Chousukethe build-list-and-reverse is a CL idiom but it doesn't work in Clojure :)
12:47tnoborioIn conclusion, I should understand that the rules should be one?
12:48tnoborioSorry, bad english.
12:53LauJensenchouser: 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:54chouserLauJensen: perhaps, but I think that would be dependant on the ctor itself.
13:01edbondenlive question: how to select ul > li, and li doesn't have class
13:01edbond "title"?
13:03tnoborioJapan time at 2am, good night.
13:03edbondanswer: [:ul [:li (but :.title)]], cool
13:10LauJensenedbond: I think you left out the > ?
13:27kumarshantanuis there any short form for (if x x y) ?
13:27jkkramerkumarshantanu: (or x y)
13:28kumarshantanujkkramer: omg, not sure how I missed that
13:29jkkramer:)
13:40jcromartieIf map is lazy, then "chaining" maps together has the effect of only iterating over the "base" collection once, right?
13:41LauJensenright
13:41LauJensenI mean, there's quite possibly some heavy sharing between the collections, but technically you're right
13:42jcromartiethat's a *very* cool thing
13:42LauJensentechnically, its *ubercool* :)
13:43jcromartiethat makes doing any number of maps, essentially, O(N) right?
13:43jcromartienot quite
13:43jcromartiebut close enough
13:43jcromartiewhere N is the size of the collection
13:43jcromartienot the number of maps
13:43LauJensenNot sure, Big O isnt my strong suit
13:49jcromartiewell 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:51ssiderishi, I'm struggling with namespaces a bit
13:51ssiderisI'd like to use the Ellipse2D.Float class
13:51ssiderisso I have (ns mynamespace (:import (java.awt.geom Ellipse2D)))
13:52ssiderisand then I'm trying (Ellipse2D/Float. 10 10 100 100)
13:52ssideriswhich doesn't work
13:52ssiderisit's a bit of an unusual one because it's a nested class
14:00LauJensenssideris: nested classes are accessed with the $ operator, so outer$inner/method
14:00ssiderisoh, thanks"!
14:03ssiderisso should this work? (new Ellipse2D$Float 10.0 10.0 100.0 100.0)
14:03LauJensenis Float a class?
14:03LauJensenOr a Method?
14:03KirinDaveLauJensen: There is a boxed float class called Float, right?
14:03ssideristhis is a Ellipse2D.Float class
14:03LauJensenno idea. But if its a class then (Ellipse2D$Float. 10.0 10.0 ...) should work
14:04ssideristhis does not refer to the java.lang.Float
14:04ssiderishttp://download.oracle.com/javase/6/docs/api/java/awt/geom/Ellipse2D.Float.html
14:05ssiderisI import (java.awt.geom Ellipse2D)
14:06ssiderisand (Ellipse2D$Float. 10.0 10.0 100.0 100.0) does not work
14:07ssiderisit's a very silly way to organise things... but that's how awt is...
14:08LauJensen,(java.awt.geom.Ellipse2D$Float.)
14:08clojurebot#<Float java.awt.geom.Ellipse2D$Float@0>
14:09edbondLauJensen: works without :>, gladly
14:09ssiderisLauJensen: thanks, that works :-)
14:10ssiderisit seems that if I don't qualify the name fully, it doesn't
14:11LauJensen,(import '(java.awt.geom Ellipse2D$Float))
14:11clojurebotjava.awt.geom.Ellipse2D$Float
14:11LauJensen,(Ellipse2D$Float.)
14:11clojurebot#<Float java.awt.geom.Ellipse2D$Float@0>
14:11LauJensenedbond: it will work, but it can leak
14:11LauJensenThats the whole point of >
14:13LauJensenssideris: Did you catch that last import?
14:16ssideristhanks
14:17ssiderisas 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:17ssiderisexplaining everything in huge detail
14:18LauJensenYou have namespace problems as well ?
14:19ssiderisi just find use/require/import a bit confusing
14:19ssiderisand I think that the current documentation does cover all points
14:19ssiderisbut a "for dummies" article would be good
14:21LauJensenimport 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:22ssiderisyes I have worked out all this by reading here and there and looking at examples
14:23ssiderisbut I didn't find all this covered in one place
14:23ssiderisespecially the :as syntax
14:23ssiderisi remember looking at code in github, the official api reference, and the wikibooks clojure book to gather all the information i needed
14:24LauJensen,(doc require)
14:24clojurebot"([& 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:25LauJensentry that in your own repl, there's a lot of info
14:27ssiderisyes, I've seen this, but I think every case mentioned could benefit from a concrete examples... it would be particularly helpful for novices
14:28LauJensenWell, the last 2 lines are
14:28LauJensenExample :
14:28LauJensen (require '(clojure zip [set :as s]))
14:28LauJensenmore complaints you need us to take care of tonight? :)
14:29ssiderislook, this is not meant as ill-willed critisism, I greatly appreciate how helpful you guys are in the irc channel (and everywhere else)
14:30LauJensenI know, Im just yanking your chain a little :)
14:30ssiderisI'm just saying that (possibly because I'm being a bit thick) I found namespaces a bit tricky to understand
14:31ssiderisso as a way to give back, I think I'll try and write something about when I feel a bit more confident
14:31LauJensenNo 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:31ssideris$ is actually mentioned in the java_interop documentation :-)
14:34LauJensenWell there you go then, Rich takes care of us
14:40ssiderisin Rich we trust
14:41LauJensenWell, no, we review the commit stream :)
14:44ssiderishaha
14:50ataggartwhat is the incantation needed for lein to pull the 1.2.0 compatible contrib jar?
15:16kumarshantanuI want to understand how does this work: (def x #(println "foo")) ((var x)) ((ref x)) ;; var and ref work, but atom doesn't
15:17kumarshantanuwhat's surprising here is, they don't need a deref @
15:20hiredmanin a time long ago vars and refs were the same thing
15:21kumarshantanuhiredman: I am intrigued why don't they need a deref
15:22hiredmanbecause vars usually hold functions it is useful to have them implement IFn and just pass calls along to the object they hold
15:23kumarshantanuhiredman: ditto for ref? why not for atom?
15:23hiredmanno
15:23hiredmanas I side vars and refs used to be the same thing
15:23hiredmansaid
15:24hiredmanrefs just sort of kept that behaviour, I don't know that you can rely on it continuing to be there
15:25hiredmanatoms where created fairly late, after the seperation had already occured so they didn't pickup that piece of left over code
15:27kumarshantanueven more curiously, ((var (var x))) and ((var (ref x))) don't work
15:27hiredmanuh
15:28kumarshantanubut ((ref (var x))) and ((ref (ref x))) work fine
15:28hiredmanclojurebot: special forms
15:28clojurebotGabh mo leithscéal?
15:28hiredmanclojurebot: jerk
15:28clojurebotI don't understand.
15:28hiredmanclojure.org/special_forms
15:28hiredmanread the docs before asking a million questions please
15:32kumarshantanuhiredman: okay, and thanks for the pointer
15:33Chousukekumarshantanu: the ref and var operators look like they're related but they do completely different things :P
15:34Chousukethe way to create a var named foo holding value bar is... (def foo bar)
15:38kumarshantanuChousuke: I think I am getting it now, but I was surprised in the beginning :)
15:39hiredmanref is function and var is a special form that the reader macro #' turns into
15:41ChousukeI had no idea that the redirection feature of refs was just a leftover though.
15:43kumarshantanuref seems to be transparent while acting on functions -- ((ref (ref (ref x)))) works
16:02LauJensenhmm, no ring/ring-core has been there for quite some time
16:05bobo_hm, any project that uses enlive? want to read some source to better understand how i should use it
16:06LauJensenbobo_: bestinclass.dk
16:06bobo_ah! should have known :-)
16:07LauJensenThere are 2 things you can check out. 1) the wordpress import, which uses the selectors, and 2) the site generator which uses templates
16:07LauJensenclojurebot: google github bestinclass.dk
16:07clojurebotFirst, out of 166 results is:
16:07clojurebotLauJensen&#39;s Profile - GitHub
16:07clojurebothttp://github.com/LauJensen
16:07LauJensenwell, close enough
16:08bobo_think its mostly the templating i want to read up on now. so il check the site generator
16:08LauJensenk, I think the file is called templates.clj
16:08bobo_yeh looks like it
16:11seangroveWhat's the easiest way to start generating charts with clojure?
16:12seangroveI've just lost ~1 hour messing around with the outdated dejcartes
16:12bobo_think i saw a jfreechart wrapper somewhere
16:13bobo_ah, that was dejcartes :-p
16:13bobo_seangrove: incanter perhaps?
16:14seangroveheh, yeah, I'm wondering about just using incanter
16:14seangroveSounds good, I'll give it a shot
16:14seangroveIt just looks like it might take more than an hour to get something up and running
16:14seangroveHappy to give it a try though
16:22LauJensenseangrove: the easiest way is without a doubt Google Charts, close second is JFreeChart
16:26ApeShotevery 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:26seangroveWhat's the "hello world" of an incanter project setup with leinigen?
16:27ApeShotFor 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:27ApeShotDoes lib only contain jars?
16:27technomancyApeShot: 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:28technomancyApeShot: have you read the Leiningen tutorial? it should help you get through that stuff.
16:28technomancyclojurebot: leiningen tutorial?
16:28clojurebotparedit tutorial is http://p.hagelb.org/paredit-outline
16:28technomancyclojurebot: botsmack!
16:28clojurebotclojurebot evades successfully!
16:28technomancy...
16:29technomancyclojurebot: leiningen tutorial is at http://github.com/technomancy/leiningen/blob/master/TUTORIAL.md
16:29clojurebotIn Ordnung
16:30ApeShottechnomancy: Thanks. This looks ultra helpful.
16:30ApeShottechnomancy: 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:30technomancyApeShot: look for the "checkout dependencies" feature
16:30seancorfieldlein new myproject; cd myproject; lein deps
16:31technomancyApeShot: can't remember if it's in the tutorial or the readme, but it's designed for that use case
16:31bobo_technomancy: is that documented somewhere? except for its existance
16:31ApeShottechnomancy: ok
16:31technomancybobo_: lightly-documented, I think
16:31technomancybut on the other hand, there's not a lot to it; it's easy to set up and should just work.
16:32seancorfield"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:32seancorfieldREADME > FAQ
16:33ApeShotseancorfield: So by this technique, I should create a "apeshotlib" project, even if I never hack on it directly.
16:33ApeShotAnd symlink it into checkouts
16:34technomancyApeShot: right; in most cases you have one project that depends on all the others.
16:34technomancyif you don't, you can create a dummy project
16:36thunkIs there a way to get slime to track buffers' namespaces from the (ns ...) form?
16:36technomancythunk: C-c M-p should do it
16:37thunktechnomancy: Ahh, very nice. Thanks
16:39technomancynp
16:47ApeShotOk, so I put the symlink to the library project in checkouts, but how to I (use '...) a library defined there?
16:47ApeShotI am not sure what path-thingy to specify in the use command (or require, etc)
16:49technomancyApeShot: 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:51ApeShotNot quite what I mean - suppose I create the apeshot lib, and in it lives src/error.clj which creates an (ns error)
16:51ApeShotHow do I refer to that namespace from within another project?
16:51ApeShotafter I have symlinked apeshotlib in checkouts
16:51technomancyfirstly it should be src/apeshot/error.clj
16:52ApeShotYes, that was my next question
16:52ApeShotAnd then it should be (ns apeshot.error)
16:52ApeShotIn the file itself?
16:52technomancyright
16:52technomancyand 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:53ApeShottechnomancy: I think I get it all now.
16:53ApeShottechnomancy: thanks!
16:53technomancyif 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:53technomancysure
16:54ApeShotI guess all this project discipline pays off in the long run.
16:54ApeShotI am sort of used to just hacking, starting with a "scratch.py" or whatever.
16:54ApeShotAnd gradually building up what structure a project needs
16:54ApeShotI suppose I could do that here.
16:55ApeShotBut then it would be hard to use SLIME to its fullest.
17:07technomancyMan, it's too bad Relevance isn't secretly working on an in-house Clojure web framework, huh?
17:07LauJensentechnomancy: ?
17:08technomancyLauJensen: just a silly thread on the mailing list
17:08technomancyhttp://groups.google.com/group/clojure/browse_thread/thread/32c51ca7ebdbc154
17:08LauJensenah
17:09ApeShotOk, 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:09technomancyApeShot: no quote in (ns apeshotlib.error)
17:09ApeShottechnomancy: right, type
17:09ApeShottypo.
17:09ApeShotOk, so in another project, I create a checkouts folder, symlink the apeshotlib project directory, start swank
17:09ApeShotHow do I access apeshotlib.error?
17:10bobo_technomancy: al you know is that they dont admit that they are doing something secret! ;-)
17:10ApeShot(use 'apeshotlib.error) doesn't work, saying it can't find apeshotlib on the class path.
17:10ApeShotDo I symlink the lib project folder in checkouts, or do I symlink the apeshotlib folder under src?
17:11technomancyit should be a symlink of the project root
17:11technomancybobo_: true! stu is a sneaky guy.
17:12chousernot 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:12bobo_oh! *plot thickens*
17:12ApeShottechnomancy: that is how I have it now.
17:12somniumisn't the main unsolved problem in CS these days creating a web framework better than rails?
17:12chouserheh
17:13technomancysomnium: as long as we've solved naming things and cache expiry.
17:13technomancynaming things: just don't use *jure, and you'll be fine
17:13technomancycache expiry: use memoize! it'll be simple.
17:13technomancyproblems solved. next!
17:14ApeShottechnomancy: do I have to do something with apeshotlib's project.clj file?
17:15technomancyApeShot: shouldn't be necessary. what does lein classpath show in the top-level project?
17:16technomancyif apeshotlib/src isn't in there then it's not going to work.
17:16technomancyApeShot: could it be a problem with relative symlinks? try an absolute one maybe?
17:16ApeShotIt shows apeshotlib/src
17:17ApeShotSo maybe it is the relative/absolute symlink thing
17:17ApeShotOr maybe swank-clojure-project isn't grabbing the classpath?
17:17ApeShotThe emacs command `swank-clojure-project`, I mean.
17:17technomancyyeah, that wouldn't work
17:17ApeShotAh
17:18technomancycheckout dependencies are a leiningen feature, not an Emacs feature
17:18ApeShotSo what is the right way to start a slime session from a leinigan project?
17:18technomancyso you need to do "lein swank" + M-x slime-connect
17:19ApeShotlein swank is not a task, apparently?
17:19bobo_ApeShot: you need :dev-dependencies [[swank-clojure "1.2.1"]])
17:20ApeShotbobo_: thanks, just read that in the FAQ
17:20bobo_(and then lein deps)
17:20technomancyor 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:21ApeShotThis is actually pretty sweet.
17:22technomancyyay \m/
17:22bobo_hm, is it only me who thinks it sounds nice to have a lein plugin to add other projects to a project?
17:23bobo_ie, that symlinks and so on
17:23bobo_except it isnt realy any so on
17:23technomancybobo_: lein-search can add to project.clj
17:24bobo_cool
17:24ApeShotEverything seems to be working now - thanks everyone.
17:25technomancybobo_: 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:26technomancyyou could totally use that to check stuff out into checkouts/
17:26bobo_intresting
17:57seancorfieldtechnomancy: any thoughts on incorporating some of the more popular plugins directly into lein?
17:57technomancyseancorfield: yeah, lein-search may go into 1.4
17:58seancorfieldany thoughts about lein-run?
17:58technomancyalso a candidate
17:59technomancyI think those might be the only generally-applicable ones
17:59technomancypossibly lein-multi, but 1.4 is probably too early for that
17:59danlarkinlein-awesome
17:59technomancydanlarkin: that's already built-in!
17:59technomancyno need for a plugin
18:00danlarkintouché!
18:00seancorfieldhmm, 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:01technomancyseancorfield: upgrade to lein 1.3 and add it to ~/.lein/plugins
18:02kumarshantanuseancorfield: Lein-run 1.0.1-SNAPSHOT has a default alias too -- http://github.com/sids/lein-run
18:02seancorfieldit doesn't create ~/.lein by default does it?
18:03kumarshantanuseancorfield: not sure abt ~/.lein
18:04technomancyseancorfield: no, that's all manual right now
18:04technomancyyet another planned 1.4 feature
18:05seancorfield'k... mkdir -p ~/.lein/plugins and a few cp later i'm in business :)
18:06seancorfieldi put robert/hooke in there too
18:06technomancyindispensible chap
18:08seancorfieldif i have a task in {project}/leiningen, it doesn't show up in the basic lein list of tasks - is that right?
18:08seancorfieldi can run the task and lein help mytask shows the docs from the task
18:08technomancyit should be src/leiningen/mytask.clj
18:09seancorfieldyes, it is
18:09technomancyoh... this may have been fixed in the 1.3.1-SNAPSHOT
18:09seancorfieldit's actually hello.clj (and it prints hello world)
18:10seancorfieldso i can do: lein hello
18:10seancorfieldand: lein help hello
18:10technomancywe had some issues with missing nses due to a bug in contrib's find-namespaces lib
18:10seancorfieldah, ok
18:10seancorfieldso lein upgrade ?
18:10technomancyupgrade will only get you the latest stable
18:10technomancyyou'll need to check it out and look at the build instructions at the bottom of the readme
18:10technomancyor wait a day or two, hopefully
18:11seancorfieldoh, ok... i'll just wait
18:11seancorfieldi have a big website launch this week so i shouldn't be spending as much time on clojure as i am right now :)
18:11seancorfieldpost launch, that'll be another matter
18:11technomancycool
18:12technomancyactually it would be nice to get more help testing this since it's about to be released if you do have the time
18:12seancorfield'k
18:16technomancyyou guys too =)
18:16technomancyI mean, if you've got a moment
18:17somniumis it a sign of over-use of printf-debugging when you use this? (defmacro quietly [& body] `(do (with-out-str (do ~@body)) nil))
18:21technomancysomnium: it could also be a sign of the fact that c.c.logging doesn't let you set log level at runtime. =\
18:22seancorfieldok, pulled, built... now where do i put the 1.3.1 snapshot jar?
18:23seancorfielddo i just update VERSION at the top of the lein shell script?
18:23seancorfieldor is there some magic lein command now i have the new jar?
18:26ataggarttechnomancy: I'm about to upload a version of c.c.logging that does
18:28ataggartwell it's not up yet :)
18:29ataggartand for some reason the generated docs are a mish-mash of old and new names
18:33seancorfieldfigured it out... copied it to my maven repo manually and then copied the new lein script to /usr/local/bin
18:33seancorfieldand i seem to be in business
18:33seancorfieldmy hello task still doesn't show up in lein help tho' :)
18:38seancorfieldi'll have to update my laptop to lein 1.3.1 as well today
20:07ssideris,(String/format "%02d" 4)
20:07clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to [Ljava.lang.Object;
20:07ssiderishm
20:12dnolen,(String/format "%02d" (to-array [2]))
20:12clojurebot"02"
20:12boojum,(format "%02d" 4)
20:12clojurebot"04"
20:25dberg(require 'clojure.contrib.str-utils) throws a file not found exception
20:27dbergI installed closure from ubuntu repo and followed the instructions to compile clojure-contrib
20:28dbergany steps I'm missing for clojure-repl to load str_utils?
20:36dnolendberg: are you using clojure 1.2 ?
20:36dbergdnolen: no, the one in the repository is 1.0
20:36dbergdnolen: should I remove it and install 1.2 instead?
20:37dnolendberg: yeah, I would. In 1.2 you can just (require '[clojure.string :as string])
20:39dbergdnolen: 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:39dberg
20:44dbergdnolen: hmmm I didn't have jdk, installed, compiled clojure-contrib but no luck
20:44dbergdnolen: will try version 1.2
20:45dnolendberg: so you have the jdk installed now?
20:46dbergdnolen: yes
20:47emhwhy doesn't the following print multiple lines?
20:47emh(binding [clojure.pprint/*print-miser-width* 1] (pprint (range 10)))
20:49emhah. *print-right-margin* does what I want
21:00alpheusWhat project uses defprotocol? I'd like to read some code.
21:16chouseralpheus: http://github.com/Chouser/finger-tree/blob/master/finger_tree.clj
21:17alpheusthank you
21:18Rayneschouser: Did you ever get a chance to look at those yourkit snapshots?
21:58chouserRaynes: I downloaded them and then realized I didn't have yourkit installed.
21:58chouserI may get to them tonight or tomorrow.
21:58Rayneschouser: Alright, thanks. :)
22:53chouserRaynes: this is tough
22:53chouserirclj is one of the namespaces you reload?
22:57hugodis it the permgen space that is growing?
22:58chouserthere are many more objects of many types
22:58chousernot sure if that answers the question.
22:58hugodi see permgen growth if I :reload anything with a deftype/defprotocol
22:58chouserbut it's not just Class objects that there are more of
23:01hugodpresumably, all the "old" objects hang around until they get GC'd
23:02chouseryeah, but I don't know that they'd be included in yourkit's list of objects
23:02chouserI guess I should confirm that before making assumptions.
23:02chouserhm, I wonder if MongoDB is keep a list of Connectors.
23:03chouser...perhaps if they're not closed?
23:03hugodforce gc, reload, force gc, and see what the difference is?
23:04chouserI don't have the code.
23:04_mstjvisualvm lets you diff two memory dumps too, if that helps
23:04Rayneschouser: Irclj is the underlying IRC library.
23:05chouserI'm looking at diffs between snapshots that Raynes took with yourkit.
23:05chouserRaynes: do you have any mongodb connectors that you aren't closing?
23:05RaynesI don't know. I open the DB in core, but I never reload core. I'm not sure how that magic works.
23:06RaynesI can try disabling mongo completely and see what happens.
23:07RaynesBut 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:08chouserI 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:08chouserI doubt it accounts for all of the increase, though.
23:09RaynesI appreciate you taking a look, either way.
23:09RaynesI suck at profiling.
23:11chouserreference paths to things that there are more of, to see what roots may be hanging onto old values that you don't need.
23:11chouserbut the scale of object allocation is hard to deal with.
23:12RaynesTaking out the mongo stuff has no effect.
23:12chouserafter 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:13RaynesIndeed.
23:14RaynesIt's a seriously annoying bug.
23:14chouserwell, I don't think this is leading anywhere.
23:14RaynesI 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:15chouserI'd recommend trying to reproduce on a much smaller code base.
23:15chouseryourkit does say these are "live objects", so manual gc shouldn't be required.
23:16chouserso try something simple, with maybe just one lib. snapshot, :reload, snapshot, compare.
23:16chouserif even a simple case shows the problem, it'll be easier to get it accepted as a clojure bug.
23:16RaynesYeah. It seems with even a single plugin this happens.
23:16chouserif a simple case does NOT show the problem, start scaling up until you see it.
23:16RaynesJust on a smaller basis.
23:18RaynesI 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:18RaynesIt 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:19Raynes:>
23:19Rayneschouser: I appreciate the advice, and I'll keep you posted on my findings. Thanks a lot for checking those snapshots out.
23:30chouseryou're reloading at a REPL, or via an irc command?
23:46Rayneschouser: The latter.
23:48Rayneschouser: 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:48RaynesI'm taking off for a little while.
23:48technomancyseancorfield: sorry; had to take off there
23:48technomancythe answer is you don't have to do anything
23:49technomancyjust use the lein script from bin/lein in your checkout
23:53BahmanHi all!