#clojure logs

2009-05-26

00:38replaca+1 for better error messages from the Clojure compiler!
00:39replaca"java.lang.ClassNotFoundException: java.lang. (PrettyWriter.clj:17)" with like 200 lines of irrelevant exception garbage is just not helpful.
00:45technomancyreplaca: I hacked the slime trace buffer to dim lines that came from clojure.lang etc.
00:45technomancydoes wonders for readability
00:46technomancy... wow, and it looks like maven has *no* tests for dependency management! woooo!
00:52replacatechnomancy: yeah, that would help (I'm actually doing this one from shell) but we really need to get generally better errors
00:53technomancyreplaca: seems like a filtering problem to me
00:53replacatechnomancy: is it true you're coming to SF for JavaOne and the Clojure meetup?
00:53replacatechnomancy: well, a filtering problem and the underlying error message is just not useful in this case
00:54replacatechnomancy: but reall, a compiler error is not a thrown exception - it's a known problem
00:54replaca*really
00:54technomancyreplaca: yeah, I'm coming down to SF
00:55technomancyjust for the meetup actually, not for JavaOne.
00:55replacaawesome!
00:55technomancyyeah, pretty excited
00:55replacado you have something you want to present?
00:56technomancyactually I was hoping to catch a peek of Swarmiji
00:56replacawe're just doing a few "lighting" presentations
00:56replacayeah, me too
00:56technomancymay end up contributing to that project as it seems to cover the same ground as what we're doing
00:56technomancyinfrastructure-wise
00:56replacaI couldn't go down the night Amit showed it in Mt. View
00:57replacaI did convince Amit to discuss it again at the SF meetup (which wasn't too hard) so we should see it.
00:58technomancygreat
01:01durka42how do you test to make sure a function really is lazy?
01:05hiredmanyou pass it a seq that contains a println
01:05hiredman:P
01:07replacaack. That error message above meant that I hadn't provided a return value for a method in a gen-class :-(
01:12slashus2I always liked tesla coils http://www.youtube.com/watch?v=Zi4kXgDBFhw
01:12slashus2woops wrong channel sorry.
01:13lgasI always liked the band Tesla
01:42bradfordI want to create a function that, given a range and a value, returns which slot in teh range the value is between
01:45hiredman"slot"?
01:46bradforderr...but slot i mean (1 5 10) 6 would be in slot 2 (between 1-5 ... slot 1 would be 0 to 1)
01:48hiredman:(
01:49hiredmanwhat is this for?
01:49bradfordit is for a bayesean classifier...in order to classify the ranges that numeric values fall into
01:50hiredmanI think you might want to use a vector of actual ranges
01:50hiredman[(range 0 1) (range 1 5) (range 5 10)]
01:50hiredman,[(range 0 1) (range 1 5) (range 5 10)]
01:50clojurebot[(0) (1 2 3 4) (5 6 7 8 9)]
01:53hiredman,(first (filter #(contains? (first %) 6) (map vector [(range 0 1) (range 1 5) (range 5 10)] (range 3))))
01:53clojurebotnil
01:53hiredmanbah
01:53bradford(defn range-classifier [range]
01:53bradford (fn [item] (reduce #(+ %1 (binary (> item %2))) (concat [0] range))))
01:54hiredman,(filter #(contains? (first %) 6) (map vector [(range 0 1) (range 1 5) (range 5 10)] (range 3)))
01:54clojurebot()
01:54bradfordthis binary function just returns 1 for trie and 0 for false
01:55hiredman,(second (first (filter #((set (first %)) 6) (map vector [(range 0 1) (range 1 5) (range 5 10)] (range 3))))))
01:55clojurebot2
01:58bradford,(((fn [range] (fn [item] (reduce #(+ %1 (binary (> item %2))) (concat [0 0] range)))) (range 1 10)) 5)
01:58clojurebotjava.lang.Exception: Unable to resolve symbol: binary in this context
01:59hiredman,(contains? (range 10) 5)
01:59clojurebotfalse
01:59hiredman:(
01:59hiredman,(doc contains?)
01:59clojurebot"([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."
02:00hiredman,(some (partial = 6) (range 10))
02:00clojurebottrue
02:00hiredman,(some (partial = 11) (range 10))
02:00clojurebotnil
02:01bradford, (((fn [range] (fn [item] (reduce #(+ %1 (if (> item %2) 1 0)) (concat [0 0] range)))) (range 1 10)) 5)
02:01clojurebot5
02:02bradfordworks
02:03hiredmanif you say so
02:04bradfordhehe
02:04bradfordits kinda strange though
02:04hiredmanI don't see the advantage of that
02:04bradfordadvantage of what?
02:04hiredmanwhat is it supposed to do?
02:04hiredmanthat function
02:05hiredman,((set (range 10)) 5)
02:05clojurebot5
02:05bradfordit will find what interval of the range that a value lies in
02:05hiredmanif you say so
02:24eliantorhi i read that for each lambda a new IFn interface is created and stored in the PermGen memory, and that this memory area is never garbage collected?
02:25eliantoris it true, and is it an issue?
02:25hiredmanno, no, and no
02:27eliantor:)
02:27slashus2eliantor: Where did you read that?
02:28eliantorhttp://npcontemplation.blogspot.com/2009/01/clojure-genetic-mona-lisa-problem-in.html
02:29hiredmaneliantor: you should read the comments
02:29eliantorhiredman: :)
02:29hiredman(on that old blog post)
02:30hiredman~latest
02:30clojurebotlatest is 1375
02:30hiredman(- 1375 1232)
02:30clojurebot*suffusion of yellow*
02:30hiredmanclojurebot: thanks!
02:30clojurebotExcuse me?
02:30hiredman,(- 1375 1232)
02:30clojurebot143
02:31hiredmanr1232
02:35eliantorhiredman: so if i plan to use a huge set of lambdas i better wrap them in eval??
02:35hiredmanno
02:35hiredmanlike, uh, just no
02:35hiredman*sigh*
02:35slashus2hehe
02:36slashus2eliantor: Just code as you regularly would, don't worry about this.
02:36eliantorhiredman: maybe my question are really stupid, but i really don't know much of this stuff...
02:36eliantor:)
02:37eliantorthanks
02:37hiredmaneverything essential moves through eval any way, it's how a lisp works
02:38eliantoroh ok
05:21adityogood afternoon folks
05:22adityoa small question
05:22adityofor this statement => (map #(+ % 3) [2 4 7]) ; -> (5 7 10)
05:22adityowhat does % signify
05:22hoeckadityo: hi
05:22hoeckadityo: the first argument
05:23adityoohh..okie..
05:23hoeck,`#(+ % 3)
05:23hoeckwhere's clojurebot?
05:24slashus2,(+ 1 2)
05:24slashus2:-(
05:25hoeckadityo: anyway, #(+ % 3) is shorthand for (fn [x] (+ x 3))
05:29adityoohh cool, that makes much more sense..im coming from CL :)
05:32hoeckadityo: yeah, its just a simple reader macro, I have seen this in scheme too, using <n> instead of %n
05:47Gertmcan anyone help me set up my slime? I get an error saying: Exception in thread "main" java.lang.NoClassDefFoundError: clojure/main when I start it. Something is probably not configured well, but I can't figure out what
05:50hoeckGertm: have you set up the classpaths, clojure.jar etc using M-x customize-group ?
05:51GertmI have this one: (setq swank-clojure-jar-path "/usr/share/clojure")
05:51GertmI'll check the rest now
05:52hoeckGertm: swank-clojure-jar-path should point to the actual clojure.jar
05:54hoecknot the path, that name is a little confusing
05:54Gertmhoeck: ok thanks, that got it to work
05:57hoeckfine, glad I could help
08:39gnuvinceGood morning
08:46rhickeyhi
08:46gnuvinceThe server rebooted properly
08:47gnuvinceI guess I can put off opening cv.tex :_
08:47Chouser_gnuvince: got backups in the budget now?
08:47gnuvinceChouser_: dunno, but I'm definitely bringing it up again
08:47gnuvince(and documenting that I brought the issue up again)
10:07Chouser_I've been fighting a race condition trying to shutdown the agent pools cleanly.
10:08Chouser_One complication is that I can't catch (for debugging, reporting, instrumenting, etc.) RejectedExecuction exceptions, because they bubble out of Action.execute()
10:08rhickeyChouser_: let me look
10:08Chouser_I temporarily hacked in a printf so I could see the agent causing the problem.
10:09Chouser_but that doesn't seem like the Right solution.
10:11lisppaste8Chouser pasted "extra info on RejectedExecution" at http://paste.lisp.org/+1QDM
10:12Chouser_to be clear, the race isn't in clojure itself, it's in my code trying to halt self-sending agents before shutting down the pools.
10:14rhickeyChouser_: do you just want them stuck on the agent like all other exceptions?
10:15Chouser_once there's a error callback (or whatever) that might be perfect.
10:16Chouser_Right now I'm not using the agent-errors because I have to poll it, so instead I wrap try/catch around the action like this: (send-off my-agent rpt-err real-action arg1)
10:16rhickeyChouser_: patch welcome for on-error callback fn
10:17Chouser_...where rpt-err call the real-action in a try. Also a useful place to log state transitions, etc.
10:18rhickeywow - now reduce of filter of map over vector with chunked seqs faster than the equivalent loop!
10:18Chouser_whoa
10:18Chouser_faster than a non-chunked loop?
10:19lisppaste8rhickey pasted "faster chunked seqs" at http://paste.lisp.org/+1QDO
10:20rhickeyyup
10:20Chouser_very cool
10:20rhickey67ms on my machine
10:21rhickeyand the loop isn't even looking at a vector
10:21Chouser_I just noticed that
10:22Chousukewonder how it'd work with a chunked Range
10:22duck1123is anyone here making use of clj-record?
10:25duck1123I'm getting a class not found exception, which is odd, because I would exect the normal can't find the ns exception from clojure
10:26lisppaste8rhickey annotated #80844 "apples to apples" at http://paste.lisp.org/+1QDO#1
10:26rhickeywow, it's an even bigger difference over loop w/vector - 3x!
10:27Chouser_you're using the vector's natural chunk size? 32 per chunk?
10:27rhickeyyup, uses the nodes directly (actually a small shim is allocated right now)
10:27asbjxrnI'm a bit out of the loop. Does this mean that you're now starting to focus more on performance?
10:28rhickeyasbjxrn: no, this is about maximizing the value of Clojure's key abstractions
10:29rhickeyperformance optimization overall is a black hole
10:29asbjxrnCool.
10:30rhickeyall the *'s will be going away, this will be built into map/filter/reduce etc
10:30duck1123thinking about performance never hurts, but performance optimization is rarely something you should loose sleep over.
10:31Chouser_or lose it, either.
10:31stuartsierraWhat is a "chunked" sequence and why is it faster?
10:32asbjxrnI don't have any issues with performance fow what I'm doing so far, so I'm not losing any sleep.
10:32Chouser_asbjxrn: exactly. Clojure's already too fast.
10:33rhickeystuartsierra: chunked sequences extend the seq abstraction to seq nodes that have small chunks inside them, so all laziness and allocation overhead is amortized - they are also perfectly normal seqs
10:33gnuvinceChouser_: "too fast"?
10:34Chouser_gnuvince: breaking speed limits. making other languages look bad. allowing sloppy coding to still perform well. ...there are plenty of reasons too fast can be bad.
10:34rhickeystuartsierra: map/reduce et al will recognize they've been handed a chunked seq and will process the entire chunk in one go
10:35stuartsierraSort of like a buffer for a stream?
10:35rhickeyso laziness and boxing overhead become 1/32 of what it was
10:35gnuvinceChouser_: I can hardly think of any.
10:35Chouser_gnuvince: I'm being silly. Please ignore me.
10:35rhickeyyet it is still a lazy model, i.e. not everything is pulled into memory and no realization of intermediate results
10:35gnuvinceIf you can have nice, modular, maintanble code that also happens to be really quick, I say go for it
10:35gnuvinceAh
10:35stuartsierracool
10:36gnuvinceMy sarcasm detector is deffective it seems
10:36Chouser_gnuvince: or my humor isn't funny. Either way. :-)
10:36rhickeythis has replaced the streams idea, much nicer, safer, integrated, functional
10:37Chouser_streams had already abandoned resource management, right?
10:38rhickeyChouser_: streams had two parts, an unsafe bit you weren't supposed to share, and an ability to create a locked-down stream. Resource management is orthogonal - the scope system could work with either
10:39gnuvincerhickey: are these new developments coded in pure Clojure or is there Java code involved?
10:39danlarkinI like
10:40rhickeythe thing about streams is they put mutation (when needed) in the source, drastically reducing the sharability and functional nature. Chunked seqs put it in the return value creation, following the model of all of the persistent vecs/hashmaps
10:42duck1123hmm... would chunked seqs be what you would want for lazy sql?
10:45rhickeygnuvince: there's still some Java until I get around to implementing 'instance'
10:45gnuvincerhickey: ok
10:47rhickeystuartsierra: yes, like a buffer in some ways
10:49rhickeygnuvince: this kind of infrastructure stuff has to be as fast as possible, currently only possible in Java - 'instance' will not have the overheads of proxy/gen-class
10:51gnuvincerhickey: I was asking because I'm curious if/how custom data structures could be created in Clojure
10:52rhickeygnuvince: they can now, in several ways
10:53rhickeymoving forward the recipe will be definterface (static) + instance (dynamic)
10:54rhickeyyou can't get the highest perf without some static aspect
10:55rhickeyinstance will be what many people think proxy is
10:55Chouser_I've seen some people doing some fun dynamic stuff with proxy -- will it stick around for such purposes?
10:56gnuvincerhickey: okay
10:57gnuvinceLooking forward to it
11:09rhickeyChouser_: actually leveraging swapping the fns out?
11:10Chouser_rhickey: Yes, I think so. Or at least building up the fn map using domain-specific means.
11:10rhickeythere's no harm to it remaining other than confusion about which to use when
11:11Chouser_I guess I don't remember enough to know if they really need to muck about with it at runtime, but that's my vague impression.
11:11rhickeyinstance will be much faster, and not subject to the travails of proxy for interacting with superclass stuff
11:11Chouser_yeah, proxy-super's not threadsafe, is it?
11:12rhickeyo
11:12rhickeyno
11:13rhickeyso, this chunked seq experiment seems a smashing success - I'm going to try to wrap it up a bit and get in in trunk so maybe we can get more hands involved in doing the complete job
11:14rhickeya persistent T-tree replacement for the red-black trees would be welcome
11:14rhickeythen the sorted colls will have interior nodes amenable to chunking
11:15rhickeyhttp://en.wikipedia.org/wiki/T-tree
11:15Chouser_Will 2-3 finger trees' chunks be too small to get much benefit?
11:15gnuvinceI missed most of the conversation about chunked seqs, so I'll ask: how do they work?
11:15rhickeyChouser_: probably, they are more like linked lists, which also won't chunk
11:17rhickeygnuvince: there is an IChunkedSeq derivee of ISeq which adds chunked first/rest/next. Data structures that can support them will return seqs that implement IChunkedSeq. In my prototype I've written a chunked seq for PersistentVector
11:18Chouser_rhickey: http://code.google.com/p/clojure/issues/detail?id=26#c1
11:18rhickeymap/reduce/filter will check to see if what they get from seq is chunked, if so they do a little loop over the chunk, and use chunked-cons to return another chunked seq themselves
11:18gnuvincechunked first/rest/next meaning what? first fetches a few elements and caches them?
11:19rhickeychunkedFirst returns an indexed chunk, supporting nth and count, chunkedRest returns a logical collection of items after the first chunk, chunked next does the same with the seq-or-nil protocol
11:20rhickeygnuvince: but no, it's not a ache and in that sense differs from buffering - the underlying data structure needs to be able to provide indexed access to some small (e.g. 32) number of elements, as can the persistent vectors and hashmaps
11:21gnuvinceok
11:22rhickeyChouser_: thanks for the patch - do you think it should still put errors on the agent when a callback is supplied?
11:23Chousukesounds like they should make "IO" seqs a fair bit faster too.
11:25Chouser_rhickey: good question
11:25Chouser_if the callback doesn't know how to handle a particular error, it doesn't have any way to put that error on the agent's list
11:26rhickeyI always saw the callbacks as an alternative to the per-agent list
11:26Chouser_but it seems like most error-fn's won't care about the particular error and will end up calling clear-agent-errors.
11:27rhickeyif I had a callback I wouldn't want agent-errors etc, maybe just some way for the agent to pause until restarted
11:28rhickeybut there is also the possibility of a protocol in the callback, via a return value
11:29rhickeythere are two independent problems currently handled together - workflow and reporting
11:29Chouser_a protocol to allow clearing, queueing on the agent's erroer seq, pausing until ...something??
11:30rhickeya lot of callbacks might only be about reporting
11:30rhickeycentralized logging etc
11:31rhickeyothers might route a problem to a controller that would know to restart/reset the agent, if that was possible
11:32rhickeybut that might not be a synchronous decision
11:32rhickeyi.e. put error on queue and return
11:32Chouser_do you want to allow for multiple error-callbacks, so different concerns can be handled separately?
11:33rhickeyChouser_: I don't think so - people can add whatever multiplexing they like, but unlike watching, error handling strategies don't compose ad hoc
11:35Chouser_if the error-callback got the action args, that should be all it could need to decide how to restart later.
11:35rhickeywhat gets routed to the handler - just the exception?
11:35rhickeyheh
11:36rhickeyI think it's important not to get locked into the agent-errors/clear-errors model with this callback system
11:36Chouser_currently the callback gets the agent and the exception list (which it doesn't really need since it could call agent-errors)
11:36Chouser_hm.
11:37rhickeyso yes, communicating as much as possible to the handler is good, using the return value of the handler to either proceed (with a possible new state), or go into an error mode until further notice, and then a way to reset when in error mode in order to proceed
11:37rhickeylater
11:38Chousukehmm
11:39Chouserany reason "error mode" should be other than non-nil error list as it is now?
11:39rhickeyfrom a workflow perspective either the agent is running or stopped
11:40Chouserif the callback just returns [:error e] instead of [:new-state :foo]
11:40rhickeyit's an open question as to whether there would ever be a list, once you can get notified of the first error synchronously
11:40rhickeythe only reason they accumulated was due to the async
11:41Chouserthe code I'm working on now uses the state of the agent for workflow
11:47Chousukehow about making it possible to add a redirect to another agent while the original agent is in "error mode"? that way, it could log users of the agent for example. and if the redirected-to agent errors, the same mechanism could be used to redirect further, or whatever you want.
11:48Chouserthe callback patch I have in is synchronous, which I think is fine -- until the error is handled the original agent can't do anything else anyway.
11:49Chouserif the callback throws something, I fall back on the default behavior -- queing it in the agent's errors.
11:49Chousukeif the error is something that can't be handled synchronously, a redirect mechanism could be useful.
11:49Chousersure, but the callback can do a send-off, or add something to a BlockingQueue or whatever.
11:50Chouserwell, I think I've done as much as I can at the moment. If the requirements get firmed up a bit, perhaps I can make another go-around on the patch later.
12:19ChouserWhat's the best way to make sure a function is not called from within an agent action (because it might deadlock)?
12:19Chouser(assert (not *agent*)) ?
12:25rhickeyChouser: sound scary, how did this happen?
12:26rhickey(assert (not *agent*)) will work
12:26ChouserI've got several self-sending agents, most blocked on reading or accepting sockets.
12:27ChouserBut now I want to shut it down. So I need to close the sockets, clean up the agent queues, and shutdown the pools.
12:27ChouserOver the last several days I found several stragies that don't work. I now have one that does.
12:28rhickeydoes the socket api support the interruption protocol?
12:28Chouserat shutdown, I count up my agents, put that in a CountDownLatch, (send agt quit) for each agent, and then close the sockets.
12:29Chouseroh, then await on my countdownlatch.
12:30Chouserthe quit fns check the agent state. If it's not yet :closed, they send-self. If it's :closed, they countDown the latch.
12:31Chouserso the socket agents do what they do until they notice their socket is closed, at which point the go to :closed and stop self-sending.
12:32Chouserthis means every agent has a change to clean itself up properly then cleanly signal its done. The shutdown code is self-contained and can be sure all the agents are done before it unblocks and returns.
12:32ChouserI don't really need to use interruption as I can close the sockets.
12:33Chouserso this is all working fine -- no deadlocks, no RejectedExecution
12:33Chouser...unless you're in one of the agents when you try to shutdown. In that case you've got a deadlock on the agent waiting for a queued action on itself to complete.
12:34ChouserI can document this and I don't expect it to be a big deal for users, but they will forget and I'd like an error instead of deadlock.
12:36stuhoodthe self sending agents seem really dangerous in general
12:37stuhoodif you were using an epoll type architecture, a parent thread could (send) when there was something for an agent (per connection) to do
12:39Chouserthe only problems I've had with the self-sending agents are when trying to synrchonize them all for shutdown. And even then, it's only been a problem of spurious RejectedExecution exceptions. Do you see other problems?
12:40stuhoodno, just the fact that you needed to use a countDownLatch
12:40Chouserah. I always seem to have to do something like that when trying to collect all my agents.
12:41stuhoodif the agents never blocked, then they would always be short lived
12:41Chouserrhickey has frowned at that in the past, but I haven't understood any alternative that I like at all.
12:44stuhoodagents really seem like they need to be treated like a threadpool
12:45stuhoodhmm, but i guess your use case would apply well to a threadpool
12:45stuhoodnevermind me.
12:45Chouser:-)
12:46ChouserI dabbled with managing Threads directly, and just having them loop (still not the epoll you mentioned), but that didn't really solve any of my problems and meant I couldn't redefine functions livetime (usefully)
12:46stuhoodbut if the agents weren't self sending, it would be easy to shut them down
12:47emacsenIs there any way to ask Clojure for all the methods that an object can be called with?
12:48technomancyemacsen: try clojure.contrib.repl-utils/show
12:49emacsentechnomancy: Okay, question 2: Is there any nice way to search the docs by full text, rather than by function name? :)
12:49technomancy(doc find-doc)
12:49emacsenWell isn't that clever :)
12:49technomancyoh no, where's clojurebot?
12:50emacsendoes the lib need to be included?
12:50duck1123 it's in core
12:50emacsenno... I mean can I search contribs, for example
12:50emacsenthings I've yet to require
12:51Chousukeno
12:51emacsenala perldoc, pydoc, etc
12:51technomancyemacsen: for that you need grep. =)
12:51duck1123i thought it did the whole classpath
12:51Chousukehmm
12:52technomancyI don't think so, that would cause everything on the classpath to get required, which would balloon memory usage.
12:52Chousukebut there's online documentation for contrib, and it has a search box :)
12:56replaca,(doc finddoc)
12:56duncanmhola
12:57replaca,(doc find-doc)
12:57duncanmi really miss having @"foo" literal strings for paths (ala C#) on Windows
12:57duncanmit's much easier to write @"C:\foo\bar" than doing search-n-replace to get "c:\\foo\\bar" or "c:/foo/bar"
12:58duncanmcan i write a reader macro to get @-strings?
12:58Chousukeno user-defined reader macros
12:58technomancyduncanm: can't you use regular slashes and have the JVM perform the conversion for you?
12:58Chousukebut you can have a (path "foo") macro.
12:59replacaChousuke: you literally took the words out of my mouth :-)
12:59emacsenreplaca: I know it's a dumb pet peeve, but it's a pet peeve nonetheless. He LITTERALLY took the words out of your mouth?
12:59technomancyChousuke: that macro would already have the string parsed by the reader, so backslashes would get lost
12:59technomancyhehe
13:00Chousuketechnomancy: hmm, right.
13:00replacaemacsen: yeah, you should have seen it. Sort of painful, actually
13:00emacsen:)
13:00replacaemacsen: but to be precise, I meant that was literally the exact sentence I was typing, not just close
13:01technomancyreplaca: english needs more parens
13:01duck1123Lojban FTW
13:01Chousukeno it doesn't. I tried lisp-syntax english once. painful.
13:01emacsenhehe, lojban! :)
13:01replacatechnomancy: *everything* needs more parens. but we're helping it along
13:02technomancyChousuke: you just need to get better at diagramming sentences
13:02Chousuke(reduce eat (get-cakes))
13:03technomancynom nom nom
13:03stuhood(eat!)
13:03replacaemacsen: I was a loglan afficianado as a kid, but I found spanish was better for meeting girls
13:04duck1123I've been trying to get my wife to learn it with me, but I'll have to settle for teaching my kids
13:08duncanmif i write a path function for this, do i have to convert all control characters back to their non-control equivalent?
13:09Chousukelojban has s/z+consonant syllables ;(
13:09Chousukeevil
13:14duck1123Is there a way to specify in my namespace that all of my tests are located in a different namespace?
13:18duck1123basically I want to be able to say that net.mycyclopedia.model.entry's tests are in net.mycyclopedia.model.entry-test so I can use the former as the call to run-test
13:19Chousukeclojure's tests are in clojure-contrib. see how it's done there :)
13:19technomancyduck1123: were you the one asking me about an emacs function to switch between test and impl?
13:20duck1123technomancy: yes i was. I see that you made something, but haven't gotten around to trying it yet
13:21duck1123I'm just now getting started with TDD now that my pom.xml is able to compile and test for me
13:23technomancyduck1123: I find it's easier to do TDD if you don't have to switch away from the test buffer to see the results, which is what clojure-test-mode does
13:30duck1123technomancy: I think I'm going to have to hack it a little bit because I keep my tests in a difeerent location (src/test/clojure/) than you do.
13:31duck1123other than that, it looks very useful.
13:31Raynes?
13:32Lau_of_DKGood evening gents
13:33duck1123it's so hard going back to using elisp, I keep wanting to use [] in places. (ie. let)
13:34RaynesGood evening Lau_of_DK.
13:34technomancyduck1123: no kidding
13:35technomancyevery time I type setq it makes me cringe
13:46durka42,(seq? '[a])
13:47durka42no clojurebot...
13:47durka42anyway
13:47durka42Clojure=> (seq? '[a])
13:47durka42false
13:47durka42why?
13:47Chousera vector is not a sequence
13:47RaynesBoom.
13:47Chousermost collections are not themselves seqs
13:47kotarak(seq? (seq [a])) => true
13:47Chouser...the exception being PersistentList
13:48RaynesThat list is so darn persistent!
13:48cmvkkthat reminds me, why don't sequences implement Associative?
13:48durka42coll? was the function i wanted
13:48cmvkki want to be able to do (assoc '(1 2 3) 1 4)
13:48durka42(assoc [1 2 3] 1 4)
13:49cmvkkwell yes, it works with a vector
13:49cmvkki'm just wondering if there's a specific reason that it doesn't work with lists
13:54Chousukecmvkk: lists aren't associative.
13:55cmvkkis there any particular reason for that? just because it isn't very efficient, or something?
13:55cmvkki'm mostly just curious
13:55Chouserlists don't associate anything. lookups via nth are O(n)
13:56Chousukecmvkk: lists just contain items. they're not associated with keys (like maps) or their index (like vectors)
13:57Chousukepretending that list items have an index would make them vectors, conceptually, and it'd be rather stupid :/
13:57cmvkkof course you're right. i wonder where I got the idea that you could index lists at all.
13:57cmvkki was thinking that (get '(1 2 3) 1) would work too but it doesn't
13:57cmvkkmaybe you could do that in common lisp or something? hmm.
13:59cmvkkit seems like it would be a useful abstraction anyway though, and I guess you could argue that elements in a seq are conceptually associated with their positions ("first", "second" etc)
13:59cmvkkbut i get the idea
13:59duck1123technomancy: ok, I got clojure-test-mode working with my directory structure. Very nice.
13:59technomancycool
14:00dnolencmvkk: (nth '(1 2 3 4 5) 3) works
14:00cmvkkyeah.
14:03Chousukecmvkk: I guess the difference here is that vector are associative becuase they're functions of indexes (meaning the operation of indexing is natural for a vector) while a you can look up an item in a list by its position, but the data structure itself does not make such an association.
14:03cmvkkthat is true.
14:03ChousukeI'm sure there is some fancy word for what I'm trying to say :P
14:04cmvkkno, I get it, and that makes sense.
14:04duck1123so now that more people are up, has anyone had any luck getting clj-record to work in their project?
14:04Chousukemaybe intensional and extensional
14:04cmvkkanyway i was only thinking about it because i wanted to do something like (assoc "hello" 2 \q) but I think there's a java function for that somewhere
14:06Chousukewell, strings are indexed so that conceptually that should actually work, but I think it doesn't because the String class doesn't implement the needed Clojure interface :/
14:07cmvkkyep. i think that has to do with the fact that the java String class is final so nobody could make a clojure wrapper class for it
14:07cmvkkoh well.
14:14hiredmancmvkk: CharSequence
14:20durka42hiredman: what happened to clojurebot today?
14:21mozinatoranyone here done some stuff with markov chains and clojure ?
14:21durka42hmm, clojure.core/replace kind of screw up maps
14:21durka42screws*
14:21hiredmanoh
14:22Chouser,(map identity {:a 1, :b 2, :c 3})
14:22technomancycrap! groovy jumped ahead of Clojure on github.
14:22technomancycome on guys, let's get some more projects up there
14:23technomancywe can't get beat by Groovy, that's embarrassing.
14:23Chousukehm
14:23gnuvincerhickey featured on infoq.com
14:23hiredmangnuvince!
14:23gnuvincehiredman: hello
14:23technomancygnuvince: is that good? worth trying to track down a non-flash version of the interview?
14:24Chousuke,(replace '[foo bar zonk] [2 0 1])
14:24clojurebot[zonk foo bar]
14:24duck1123technomancy: one issue I've noticed with clojure-test-mode. I thought libraries weren't supposed to bind C-c {single letter}
14:24hiredmangnuvince: been waiting for that stuff to show up
14:24technomancyduck1123: ah yeah... I chose that binding when it was still part of my personal dotfiles and forgot to change it when I moved it. =)
14:25gnuvincetechnomancy: watching now, but I guess you could ask Rich if you should watch it :)
14:26technomancydoesn't look like they offer any downloadable versions; too bad.
14:26gnuvinceSo far, the interviewer seems... lost
14:26technomancyI really don't need to see any visual with this kind of interview. annoying that they can't just post an mp3
14:40bradfordstrange
14:40bradfordI can name a function like this: (defn | [a b c] (b c a))
14:41bradfordand it works...but i can not use the "|" symbol in hte repl
14:41hiredmanbradford: works for me
14:41Chouserme too
14:41bradfordin the repl?
14:42hiredmanyep
14:42Chouser(| 5 + 6)
14:42bradfordright
14:42hiredmanunless b is a an IFn you are going to get an exception anyway
14:42kotarak| is not a valid symbol, IIRC.
14:43bradfordi always get "input not complete" in my emacs minibuffer...
14:43bradford| seems to be valid
14:43technomancy(symbol? (read-string "|")) ;; => true
14:44hiredmanbradford: well, that's emacs for you
14:44Chouserall chars besides *, +, !, -, _, and ? and alphanumerics are reserved.
14:44hiredman~emacs
14:44clojurebotuggada buggada
14:44Chouserkotarak: so you're right.
14:44technomancybradford: you sure you're not trying to eval it as elisp? =)
14:44bradfordyes, im sure :-)
14:44technomancyChouser: how come (symbol? (read-string "|")) works then?
14:45technomancyis it just one of those "it works by accident, but don't rely on it" things?
14:45kotaraktechnomancy: because Clojure doesn't enforce the rules.
14:45bradfordanyway, i want this to express conditional probabilities in their mathematical form
14:45technomancygotcha
14:45Chousertechnomancy: http://code.google.com/p/clojure/issues/detail?id=13
14:45bradfordP (a | b)
14:45technomancyChouser: those are my patches on that issue. =)
14:45technomancyI thought the reader defined what was valid though.
14:46Chousertechnomancy: well there you go then.
14:46technomancymust be wrong
14:46Chouser:-)
14:46ChouserI guess maybe that's a separate issue
14:46Chouserthat bug says "readable" which may not be identical to "supported"
14:46technomancyright
14:47kotarakrhickey once suggested || to delimit (more or less?) arbitrary symbols.
14:47kotarakNot sure what was the outcome of that.
14:48technomancythat's too bad about reserved symbols though; I'd love to use ? to name a var
14:48technomancy(for predicate functions that are destructive, I guess)
14:49kotarakThread.interrupted() comes to mind. :)
14:49Chouseryou're probably free to use non-ascii stuff. I don't think that'll ever conflict with a Clojure builtin
14:49hiredman
14:49hiredman� would be for things that look destructive, but aren't
14:50technomancynice
14:50hiredman(i.e. assoc, update-in, etc)
14:51technomancy(def ? fn)
14:51hiredmandoesn't work
14:51hiredmanfn is a special form
14:51technomancyoh of course
14:51hiredmanso you have to defmacro ?
15:08ddonnellwhat's the conventional way to distribute and consume libraries of clojure code?
15:09technomancyddonnell: it's pretty ad-hoc right now.
15:09ddonnell:(
15:10technomancyddonnell: the easiest way to support automated dependencies is probably to add a pom.xml that inherits from clojure-pom
15:10technomancybut it's a bit of a hassle, even clojure itself hasn't made it into any mainstream public repositories yet.
15:10ddonnellthanks
15:10dysingerIt's less hassle than all the other options
15:11kotarakddonnell: there is also some effort going on for Ivy support
15:11technomancydysinger: it'd be less of a hassle if we got clojure-pom into a public repo, I mean. =)
15:11dysingerand clojure-lang & clojure-contrib
15:11technomancythat too
15:11dysingeralthough I don't understand why the "-lang" part of that got started.
15:12kotarakIt is not removed by order de Rich.
15:12kotaraks/not/now
15:12dysingerAll we need to do is create a clojure-specific maven repo
15:12dysingerit would work for the ivy fanboys too.
15:12kotarak:)
15:12technomancydysinger: last night I poked around at getting mvn support in corkscrew; it doesn't look like it'd be hard at all.
15:13dysingeruntil you look at all the plugin infrastructure :)
15:13bradfordtechnomancy: do it dude :-)
15:13technomancyspent some time looking at the test cases for guidance, which turned out to be a mistake; repl-utils/show was more helpful
15:13dysingeryou mean "it wouldn't be that hard to support maven repos"
15:14dysingerbuildr for example, uses maven repos and can figure out trans deps
15:14dysingerbut it can't do any plugins.
15:14technomancydysinger: yeah, it's pretty easy to construct a project Model, and it looks like you can hand that off to a ProjectBuilder
15:15dysingersince the plugins don't work, you are forced back into writing a higher-order build tool or worse copy/pasting the same build snippets to all your projects.
15:18duck1123dysinger: the maven-clojure-plugin works fine for me
15:18dysingery it's just not needed.
15:18dysingerat least IMO
15:19dysingermy clojure-pom is like 2 dozen lines of XML and does AOT, tests, packaging.
15:19duck1123It needs some more work, and the defaults need to be fixed, but I think there could be future in it
15:19dysingerI'd buy that.
15:19dysingerI just looked at it a month ago and said "I can do all that with maven and a couple antrun tasks"
15:20duck1123I'm a complete maven noob, but I've been learning a lot lately
15:21dysingerIt's complex - that's why people hate it.
15:21duck1123Clojure needs some good maven archetypes too to make starting a new clojure library easy
15:21dysingerbut it works.
15:21dysingerand if you model your POMs correctly, often times projects have only a dozen lines of xml
15:22dysingerduck1123 yeah - I have a README that says "if you are brown belt in maven fu, you can create a maven archetype from an existing clojure project"
15:22duck1123right now, the plugin isn't modeled correctly, but as soon as I figure out how to change those defaults, I'll push out my fork
15:23duck1123saw that, not there yet. tried and failed
15:23dysingerI did a couple of them.
15:23dysingerbut it's almost as easy to just create a dir and put the base xml in the pom.xml than to use archetypes.
15:23dysingersince clojure is low on ceremony
15:23duck1123what ever happened to that clojure project hosting site idea that someone had
15:24dysingerIt's called "github"
15:24dysinger:)
15:24duck1123we came up with a whole bunch of names, and then i never heard of it
15:24hiredman~Xiphojura
15:24duck1123there's no way to make github a maven repository though, or is there
15:24clojurebot2009:Jan:29:16:03:17 <hiredman> I call Xiphojura
15:35Chouseruses of proxy is one of the very few places in clojure code where (foo ...) is not a call to a foo. Is there any sane way to fix that?
15:35Chouser(proxy [] [] (:foo [arg1 arg2] ...)) ?
15:36Chouser(proxy [] [] [foo [arg1 arg2] ...)] ?
15:36cmvkkyou just want to avoid using that syntax? what about (method foo ...) even though it's more verbose
15:36kotarak(proxy [] [] {foo (fn [arg1 arg2] ...})
15:36Chouser"method" isn't too bad.
15:37ChouserI assume the upcoming 'instance' form will need a similar syntax
15:45technomancyduck1123: that's something that corkscrew can do though; unpack git projects just like any other dependency
15:46technomancysince even if folks move towards the mvn repo format there will still be a lot of code that's just a raw repo
15:47technomancydysinger: are you just using plugins to do AOT and run tests?
15:52duck1123technomancy: that's actually what I has hope that'll fill this space. I just wish we could get all of the libraries out there to settle on a format making it easy to "require" a git-hub repository
15:53duck1123I'm using the plugin, dysinger uses the ant tasks
15:57technomancyduck1123: as long as using a lib is as simple as putting its src/ on the classpath, corkscrew should be able to handle it.
15:58duck1123what if it's actually src/main/clojure/
15:59technomancythen it won't work. =)
16:00duck1123there's still too much variation in clojure libraries at this point to make something work easily
16:00duck1123I'm sure you kknow this, do gems mandate a directory structure?
16:01technomancyduck1123: more or less; you put "require"-able stuff in lib and use bin for executables
17:01devinuswhat java book should i use to familiarize myself with it enough to use clojure ?
17:05stuartsierraThe Sun Java Tutorials.
17:31StartsWithKfyuryu: hi
17:48StartsWithKkotarak: it works :) hehe
17:48kotarakStartsWithK: :)
17:49kotarakJust syncing the repo on my server. :)
17:50kotarakI'll check the repo order.
17:52StartsWithKthat should seed up the build, maybe 40-60 sec max after that
17:52kotarakStartsWithK: Hmmm... I actually have a custom resolver chain, which checks local, then shared and only then the server...
17:52kotarakIvy should cached clojure...
17:53kotarakI think, the fork for the compilation is eating the time...
17:53StartsWithKthat happens im my builds too, fork takes to long
17:56StartsWithKalso, cloak can now execute simple ant task and generate repl script for standard clojure repl, rlwrap and jline based ones
18:21devinusgod clojure looks so cool but i'm not sure i'm smart enough to learn it
18:21devinusgoing through the code to clojure-contrib and i just can't grok even the comments! :-/
18:22danlarkindevinus: start with something simpler, one of rich's videos perhaps
18:22devinus"Dissociates an entry from a nested associative structure returning a new nested structure. keys is a sequence of keys. Any empty maps that result will not be present in the new structure."
18:22hiredmandevinus: core.clj is much nicer
18:22devinusWoah.
18:23devinusi don't even know what a nested associative structure means!
18:24hiredmandevinus: a map containing another map
18:24devinusi see
18:24hiredman,{:a {:b 1} :c 3}
18:24clojurebot{:a {:b 1}, :c 3}
18:25devinusbut then i read programming.reddit.com and i hear of things like stm, agents, multimethods...concurrency primitive! an explosion of wtf in my brain
18:33danlarkinjust take it slow
18:36kotarak,:@
18:36clojurebotInvalid token: :
18:37kotarak,(keyword "@")
18:37clojurebot:@
18:45bradfordI'm having trouble doing a reduce on a seq of vectors (pairs in this case)
18:47hiredman,(reduce concat '([1 2] [3 4] [5 6]))
18:47clojurebot(1 2 3 4 5 6)
18:47bradfordI tried to pass reduce a function like this: (defn reduce-pair [[x1 y1][x2 y2]] [(+ x1 x2) (+ y1 y2)])
18:48hiredman,(reduce (fn [[x1 y1] [x2 y2]] [(+ x1 x2) (+ y1 y2)]) '([1 2] [3 4] [5 6]))
18:48clojurebot[9 12]
18:48hiredman?
18:49bradfordyou're right, my code was correct...the arg I passed to it in the repl was wrong. :-(
20:25danlarkintechnomancy: merge Perry Trolard's clojure-http-client branch :)
20:27technomancyoh; that looks nice
20:30technomancydidn't realize you could have key-only cookies
20:31technomancymerge'd!
22:50technomancycould someone take a look at a some mvn internals to give me some hints? I'm running into some weird roadblocks.
22:50duck1123I'll take a look
22:50duck1123I'm not the greatest at maven yet
22:51technomancyduck1123: I'm trying to create an UnpackDependenciesMojo. that class has a "project" member, but it's protected, and I can't figure out how to set it.
22:52duck1123hmm... then beyond me at this point
22:52duck1123sorry
22:54technomancyI even tried to load it up in Eclipse, (shock, horror) but it couldn't make head or tail of it.
22:56technomancyI just don't know enough Java idioms to know where to look for that kind of thing; it's probably some obscure factory method somewhere, but I'm blanking.
22:57danlarkincheck the XML config file which points back to code!
22:58technomancyheh
22:58technomancydanlarkin: what's your take on the dependencies dance?
22:59danlarkinthat it takes most languages a few years to sort it out
23:00dnolen_well since Clojure code tends to be really short, maybe we can get there sooner :)
23:01technomancydnolen_: not to mention being built on an existing platform
23:01duck1123we have tons of java solutions for everything
23:01danlarkinit's a blessing and a curse that we have maven/ivy/whatever to consider too
23:02technomancydanlarkin: sure, but having one system for pure-clojure deps and another for other JVM-language deps seems like The Wrong Thing.
23:03dnolen_I'm not sold basing a anything on maven/ivy/whatever. I think we need something lispy, and people can plugin support for the Java stuff. The only library that I use that really requires me to mess around with jars is Compojure, and stuff like OpenGL and serial.
23:03danlarkinoh yes, what do other jvm languages do?
23:03technomancydnolen_: I think the compromise is to wrap existing infrastructure in a lispy interface
23:03dnolen_technomancy: totally.
23:03duck1123I guess a lot of scala users use maven
23:04dnolen_but not support maven/ivy/ant directly.
23:04dnolen_just call into them.
23:04technomancygroovy has a wrapper around maven
23:04duck1123I was asking where to find info about maven, and was told to ask the scala room
23:04RaynesSomeone should write a build system in Clojure.
23:04RaynesHaskell has Cabal, OCaml has... Well something... Clojure should have something. :)
23:04duck1123corkscrew? ties? lancet?
23:05technomancystu hasn't been to keen on making lancet anything other than an example project
23:05technomancymaybe now that the book is out he'll have more time to hack on it?
23:05dnolen_cloak is interesting as well. I gave up reinventing to wheel for that part. Something like rake for moving files around and running tasks is nice.
23:05danlarkinI have yet to look at corkscrew, I do like the idea though
23:05Raynesduck1123: Well, I mean a build system that Clojure people actually /use/. And insofar I've seen no one using any of them. Guess I haven't looked very hard though.
23:06dnolen_I also think libraries are too simple at this point.
23:06duck1123Raynes: that's the problem, all the libraries are scattered right now
23:06dnolen_community maintained meta-index is the answer to that.
23:06danlarkincheeseshop equivalent
23:07duck1123I've been downloading clojure libraries and converting them to a maven build system lately
23:07technomancyduck1123: me too; it's not too tricky
23:07RaynesLike Hackage.
23:10danlarkinanother problem with build systems & package management systems is it seems everyone's got a different setup of clojure on their systems
23:11technomancydanlarkin: well the way I've been doing it is that each project has its own copy of clojure checked out in its target/dependency directory
23:11technomancyso that's not really an issue
23:11duck1123it gets even worse when you consider testing
23:11danlarkinand no standard library location... I *really* like the idea of python's site-packages directory...
23:12dnolen_danlarkin: that's the part that should be standardized. I never loved ASDF, but at least everything is one place.
23:12dnolen_I'm going with .clojure in home
23:12duck1123maven has ~/.m2/repository/ which is similar
23:12dnolen_inside there's ext (all OS specific libs and jar goes here)
23:12technomancydanlarkin: yeah, everything gets stored in ~/.m2/repository
23:12technomancyit's just per-user rather than system-wide
23:12danlarkinand I use ~/clojure/src/ ... and there's the problem :) everyone's got a different setup
23:13dnolen_danlarkin: only because a script didn't set it up for you.
23:13dnolen_there's no reason to do this stuff by hand.
23:13danlarkinI totally agree
23:13technomancydanlarkin: if a build system handled it, you wouldn't even need clojure checked out on your box
23:13duck1123corkscrew generate {project name}, perhhaps?
23:14technomancyduck1123: eventually. but that's the easy part; I want to prove mvn integration is possible first. =)
23:14danlarkintechnomancy: oh, but I don't really favor that idea personally, it just seems crazy to checkout all these deps each time rather than just define a standard place for them to be
23:15technomancydanlarkin: you could just make your classpath include the jars straight out of ~/.m2/repository/$FOO/etc, I just haven't done that yet since it's easier to keep it all unpacked in one place.
23:15technomancyif you don't unpack, you can't add libraries at runtime, which is unfortunate
23:16danlarkinI think clojure should come with a clj binary/shell script that puts a default path on the CLASSPATH when it runs the jvm, and all clojure tools can use that path
23:16technomancyyeah, the lack of a shell script that comes with clojure is really boggling to me.
23:17technomancyit just enforces the "you should never use clojure without Slime or an IDE" mindset
23:17dnolen_technomancy: well a shell script isn't very Windows friendly right?
23:17dnolen_not that I care about that...
23:17danlarkinclj.bat :)
23:18duck1123when will we be able to 'sudo apt-get install clojure clojure-contrib'?
23:18Chouserhttp://packages.ubuntu.com/karmic/clojure
23:18hiredmanclojure is in freebsd ports and it comes with a launcher script
23:19danlarkinit's in gentoo portage too
23:19technomancythere's one in contrib, it just belongs in clojure
23:20danlarkinit belongs in clojure proper *and* it needs to define a standard library path for each architecture IMO
23:21technomancyhrm; well if I can't make any headway on calling Maven from the Java API I will have to fall back to plan B; just writing a pom.xml and shelling out to mvn. =\
23:21duck1123danlarkin: I think I would be afraid to put too many libraries in a system-wide classpath
23:22dnolen_duck1123: why is that? they don't get loaded until you load them. aren't OS libs set up this way?
23:22danlarkinduck1123: well it'd just be a clojure classpath, and I don't think it affects the JVM at all until you load them
23:22technomancythere's a limit on the size of environment vars
23:22hiredmanthe java guys seem to recommend against a system wide classpath, I'm not sure why
23:22technomancyyou're going to have conflicting versions of the same jars on it too
23:23danlarkinthis is one of the things I really disdain about the jvm :-/
23:23dnolen_well listing a bunch of .jars can be avoided with
23:23dnolen_-Djava.ext.dirs
23:25hiredmandnolen_: but that does not always work
23:25dnolen_when doesn't it work?
23:25hiredmanI don't recall :P
23:25dnolen_:)
23:25technomancyany good examples of clojure.xml usage?
23:25hiredmanand I never figured out why
23:26technomancythe test suite is empty. =\
23:26dnolen_well it's worked for me, I'm moving all my jars there, will report back when it explodes.
23:26hiredmanChouser ran into it too, for all he recomends using java.ext.dirs to people
23:35dnolen_soon as somebody has a tool and tutorial, I'll use it, first in line.
23:36hiredmansetting java.ext.dirs also overwrites the default value which is the place where stuff like crypto extensions get installed
23:39danlarkinso really, the way java "solves" this problem is that each project I start gets a full checkout of all its deps, including clojure.jar and clojure-contrib.jar? How heavy weight does it become to play around in the repl, or use emacs & slime in that case?
23:40hiredmaneh?
23:41hiredmanI just throw everything in ~/.jars/
23:41dnolen_hiredman: interesting, tho it looks like there's a lot of confusion about the relationship between -cp and java.ext.dirs
23:41dnolen_lots of article saying that they can't be used together, when I'm doing that right now with Clojure.
23:41hiredmanjre6 supports wildcards in the classpath
23:42hiredmanCLASSPATH=$HOME/.jars/*