#clojure logs

2009-08-31

00:13Anniepoowhat's the difference between clojure.main and clojure.lang.Repl?
00:24rlbAnniepoo: main is for running applications, Repl is for an interactive read-eval-print loop.
00:24rlbi.e. a prompt
00:26AnniepooOther than that main exits after loading it's cmd line arg scripts and the Repl gives, obviously, the Repl, are there differences?
00:28Anniepoorealized while doing some work on a project involving Clojure on Google App Engine that I'm slightly fuzzy on this stuff
00:29rlbI don't know offhand. I imagine they might set up the environment a bit differently.
00:29Anniepoook, thanks rlb
00:29rlbsure
00:30hiredmanclojure.main is newer and combines clojure.lang.Repl and Script
00:30hiredmanwith a few extra doodads
00:31Anniepooah, thanks
00:50j-dotAnniepoo: have you had any specific problems incorporating Clojure in an App Engine project?
00:51benatkinCan anyone tell me why (let [+ 3] +) evals to 3, while (let [+ 3] (::+ + 4)) evals to 4, and not 7?
00:52j-dot,::+
00:52clojurebot:sandbox/+
00:52j-dotthe ::+ does not represent the function clojure.core/+
00:53j-dotit represents the keyword :current-ns/+
00:53Anniepooj-dot - no, it's gone amazingly smoothly so far
00:53Anniepoomike hinchy's got more expertise doing it, he gave a talk at baclojure on it
00:53j-dotAnniepoo: glad to hear :)
00:53j-dotnice
00:53Anniepoobut we're doing it, and I'm new to Google App engine, my partner doesn't know Clojure
00:55Anniepoohmmm.... I've got slime running in emacs, I think I've got swank in emacs talking properly to swank-server in an external repl, but slime is attempting to evaluate my clojure as lisp
00:55j-dotI haven't done much more than play, but I've had good luck so far with this: http://github.com/jmcconnell/appengine-clj/tree/master
00:56benatkinj-dot: thanks. I didn't account for the possibility that ::+ wasn't adding. I thought it would have barfed on the number 3 as its first param, though.
00:56Anniepoohey, thanks!!
00:57j-dotmy pleasure
00:57Anniepooyah, this is amazingly great, it will save us a ton of work
00:57j-dotglad to hear!
00:59j-dotbenatkin: I haven't looked into it, but I bet that ::+, when applied as a function, is seeing that it can't be applied to the value +, since it's not a map, and is returning the default value 4
00:59j-dotanyway ... off to bed for me
00:59benatkinj-dot: g'night. I figured out that keywords just return their default value when you don't use a hash :)
01:15AnniepooI've got slime up and running, apparently, in emacs, but C-x C-e still gives me lisp
01:46noidiwhen defining a map, is it possible to refer to another key's value?
01:47noidisomething like {:r 5, :d (* 2 (% :r))}, where the % would refer to the map itself
01:49ambientAnniepoo C-c C-k evaluates the full file for me and C-M-x evaluates expression SLIME/Clojure
01:49ambientiirc
01:49Anniepoothanks ambient
01:49ambientthose can be found on the SLIME menu i think
01:49AnniepooI see no menus
01:50ambientemacs -nw? use the gui
01:50Anniepoowindows native emacs
01:50Anniepooit trashes it's menus when I load .emacs
01:50ambientwell i have that also
01:51Anniepoosomehow I'm clobbering them when I get the slime stuff going
01:51ambientstrange
01:51Anniepooand C-M-x gives me lisp, not clojure, as well
01:52ambientwell then it's well and borked
01:52Anniepoook
01:52Anniepoothat's useful to know, thanks
01:52ambientwhy not just install ClojureBox?
01:53ambientjust set HOME to your user directory so .emacs goes to the right place
01:53Anniepoohmm... I think it's getting the right emacs
01:53Anniepoos/emacs/.emacs/
01:54ambienti wrote down how I did the whole install thingie http://tommih.blogspot.com/2009/08/emacs-clojure-and-windows.html
01:54Anniepooah, lovely
01:54Anniepoothanks
01:55AnniepooI'm afraid to follow it, danlei spent like 5 hours helping me get this set up
01:56ambientwell it's not that hard, just set some paths, install git, ant, java and clojure-mode and hit GO
01:56ambientdone
01:56tomojdamn, 5 hours?
01:56tomojis your emacs like, totally pimped out?
01:56Anniepoono
01:56AnniepooI'm a complete emacs noobie
01:58Anniepoodoes this get slime and swank and such?
01:58ambientthis has pretty cood "cheat-sheet" for all things emacs & clojure http://lifeofaprogrammergeek.blogspot.com/2009/03/learning-clojure-and-emacs.html
01:58ambientyes
01:59ambientbut I'd recommend just installing ClojureBox
01:59ambienthttp://clojure.bighugh.com/
01:59ambientjust click a button and everything works
01:59Anniepoook, this looks like it might do it
02:00AnniepooI'll save off my .emacs and try it
02:00Anniepoodanlei will kill me
02:00ambientand .emacs.d
02:03AnniepooPray for my soul
02:04ambientyou probably had just one line wrong on the .emacs anyway :D
02:04Anniepoooh, it was a long saga
02:04ambientit's not that complicated
02:04ambientELPA & clojure-install make things extremely simple
02:06tomojapparently clojure-install doesn't work on windows
02:07ambientum, it does. I did it twice yesterday, with windows 7 and windows vista, separate machines
02:07tomojmaybe depends on which git you have then
02:07ambientyes, it does, and also ant, and java
02:07ambientif you don't have those in the path it will break
02:08tomojif you use cygwin git then it has no chance of working, right?
02:08tomojI dunno, I'm just speculating, I haven't touched windows in years
02:08ambienti have no idea
02:09ambientyou could just probably make a link of the executable and place it in emacs root in the worst scenario
02:11AnniepooI seem to be in a slime repl
02:11ambientwrite (+ 1 1) and (defn foo [x] (+ 1 x)) and stuff to see if it works
02:12Anniepooseems to be
02:12Anniepooand I typed in some clojure that isn't valid CLisp to make sure
02:13ambientim using mostly REPL myself to learn Clojure
02:13ambientalt-n and alt-p rewind and forward the previous commands
02:14AnniepooC-M-x isn't producing any visible results
02:15ambientit only works when you have file open and click definitioni in that
02:15ambientin repl you just press the enter key
02:15Anniepoook, my mistake
02:15ambientbut yeah, im still myself learning slime and emacs, there are a lot of useful keybindings
02:16AnniepooI opened a file, typed in (+ 1 2) I get 3 in the minibuffer
02:16LauJensenAwesome :)
02:16Anniepoobut if I change it to a println the output doesn't appear
02:17Anniepooah!
02:17Anniepoooutput is at repl
02:17Anniepoo8cD
02:17LauJensenAnniepoo: You're on SLIME now ?
02:17ambientyou do know how repl works?
02:17AnniepooI'm snug as a bug in a rug, happy as a clam
02:18Anniepoowell, I know what a repl is, I've used one befor
02:18Anniepoobefore
02:18AnniepooI'm coming off using intellij to write clojure
02:18Anniepoo(feel like I'm coming off heroin)
02:18LauJensenAnniepoo: You're on SLIME now ?
02:18AnniepooI am indeed sliming away
02:19AnniepooI'm all slimy
02:19ambienti dont even know how to paste into emacs from windows
02:19ambienti probably should find out
02:20LauJensenAlright, then just one word of caution. Printlns and similar outputs to *out* will go into the slime-repl-buffer, except when its coming from a thread, then it will most likely go into the inferior-lisp-buffer, or sometimes, no buffer at all :) Has tripped me up a few times
02:20LauJensenC-y = paste
02:20Anniepooah, good to know
02:20AnniepooC-y isn't doing it for me
02:20LauJensen(setq x-select-enable-clipboard t)
02:20LauJensenAdd that to .emacs or eval in ielm
02:20clojurebotemacs is best configured for Clojure with instructions at http://technomancy.us/126
02:20ambientLauJensen gracias
02:21LauJensennp
02:21ambientstrange though, it didn't work previously
02:23Anniepooany idea where clojure-box will put .emacs?
02:23ambientC-x d <enter>
02:23tomojone thing I found pretty cool about slime is that the slime-inspector shows java methods
02:23ambientand you're in that directory
02:23ambienttomoj how?
02:23tomojso if you do C-c I Math <RET>, you see all the methods in java.lang.MAth
02:24tomojit doesn't know how to look at clojure stuff yet though :/
02:24ambientum, clojure stuff works with just tab, right?
02:24tomojwell completion
02:24ambientC-c I is undefined :/
02:25tomojwell, the function is slime-inspect
02:25tomojguess I got a binding from somewhere
02:25tomojalso C-c C-d d (slime-describe-symbol) is cool
02:25LauJensenambient: C-c I (capital i) ?
02:26ambientyes
02:26Anniepooah, for others interst it's in application data
02:26LauJensenAnniepoo: Is Clojurebox using technomancys install-mode ?
02:26ambientAnniepoo set HOME environment variable to your home dir
02:26ambientand then copy .emacs* there
02:27LauJensenambient: C-h b ?
02:27ambientperhaps I should revise my clojure installation according to technomancy
02:27Anniepooclojurebox thinks hope is the application data dir
02:29ambientLauJensen nvm I was in the wrong buffer
02:29Anniepooah, lovely.
02:29Anniepoofixing my HOME even got my menus back
02:31ambientis there any way to get a listing of all working SLIME functionality with clojure?
02:31ambientsome functions seem to be unmapped
02:31ambientor not working
02:34ambientback to reading this http://common-lisp.net/project/slime/doc/html/
02:34Anniepoostrange, now it won't let me make a new file
02:35jdzit?
02:35Anniepooemacs
02:35jdzhow are you doing it?
02:35LauJensenAnniepoo: Given what reason ?
02:36Anniepooah, it's just the windows menu is somehow messed up
02:36ambientC-x b shows all buffers
02:37LauJensenC-x f => find / create files
02:37ambientidk what logic the buffers menu uses, but it often seems to be missing some entries
02:37jdz* C-x C-f
02:37AnniepooC-x C-f threw me into some weird non GUI file browser in a buffer at one point
02:37Anniepooand the actual windows file->new menu is borked
02:37jdzthat's what you want most of the time
02:38jdzwho'd want to browse through tons of folders by pointy-clicking when you can easily find what you want with tab-completion?
02:38Anniepooyah, but I couldn't figure out how to make a new file in that
02:39LauJensenjdz: and besides, ido-find-file, you just type boostrap.clj, and it'll find the file for you, no matter where its hiding :)
02:39ambientbootstrap.clj?
02:39jdzAnniepoo: you just type the path, and the file will be created when you save it.
02:40jdzAnniepoo: type the path in find-file query
02:40LauJensenJust at example. Ido keeps a history of your files, so you never have to type the fullpath, just the name or part of the name
02:40Anniepooyah, just their attempt to add 'real' windows menus is borked
02:40ambientoh ok
02:40Anniepooah, lovely,
02:40Anniepooswimming in info, but there's something called ido?
02:41Anniepoocause file browsing is pretty absurd
02:41ambientM-x ido- <tab>
02:41ambientM-x is pretty sweet with tab completion
02:43LauJensenAnniepoo: I believe that if you (require 'git-emacs) in your .emacs, it will automatically give you git integration AND ido. So that C-x f from now on will complete paths for you. just type "core" for instance, and way a sec, it would find "/foo/bar/core.clj" if you've previously accessed it
02:43jdzagain, it's C-x C-f
02:44AnniepooI seem to have ido
02:44AnniepooM-x ido- tab gives me a buffer with a bunch of commands
02:44Anniepooso what's this thing do?
02:44LauJensenYou have it, but its not bound and loaded
02:44LauJensenI gotta jet, be back l8r
02:44Anniepoothanks for the help
02:45jdzAnniepoo: most probably you'll want to bind C-x C-f from plain find-file to ido-find-file in your .emacs
02:45Anniepoofoo, lost paredit
02:47Anniepooand am getting smart indent 8cP
02:48Anniepoowell, thanks all
02:49Anniepoohave beaten myself enuf 4 2nite
03:34carkhttp://java.ociweb.com/mark/stm/article.html
04:01ambienthow do i trigger time-based events in clojure?
04:01ambienti have a stack that has different time stamps sorted in chronological order, pop takes the first one
04:02ambientand according to time, i have to trigger those events but i dont want to write a busy loop
04:02tomojwhat other possibility could there be?
04:02ambienteg. callbacks
04:03ambientbecause the next time is always known when the event triggers
04:03tomojbut someone has to call a callback
04:03ambientbusy loops are so ugly :(
04:03ambientoh well...
04:04tomojisn't pretty much everything running on your computer a busy loop?
04:04ambientin theory there has to be only one busy loop
04:04jdzthreads are used for this usually,
04:05hiredmanambient: there are all kinds of cool stuff in executors
04:05tomojyeah, mabye I dunno what a "busy loop" is
04:05ambientwhile 1: do stuff until break
04:06ambients/1/true
04:06hiredmanhttp://gist.github.com/178350
04:06tomojoh, I thought you meant spawn a thread that checks if the task's time has come and then sleeps for a bit
04:06ambienthiredman nice, thanks
04:06ambienttomoj well i could do that also, then the loop would be in that thread
04:07tomojyeah
04:08hiredman (sched/fixedrate {:task #(dump-dict-is config) :start-delay 1 :rate 10 :unit (:minu
04:08hiredmaner
04:09ambientalthough if i know the time difference i can just call (Thread/sleep time-delta)
04:09ambientheureka
04:09hiredman (sched/fixedrate {:task #(dump-dict-is config) :start-delay 1 :rate 10 :unit (:minutes sched/unit)})
04:09ambientthe rate is not fixed
04:09tomojambient: do people in your locale say "heureka" or do you just know greek?
04:10tomojeveryone around here says just "eureka"
04:10ambientit just felt right
04:10ambientno, people in my locale dont speak greek
04:11tomojI thought maybe in other places "heureka" is just the word they use
04:11tomojwhich would be awesome
04:11ambientwell i think it is so
04:12ambienthttp://fi.wikipedia.org/wiki/Heureka
04:18eevar2ambient: java.util.Timer & java.util.TimerTask?
04:18hiredman:(
04:18Fossigerman, finish and polish seem to be those that keep the h
04:19hiredmanthe scheduling stuff from the executors framework is much better than Timer
04:19tomojI'm guessing in english we lost all the h's that didn't come through latin
04:20eevar2though the stuff in java.util.concurrent is probably better, yes
04:44triyoI see the apply and reduce functions can perform the same action cases I have tried. """(apply + [1 2 3])) -> 6 AND (reduce + [1 2 3])) -> 6""" What is the major difference between the two?
04:47tomoj(apply + [1 2 3]) means (+ 1 2 3)
04:47tomoj(reduce + [1 2 3]) is like (+ (+ 1 2) 3)
04:48tomojthey happen to be the same for + but won't be the same for most functions
04:48triyotomoj: thanks. I see though that apply wouldn't always return the same result as reduce of course...make sense now reading the doc string
04:49tomojin most of the places I use reduce, apply would cause an error
04:49tomoj(most functions don't take an arbitrary number of arguments)
04:50jdzarbitrary number, which can also be infinity :)
04:50tomojI think reduce is faster with +
04:52tomojand it works better with lazy seqs, I believe
04:52jdzbetter how?
04:52tomoj(apply + (range 10000000)) blows my heap, but (reduce + (range 10000000)) works fine
04:52tomojreduce doesn't need the whole seq at once, apply does
04:53jdzi remember apply not needing the whole sequence at once...
04:53jdzmight be some specific cases
04:53jdzoh, right
04:53tomojhow could it not? it has to pass the whole seq as arguments to a function
04:53jdzin case a function has a &rest parameter
04:53tomojah, yeah
05:04tomojyup, true
05:04tomojthat's pretty neat
05:06tomoj(apply + ..) only seems to be slower than (reduce + ..) if you're not holding the head
05:12tomojbut in that case I'm seeing a 35% speedup
05:16LauJensenAny nginx experts here?
05:17LauJensennginxperts? :)
05:17tomojI've used it.. wouldn't say I'm an expert
05:18LauJensenI'm using it to proxy all requests to port 80 to my jetty server on another port. The problem is my logging in Jetty shows all users to come from 127.0.0.1 - how do I get around this?
05:19tomojyou've just got "proxy_pass ..."?
05:19eevar2LauJensen: http://forum.nginx.org/read.php?2,4805,4809
05:20tomojindeed
05:20LauJensentomoj: yea
05:20eevar2the proxy_set_header bits in particular
05:20tomojI think the block here should be enough http://wiki.nginx.org/NginxHttpProxyModule
05:20LauJensenoh yea, great if that works
05:20LauJensenfantastic
05:21LauJensenClojure community never ceases to amaze me with its versatility :)
05:21tomojI still don't really understand deploying jetty stuff :(
05:23LauJensenWhat dont you understand?
05:25tomojin the ruby world there's no threading really
05:25tomojso you have nginx proxy to a cluster of processes
05:25tomojbut I'm thinking maybe you only need one jetty instance on each box?
05:26tomojnever did any java web stuff so servlets and all are new to me
05:26eevar2one jetty instance should do, yes
05:31LauJensenJetty can listen of a given port using run-server. It takes an argument of a servlet and each servlet handles various routes, ie "/" "/foo" "/favicon.ico" and so on. I recommend loading your namespaces from a central boot.clj, which then opens your sites/servlets on various ports.
05:31LauJensen(I'm speaking of Compojures approach)
05:32eevar2anyone had a look at nginx built-in caching support?
05:32LauJensenno - but I've just tested, and that snippit puts another field in the header, so now I'm logging all IPs :)
05:33LauJensenmysql> select remote from traffic;
05:33LauJensen+----------------+
05:33LauJensen| remote |
05:33LauJensen+----------------+
05:33LauJensen| 90.185.128.253 |
05:33LauJensen| 90.185.128.253 |
05:33LauJensen...
05:33ambientwouldnt it be a good idea to build a sql frontend for mysql too in clojure?
05:33eevar2which headers did you have to set? x-real-ip, x-forwarded-for, or both?
05:34eevar2and host?
05:35LauJensenambient: You mean like ClojureQL ?
05:35ambientoh man, this concurrency thing is giving me a headache
05:35LauJenseneevar, just x-real-ip
05:35eevar2oki
05:35LauJensen~clojureql
05:35clojurebotclojureql is http://gitorious.org/clojureql
05:35ambientLauJensen oh, you've already done so :)
05:36LauJensenYes sir, its also what I use for logging traffic on my site, like http://groups.google.com/group/compojure/browse_thread/thread/2f1729608be2b072
05:36LauJensenI was looking for some feedback on it. Am I logging the right stuff? To much, to little?
05:37ambientset different log levels and you can switch on/off when you feel like it *shrug*
05:38LauJensenI already have that, but its rolled in a debug macro, which goes quote verbose when its on
05:39LauJensensomething like
05:39LauJensen(debug "launching thread" "launched" (send-off 0 (myfunc)))
05:39LauJensenTIMESTAMP: Launching thread
05:39LauJensenTIMESTAMP: launched
05:39LauJensenTIMESTAMP: Theads own debugging...
05:42tomojwhat's (send-off 0 ...) ?
05:42eevar2LauJensen: I think most existing logging libraries do buffered, asynchronous, logging, btw
05:43eevar2committing every entry to the db might add some overhead
05:43LauJenseneevar, its a good idea to do it async, each transaction runs at ~10 msecs. I'm mostly interested in the data I'm trapping right now. Is it enough for doing statistics later on, or should I get more ?
05:45LauJensenHmm, the buffer is a good idea. I should cluster about 500 rows together before committing, having an agent which checks regularily.
05:45LauJensenCalling mysql 10 times per visitor can quickly flood the cpu
05:46eevar2i'd just leave it to the web server tbh. ;)
05:46LauJensennginx supports dropping logs in mysql ?
05:46eevar2you could always import them later
05:47eevar2if you ever add caching, some requests won't actually hit the app server either
06:01tomojhas anyone tried decreasing the wait times in ants.clj? seems to screw things up
06:02LauJensenWay back when, yea I think so. Dont remember anything breaking though
06:04tomojI guess 10ms for the ant sleep time just leaves no time to do the animation
06:04tomojso the animation locks up
06:22juhalapparently clojure compiles and loads a new class every time I call eval
06:22juhalsigh
06:23jdzwhy would you call eval?
06:23juhalbecause I need to evaluate clojure expressions
06:23jdzare you sure?
06:24jdzi mean, are they user-supplied and you have no control over them whatsoever?
06:24juhalyes
06:25jdzand what's bad about the compilation, then?
06:25juhalwell the expressions don't change so recompiling them every time doesn't make sense
06:26jdzthen don't
06:26jdzif the expressions don't change, why are you calling eval on them more than once?
06:27juhalbecause I need their side-effects
06:30jdzif nobody more knowledgeable than me offers something else, you can wrap your expressions so that eval returns function, which you can then call when you want
06:31juhalhmm that sounds like it could work, thanks
06:36jdzbut anyway blingly executing random code is not a very good thing to do...
06:37ChousukeThe mention of both side-effects AND eval makes me highly suspicious, but I have no idea what you're trying to do :/
06:50tomojhrmm.. clojure-http-client currently gives you the headers with keys being header names
06:50tomojbut header names are supposed to be case-insensitive
06:51tomojI can't think of a good way to fix this
06:51tomojyou could provide a function for looking up headers in the header map in a case-insensitive way, but this isn't as pretty as just using the headers as a map
06:51tomojwould be nice if the headers map had symbols as keys with the header names downcased, but that's not backwards compatible
06:52tomojin ruby I would just monkeypatch the header map to downcase keys before looking them up :(
06:57tomojs/symbols/keywords/
07:18AWizzArdIs it possible to have a regex which splits a string at the empty string following the regex [,;]? So, like splitting on , or ; but without consuming those chars?
07:20jdzregular expressions will create more trouble than they solve
07:39cgrandAWizzArd: #"(?=[,;])"
08:28AWizzArdcgrand: works, thanks
08:38LauJensen,(sort > (vals {:foo 5 :bar 2 :baz 10}))
08:38clojurebot(10 5 2)
08:38LauJensenWhats a pretty way to flip that back to the keys, so I get (:baz :foo :bar) ?
08:41Chouser,(map key (sort-by val > {:foo 5 :bar 2 :baz 10}))
08:41clojurebot(:baz :foo :bar)
08:42LauJensen(sort-by val) thats a new one. Thanks alot
08:45tomojnever realized how useful it is that maps act as seqs of mapentries
08:50LauJensenRich has a few good ideas like that :)
08:51tomojgoddamn't
08:52tomojmy university was like "oh hey looks like tom finished writing a scraper for the course schedule, let's change all the markup around!"
08:53LauJensenYea being an IT admin has its perks :)
08:54jdztomoj: you should instead wrote a program that writes course schedule scrapers :)
08:55tomojjdz: that's be a good idea, but the data's not stable so I don't see how I could do it easily
08:56jdzwhat do you mean data is not stable?
08:56jdzand it's not about being easy to do, but doing it once :)
08:56Fossi*couhg* xls *couhg* ? ;)
08:56tomojbut I mean, every time the markup changes, I need to have the program write a new scraper
08:57tomojbut by that time the expected data is all different
08:57jdzoh boy oh boy
08:57Fossiwow. not that i can't type, but i can't type twice as much today :)
08:57jdzhave you ever heard of machine learning thingie?
08:57tomojyeah but I don't have target data to train on
08:57jdzthen generate it
08:58tomojI mean I could go visit the site and manually scrape the data into some reasonable format
08:58tomojI guess doing that is easier than rewriting the scraper every time the markup changes
08:58jdznot to mention all the things you learn along the way
08:59tomojsomething like scrubyt, you say what the data should be and it figures out how to scrape it
08:59jdzoh, look, somebody has written the program for you! :)
08:59tomoj(or tries to)
09:00tomojthat one doesn't work for me though :/
09:00tomojfirst of all it's in ruby, not clojure
09:01tomojand second there are some special relationships my scraper-writing program would need to understand which scrubyt doesn't
09:01LauJensentomoj: Are you using enlive ?
09:01tomojLauJensen: yep
09:01LauJensenk, isnt it a simple change to adapt it ?
09:01tomojthis time it is, I think
09:02tomojbut in general it won't be
09:02tomojthe markup on the site I'm scraping is really bad
09:02LauJensenoh
09:03tomojso like in one table cell they have "MW<br/>F" and later in the row something like "2pm to 3pm<br/>10am to 11am"
09:03tomojand that means the class starts at 2pm on monday and wednesday but 10am on friday
09:04tomojstuff that enlive can't do on its own, so I have to have logic after pulling stuff out with enlive, and that logic could be painful to change
09:04tomojthey're government workers though so since they just made a change it'll probably be a long time until the next change :)
09:06LauJensentomoj: File a feature request, I'm sure cgrand has a one-liner which both scrapes the website and gets the goverment workers fired.
09:06tomojhaha
09:07tomojI actually work here too but not in the department that does this stuff.. wish I could convince them to just put it up as XML or JSON
09:07tomojactually they must have some internal machine-readable representation because counselors get the data in a different interface.. hmm
09:09LauJensenhehe, now you're thinking
09:11Chouserin my experience, constantly fixing a fragile web scraper is often more reliable and less work than getting access to the machine-readable format internal to the organization.
09:14tomojyeah, I don't think they'd let me at that anyway
09:14tomojI'm not sure they'd even let me scrape it if they knew I was doing it
09:23rabidsnailIs there a clojure equivalent to Python's locals() function?
09:24jdzwhat does it do?
09:24rabidsnailIt gives you a map of all of all of the variables in the current context.
09:25jdzcurrent context?
09:25rabidsnailcurrent scope
09:26jdzi'm pretty sure there is no such function
09:26jdzbecause you can see all them variables by looking at the source code
09:26jdzthe don't magically appear while the program is running
09:26Chousernot really -- you might be able to use the JVM debugging api to get at some of that, but I'm not sure.
09:26rabidsnailbother
09:27jdz*they
09:28rabidsnailDjango uses it to stick all of the local varaibles in error pages when debug mode is on, for example
09:28rabidsnailIt's very useful
09:28jdzthen what Chouser said
09:41gkoIs there an operator to return from a function, like Common Lisp (return ...) or (return-from ...) ?
09:42ole3no
09:42ole3gko: no
09:46triyoI am trying to understand the difference between defining metadata for an object using #^{} and with-meta. If I use the former, (println (meta myfunc)) prints nil. However if I define the metada using with-meta then it print the metada of the object.
09:46Chousuketriyo: #^{:foo 'bar} assigns metadata to the *symbol* at read-time.
09:47Chousuketriyo: with-meta assigns it to whatever object you pass to it.
09:48Chouserjust to keep things confusing, the compiler or various macros often copy metadata from a symbol to some useful runtime object.
09:48Chouserdid I say confusing? I meant convenient.
09:48Chouser,(meta #^{:foo 'bar} [])
09:48clojurebot{:foo bar}
09:49Chouser,(let [my-vec []] (meta #^{:foo 'bar} my-vec))
09:49clojurebotnil
09:49Chousuke,(meta #^{:bar 'foo} foo) ; fail
09:49clojurebotjava.lang.Exception: Unable to resolve symbol: foo in this context
09:49Chousuke,(meta '#^{:bar 'foo} foo) ; no fail
09:49clojurebot{:bar (quote foo)}
09:49Chousukenote the location of the quote
09:50Chousuke,(meta '#^{:bar foo} foo)
09:50clojurebot{:bar foo}
09:50triyois the attr-map #^{} meant to do the same as with-meta?
09:51Chousukeno.
09:51Chousukeas said, with-meta happens at runtime. #^{} is read-time
09:52Chousukeand as such, #^{} is only useful for whatever the compiler can read.
09:52Chousukeeg. vectors, lists, symbols, maps, etc.
09:52Chousukeer, s/compiler/reader/
09:58triyoChousuke: oh I see. you need to quote the attr-map
10:07jdzhmm, that '#^{metadata here} symbol-name looks very very confusing...
10:07jdzhad to think about it like for 5 minutes until i understood what's going on...
10:09Chousuketriyo: no, it's actually quoting the symbol
10:09Chousuketriyo: the attr-map disappears after read-time
10:09Chousuke,(macroexpand '#^{:foo bar} test)
10:09clojurebottest
10:09triyoChousuke: got it now, I perfectly understand it. thx
10:10jdzye, there usually is no space between quote and the symbol :/
10:10Chousukeyeah, it's a bit weird.
10:10ChousukeYou need it with macros too, if you want to produce type-hinted code.
10:10jdzhaven't had a need for those yet
10:10Chousukeat least, sometimes
10:11jdzbut now i'll be better equipped
10:11ChousukeI wonder if I'm done toying with my chroots now.
10:11ChousukeI unstalled Debian stable AND unstable on my serverbox :P
10:11jdzmaybe writing '#^{meta data}whatever may help some. maybe not.
10:12ankouhi, anybody using slime here? If it try to use M-.(slime-edit-definition) on a function I get a NullPointerException
10:12jdzunstalling is like installing and uninstalling, all at once? :)
10:12Chousukeheh
10:13ChousukeI needed some newer software from unstable but didn't feel like keeping them up-to-date myself.
10:13ankou*but only with my own functions
10:13Chousukeso, I installed schroot and debootstrap'd myself a sid environment :P
10:13Chousukeand now I have a sid-shell alias that takes me to it
10:38AWizzArdIs there a simple way to do comp, but give the functions in reverse order, to match -> and the thinking? So, maybe a function pipe?
10:38stuartsierraSomebody wrote such a thing and posted it on the list, I think.
10:41stuartsierraMaybe this is it: http://www.mail-archive.com/clojure@googlegroups.com/msg08098.html
10:42stuartsierraAlthough (apply comp (reverse fns)) ought to work as well.
10:42gkoole3: OK
10:46stuartsierraOr just use -> in a #()
10:52AWizzArdMaybe I am one of the few who uses this regularily
10:56AWizzArdI have my own pipe function (not macro), which does essantially forward the evaluation to comp. But I find this could go into core. Users of comp will think first what should be done first, navigate with arrow keys back, then write down what comes next, use arrow keys again, and so on.
10:56AWizzArdPretty much like the ->
10:59ChouserRich has talked about adding a -> that puts the args on the right end instead of the left.
10:59ChouserI think the hold up so far has been the name
11:00stuartsierraI find I use -> and comp less than I expect.
11:01stuartsierraI started working on a Clojure package manager this weekend.
11:03stuartsierraBut then I wondered - how many Clojure "packages" are ready for a formal "release"?
11:05AWizzArdChouser: is that a new operator which turns around the args or will the existing -> require the reverse order?
11:06AWizzArdIt's just that comp doesn't match the way of thinking about it.
11:29AWizzArdChouser: is it possible to get the number of matches of a regexp and use it for substitution? For example, I want to replace all digits between 1-9 with a 9, but only for at least 2 subsequent digits.
11:30AWizzArdWhen I do (.replaceAll s "[1-9]([1-9]+)" "9$1") it does not replace each digit
11:30AWizzArd,(.replaceAll "Hello 1 and 2340" "[1-9]([1-9]+)" "9$1")
11:30clojurebot"Hello 1 and 9340"
11:30stuartsierraYou could try c.c.str-utils2/replace with a function as the replacement.
11:31AWizzArd,(.replaceAll "Hello 1 and 2340" "[1-9]([1-9])+" "9$1")
11:31clojurebot"Hello 1 and 940"
11:38ChouserAWizzArd: -> would not change
11:40AWizzArdChouser: good
11:40AWizzArd,(.replaceAll "Hello 1 and 2340" "[1-9](?=[1-9])+" "9$1")
11:40clojurebotjava.lang.IndexOutOfBoundsException: No group 1
11:40AWizzArd,(.replaceAll "Hello 1 and 2340" "[1-9](?=[1-9])+" "9")
11:40clojurebot"Hello 1 and 9940"
11:40AWizzArd,(.replaceAll "Hello 1 and 2340" "[1-9](?=[1-9])" "9")
11:40clojurebot"Hello 1 and 9940"
11:41Chouseris that the output you want?
11:43AWizzArdno, I hoped for "Hello 1 and 9999"
11:44AWizzArdno, I hoped for "Hello 1 and 9990"
11:44AWizzArdall digits between 1-9 shuold be replaced by a 9, if there are least 2 subsequent digits
11:45AWizzArdbut zeros inbetween may be a problem
11:47Chouser,(.replaceAll "Hello 1 and 2340" "[1-9](?=[0-9][0-9])" "9")
11:47clojurebot"Hello 1 and 9940"
11:48tomojI don't get it.. there aren't two subsequent digits after the 4 in 2340
11:48Chouser,(.replaceAll "Hello 1 and 2340" "[1-9](?=[0-9])" "9")
11:48clojurebot"Hello 1 and 9990"
11:49LauJensenGents, Im doing a webstat module and for this I need some webservice that I can post IPs to and in return I want information on names, adresses etc. Anyone of you know of such a service available freely?
11:49AWizzArd,(.replaceAll "Hello 15 and 4 and 0123/1234567890" "[1-9](?=[0-9])" "9")
11:49clojurebot"Hello 95 and 4 and 0993/9999999990"
11:49AWizzArd,(.replaceAll "Hello 15 and 4 and 0123/1234567890" "[1-9](?=[0-9][0-9])" "9")
11:49clojurebot"Hello 15 and 4 and 0923/9999999990"
11:50AWizzArdthere it doesn't catch the 5 of the 15
11:50tomojwhy would it? you're looking for two subsequent digits
11:50AWizzArdyes
11:50tomojthe 5 has none and the 1 has one
11:51Chousukeyou want to ignore non-digits for the look-ahead?
11:51AWizzArd"Hello 15 and 4 and 0123/1234567890" ==> "Hello 99 and 4 and 0999/9999999990"
11:52tomojso.. one subsequent digit?
11:52AWizzArdas soon there are two ore more subsequent digits replace in that sequence all 1-9 with a 9
11:52tomojok, two consecutive digits, I see
11:52AWizzArdoh ok, consecutive is the right word, thanks
11:53tomojsubsequent probably works too I just thought you meant something else
11:53AWizzArdbut maybe this should really be a function
11:54Chousukecan't you do [1-9]{2,} or something?
11:54AWizzArdi think it would then replace 12345 with 9
11:54tomojproblem is you don't know how many 9's to replace it with
11:54AWizzArdand not with 99999
11:54AWizzArdtomoj: right
11:55AWizzArdif there is just a single digit, not followed by a digit it can stay unchanged
11:55AWizzArdlike the 4
11:55tomojyou could search for a substring of two or more digits, get that match, then just regular .replace that substring with a string of 9's of equal length, and repeat until there are no more substrings of two or more digits
11:57kwatz,(.replaceAll "Hello 15 and 4 and 0123/1234567890" "(?<=[0-9])[1-9]|[1-9](?=[0-9])" "9")
11:57clojurebot"Hello 99 and 4 and 0999/9999999990"
11:58kwatzthough using lookahead or lookbehind usually feels wrong to me
12:01stuartsierrac.c.str-utils2/replace!
12:03AWizzArdkwatz: oh good, that works! stuartsierra: I am already looking at its source.
12:03tomojoh, my idea obviously doesn't work
12:03AWizzArdtomoj: why not?
12:03tomojbecause 99 is also a substring of two consecutive digits
12:03tomojso it just loops forever
12:04AWizzArd,(.replaceAll "Hello 15 and 4 and 0123/1234567890" "(?<=\\d)[1-9]|[1-9](?=\\d)" "9")
12:04clojurebot"Hello 99 and 4 and 0999/9999999990"
12:04AWizzArdkwatz: why it feels wrong to you?
12:05tomojto get my idea to work you'd have to replace the digits with nondigits and build up a list of indices to replace with 9's afterwards.. very ugly
12:06kwatzsometimes they can be hard to reason out, and it's logic that may deserve to be in a function
12:06kwatzmostly a personal preference, i supose
12:08kwatzsuppose*
12:17lisppaste8cgrand pasted "transients VS tail-call position" at http://paste.lisp.org/display/86304
12:18milepHello, when extending abstract java class with proxy, can I override the constructor?
12:19stuartsierramilep: no
12:19milepI'm trying to implement pircbot example from http://www.jibble.org/pircbot.php
12:20milepstuartsierra: ok, any tips how to do MyBot.java from that page ^
12:20milepsetName is protected
12:20stuartsierramilep: You can pass arguments to the superclass constructor.
12:21stuartsierraThen you'll have to use gen-class to expose the protected methods, I think.
12:22cgrandrhickey: OoM is an unpleasant side-effect of adding transients to a working fn (see http://paste.lisp.org/display/86304 )
12:22milepstuartsierra: ok, thanks for the tips, have to study more about that...
12:25Chouserreify can call protected methods, right?
12:25stuartsierraWhat's reify?
12:26cgrandnew new new name
12:26stuartsierraHa!
12:47pluijzerbin searching a while now, but is there a alternative for lisp's "position" in clojure?
12:52stuartsierrac.c.seq-utils has "positions" which is similar
12:52pluijzerthanks
12:56LauJensenGents, Im doing a webstat module and for this I need some webservice that I can post IPs to and in return I want information on names, adresses etc. Anyone of you know of such a service available freely?
12:57stuartsierrawhois?
12:57LauJensenSomething like that
12:58stuartsierraWhy not just use whois?
13:00LauJensenHmm :)
13:00LauJensenI think I will, thanks
13:32LauJensenwhois is slow, changing to buffered multithreaded webstatic strategy
13:32stuartsierra true, that
13:35LauJensenIts just the incentive I needed - Flushing webstats straight into sql with every call to the site was a bit too much
13:45alinp,(reduce + (range 0 9999999))
13:45clojurebot49999985000001
13:45alinp,(time (reduce + (range 0 9999999)))
13:45clojurebot49999985000001
13:45clojurebot"Elapsed time: 3382.242 msecs"
13:46alinp,*clojure-version*
13:46clojurebot{:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"}
13:49alinp,(System/getProperty "java.vm.version")
13:49clojurebotjava.security.AccessControlException: access denied (java.util.PropertyPermission java.vm.version read)
14:01LauJensenbestinclass.webstats> (country? "213.232.195.196")
14:01LauJensen"RU"
14:01LauJensenShould I be worried? :)
14:19rhickeyChouser: not sure yet about reify and protected - what did you want to call?
14:19hiredmanhttp://groups.google.com/group/clojure/browse_thread/thread/7538a136a39cce48?hl=en <--
14:19hiredmaner
14:19hiredman"Qi in Clojure (Shen) project underway"
14:20hiredmandoesn't actually look all that underway
14:23stuartsierraMost Clojure projects are not all that underway. (this morning's blog post http://bit.ly/1Va0o0 )
14:25LauJensenrhickey: Are you still considering names for new new ?
14:26rhickeyLauJensen: have you got one?
14:27LauJensenrhickey: Nope - But if its still open, we could have a rumble right here. You could say in as few words as possible what it does or what the name should express and we could all have a go :)
14:28rhickeyThe name should be able to express everything that 'refiy' does and somehow be better than reify
14:28rhickeyreify
14:28LauJensenhehe, alright
14:29LauJensenAnd just using 'extend' would be totally wrong?
14:29rhickeyJava distinguishes extend and implement, this would normally be used for the latter
14:30LauJensenAlright, it might be my english thats failing me, but leaving Java behind new new still has the feeling of extending a class to me
14:31rhickeyexcept it isn't a class but an interface, normally
14:31rhickeyextend means add something to, implement means provide a definition for
14:34ataggartdoes anyone know of some clojure-to-JMS code?
14:36rhickeyataggart: using thre JMS API directly is pretty easy - what are you looking for?
14:37LauJensenrhickey: alright, I'll think and read my dictionary
14:37LauJensenIn the mean time, why does the doc for send say "dispatch and agent", and send-off "dispatch a potentially blocking agent" ?
14:37LauJensen"dispatch and agent" = "dispatch AN agent"
14:40ataggartrhickey: nothing fancy, I just need to write a jms topic subscriber, figured I'd do it in clojure, and just wanted to see if there was some lib that would make it more idiomatic.
14:41LauJensenI mean - Arent both qualified for use with a blocking action?
14:41rhickeyataggart: wrapping queues is on my todo list, so I'm interested in use cases
14:41rhickeyLauJensen: no
14:42ataggartrhickey: I'll write bang this out, and send you anything I find useful.
14:42rhickeythe send pool is fixed size, you could exhaust it with blocking actions
14:42rhickeyataggart: what queue are you using?
14:42ataggartI believe we have an activemq instance running
14:43rhickeyI want to check out HornetQ when I have some time
14:43rhickeyI'm particularly interested in a model that scales from an in-process, direct embedded instance to full client-server
14:43ataggartI haven't done any work with jms before, so I'm not clear on how much of a "drop in" different implementations are
14:44duncanmanyone familiar with StAX/XMLEventWriter?
14:44duncanmis there a way to force <foo></foo> be written as <foo />
14:44duncanm?
14:47LauJensenConcurrent gentlemen, I have a website which generates an sql statement everytime somebody navigates the site. Every 5 minutes I'll commit all of these statements to the sql-server. Is this a good way to ensure not flushing an uncomitted entry from my buffer ref: (let [sql-statements @*sql-buffer*] (dosync (ref-set! *sql-buffer* []))... ?
14:50hiredmanwell, for starters ref-set doesn't have an exclamation mark
14:51LauJensenalright, scrap that then :) its just the approach
14:52hiredmanhmmm
14:53Chouserrhickey: I was wonder aloud about protected on behalf of someone trying to use http://www.jibble.org/javadocs/pircbot/
14:53LauJensentechnically the question must be, can an entry slip in, between the let-definition and the dosync. Which I actually think it can
14:53hiredmanChouser: for nick setting?
14:54Chouserin general, java interop sometimes requires overriding protected methods, and gen-class is a bit painful.
14:55ChouserI'm fully on board with reify being a native clojure rather than host interop feature, as long as we get something as pleasant to use as proxy with greater capability for interop.
14:56ChouserI'd be ok with proxy growing :exposes and :exposes-methods features
14:57hiredmanhttp://paste.lisp.org/display/83651
14:59stuartsierrame too
14:59cemerickrhickey: I did a little spelunking and some thinking, and I'm curious as to what you have in mind w.r.t. isa? caching that doesn't run up against the same issues a WeakHashMap memoization of supers is intended to solve (e.g. class unloading).
15:00Chouserhiredman: that was the kind of thing going around when rhickey put in super-proxy
15:00cemerickI actually think the current caching in MultiFn is a bit of a time-bomb w.r.t. retaining otherwise-unloaded Classes.
15:02hiredmanChouser: I was previously just seting clojurebot's nick after it connected, but now I am using that to access the protected setName method
15:02LauJensenNobodys got a take on how to flush a global ref ?
15:02Chouserhiredman: heh. nice.
15:02rhickeycemerick: I'm not sure class unloading is a solved problem in general
15:02rhickeybut specifically to use of WeakHashMap as a cache, what are you doing for concurrency?
15:03stuartsierraLauJensen: I think you want to put your SQL code inside the dosync
15:03stuartsierrano, wait, that's wrong
15:03hiredmanstuartsierra: :(
15:03stuartsierrasorry
15:04cemerickrhickey: nothing -- no entries should roll off the map, as long as the caller of isa?/supers is using that class (or an ancestor of it) as an argument
15:05LauJensenstuartsierra: ClojureQL prohibits sql transactions within dosyncs
15:05hiredmangood
15:05cemerickMaybe that's too trusting of class GC and WeakReferences, but it's contractually correct, I think.
15:05stuartsierraRight, it should. you shouldn't have side effects inside dosync.
15:05rhickeycemerick: so multiple threads calling supers just access the map without synchronization?
15:05LauJensenstuartsierra: but I should probably let dosync return the let value, that'll solve it
15:06stuartsierraLauJensen: you want to do something like (dosync (let [old-value @my-ref] (ref-set my-ref nil) old-value)
15:06LauJensenexactly
15:06stuartsierrasorry for the confusion
15:06hiredman~alter
15:06clojurebotalter is always correct
15:07cemerickrhickey: Yes. What's the downside, given that supers is working with entirely static classes?
15:08rhickeycemerick: my question has nothing to do with the caching behavior, has to do with proper use of a collection from multiple threads
15:08cemerickah
15:08cemerickwell, the results of super will be identical given the same argument, so worst case is the results get calculated a few more times than necessary
15:09cemerickand there's never any removes
15:09rhickeyno, the worst case is the map will be inconsistent on a lookup and produce garbage
15:09rhickeyyou start caching modi, I start read, boom
15:10rhickeyyou'll need to wrap that in a lock which will make supers a serialization point
15:10rhickey"Like most collection classes, this class is not synchronized."
15:11cemerickhaha -- been working with clojure too long :-)
15:11cemerickrhickey: yes, sorry, I'm using locking around accesses to the WHM
15:11cemerickI was thinking of transactions and such. :-|
15:11hiredmanI suppose you could manually wrap everything in a WeakReference before sticking it in the map
15:12rhickeyright, so, I've tried to avoid that kind of bottleneck in Clojure
15:12hiredman:|
15:12rhickeyhiredman: then you couldn't look it up
15:12hiredmanoh
15:12Chousercemerick: a persistent map of weak references stored in an atom?
15:12hiredmanright you are
15:13rhickeyI think there will be a concurrent weak hashmap in Java7
15:13rhickey?
15:13cemerickChouser: yeah, that'd probably be fine
15:13rhickeyany map using weak refs as keys won't support lookup without something extra
15:14rhickeysince weak refs have identity semantics
15:16rhickeymaybe a persistent map of hashes to weak refs of class+cached-value thingies
15:16Chouserin an atom
15:17rhickeylookup on hash, then dig in to check class and find data
15:17rhickeyyes, in an atom
15:17Chouser:-)
15:17Chousercould be a new joke template, like adding "in bed" to fortune cookie sayings.
15:19rabidsnailIf you ask low-level jvm questions in #java they look at you funny.
15:19rhickeyit does highlight how refs to persistent things are usually better than locks around mutable things
15:23cemerickwell, that certainly sounds better than trying to cache isa? relationships in general
15:23cemerickthere's too much dynamism in the hierarchies for me to be comfortable with the latter (or, with me implementing the latter)
15:24rhickeycemerick: sure, if you want to take a crack at that for supers I'll have a look
15:24rhickeybut the same strategy could be used for isa?
15:25rhickeyit's just a matter of remembering the hierarchy that was used as your basis, if not identical, toss cache
15:25cemerickPerhaps, but you'd have to get into invalidating relationships when a hierarchy is updated
15:26rhickeyno, just toss the cache
15:26cemerickoh, the whole thing?
15:26rhickeyyup
15:27cemerickjeez, in that case, we could just use a standard memoization
15:27rathore_sivajag: he
15:27rhickeycemerick: not with the class unloading
15:28cemerickrhickey: well, MultiFn has the same problem with class unloading
15:41rhickeycemerick: You are the one with a problem with it :) I wonder how real a problem it is
15:42cemerickrhickey: No problem per se, I just see where it *could* be a problem. I actually didn't make the MultiFn dispatch table connection until after I figured using a WHM was most prudent.
15:42rhickeyany value you use as a dispatch value can be captured by MultiFns, not just classes
15:43cemerickyeah -- I guess I'm just a little paranoid about being able to drop stuff into osgi environments, etc.
15:43rhickeybut if you do this for isa? it could be a model for a better version of the multifn caches
15:43cemericke.g. I wonder how many times people reload apps in their glassfish containers, etc.
15:49ambientis there a default directory structure i should use in a clojure project?
15:50rhickeycemerick: I agree there (containers) any global cache is tricky. I'd like to get away from a global set of namespaces even.
15:50Chouserambient: I like: projname/src/com/mydomain/projname.clj for sources, projname/classes/ for compiled .class files, then maybe projname/README
15:51ambientprojname/lib for libs?
15:51Chouserambient: clojure itsel inserts another level under src to separate .java from .clj code, directories named jvm and clj respectively
15:51cemerickrhickey: whoa, sounds like environments :-P
15:51rhickeyno
15:51Chouserambient: for external libs? yeah, I've seen some projects drop jars they need in a projname/lib/ dir
15:52cemerickrhickey: I know, just rocking the boat ;-)
15:52cemerickI'll take a crack at a thread-safe WeakReference approach tomorrow-ish, though.
15:52rhickeycemerick: you want to pass an additional env arg to every fn?
15:52rhickeycemerick: cool
15:52ambientok ty
15:52cemerickrhickey: no, certainly not
15:53cemerickI just remember us having roughly that conversation about 14-15 months ago.
15:53Chousercemerick: I think that's what IRC is for. Having the same conversation as often as possible
15:54ambientChouser I thought IRC was for typing random stuff on caffeine high
15:54rhickey:)
15:55cemerickChouser: what was remarkable about that conversation was that it was via email!
15:55cemerickLike, who ever does email anymore? :-P
15:57hiredmanclojurebot doesn't do email...
15:58hiredman(bugfixes welcome)
16:10cemerickdoes anyone else get a twitch under their eye when they read "patches welcome"? :-)
16:11Chousercemerick: no! I feel a surge of adrenaline that nearly masks the vague sinking feeling of my time slipping away...
16:11hiredmanwell that explains things
16:12Chouserhehe
16:12dave[csc]Does anyone have experience with the Clojure bundle for TextMate?
16:13cemerickChouser: ha!
16:14cemerickI happened to ask someone about Inkscape providing an OS X-native UI (rather than X11), and got "patches welcome", which was funny.
16:19dave[csc]No one uses TextMate to edit clojure eh?
16:19ChousukeI think emacs is the most popular editor. :)
16:20dave[csc]Humbug :P
16:21dave[csc]I love textmate, and the bundles, but I can never seem to get them to 'just work'
16:21ChousukeHm, I hate jokes that can't be translated ;(
16:22ChousukeI always get an urge to tell them to people who can't understand the language.
16:23ChousukeBut maybe I could make a joke out of translating them
16:24Chousukeand ending up with something that makes no sense to anyone.
16:25arbschtsounds a lot like porting code between computer languages
16:25hiredman~sense
16:25clojurebotNo entiendo
16:26ChouserChousuke: something like this? http://translationparty.com/#3751265
16:27ChousukeThat's perfect!
16:28ChousukeI suppose it doesn't work with Finnish. :/
16:30ambientso what's the joke?
16:31jensliFinnish has plentifull of, is it calls 'cases' in english? Maybe that is a bit like polymorfism.
16:31ambientFinnish is like elvish, it mangles words to give them different meanings
16:32duncanmi can't convince XMLEventWriter to write out <foo /> instead of <foo></foo> for me ;-(
16:35cemerickChousuke: I think we need a preferred-editor-poll :-P
16:35ambientis that an emacs command?
16:35Chousuke:D
16:46LauJensen~ozzilee
16:46clojurebotIt's greek to me.
16:46LauJensen~seen ozzilee
16:46clojurebotno, I have not seen ozzilee
17:00wtetzner_how are datetimes usually dealt with in clojure?
17:01wtetzner_is there an immutable datetime object, or do people just take a java datetime and construct a hash-map from it?
17:03stuartsierraI use Java Date and just don't modify it.
17:03wtetzner_ok
17:04stuartsierraThe Joda library is popular, as well.
17:04wtetzner_cool, i'll take a look at it
17:04wtetzner_thanks
17:07jensliYou could take a java DateTime and call (bean ...) on it?
17:09jensliOps, speaking .net here, Date it is
17:09stuartsierra,(bean (java.util.Date.))
17:09clojurebot{:seconds 28, :date 31, :class java.util.Date, :minutes 11, :hours 14, :year 109, :timezoneOffset 420, :month 7, :day 1, :time 1251753088119}
17:09stuartsierrathat works surprisingly well
17:10wtetzner_yeah
17:10wtetzner_jensli: thanks
17:11jensliBut how does that struct works with the Date methods?
17:11wtetzner_why is year 109?
17:12Chouserwtetzner_: years since 1900. yes, really.
17:12wtetzner_hmm
17:13Chouserpeople speak highly of Joda Time which apparently has an immutable date/time object.
17:13wtetzner_Chouser: yeah, stuartsierra mentioned it too
17:13wtetzner_looks pretty fancy
17:14stuartsierrahaven't tried it myself
17:16Chouseroh, sorry, missed that in the join/part noise.
17:17technomancywtetzner_: I wrote a wrapper for java.util.Date that translates between those and maps, but Date doesn't give correct behaviour for dealing with daylight savings and other time-based edge cases
17:17technomancyso joda is probably better if you need that
17:17wtetzner_technomancy: ok, thanks
17:17wtetzner_yeah, i think i'm gonna try going with joda
17:21technomancythe built-in JDK Date stuff is really horrible
17:22stuartsierraeh, it works for simple cases
17:24cemerickyeah, I've never had reason to stray. I know it's fundamentally shoddy, but... *shrug*
17:28wavisi'm experiencing some weirdness with the set function
17:29wavisI have a function that simplifies a common case where I use map, but instead of returning a seq it returns a set
17:30hiredman
17:32wavissorry got a call
17:33wavisso if i take out the set function, it doesn't run out of memory, and i can just apply the set outside, to the results of the function
17:33wavisand everything is hunky dorey. is there some weirdness with nesting a map within the #(set %) ?
17:34wavislike (set (map #(awesomeness %) bigseq))
17:34Chouser,(set {:a 1 :b 2}) ; like this??
17:34clojurebot#{[:b 2] [:a 1]}
17:34Chouseroh, that kind of map.
17:34wavisyeah
17:35Chouserhow big? I just put a million Integers in a set that way with no problem.
17:36wavisthere are a few tens of thousands of entries in bigseq, and each is a map like {:id 100 :name "tommy"}
17:36Licenserisn't map doing lazy sequs so mapping over a huge set would not instantly do much?
17:37ChouserLicenser: yes, but 'set' would force the whole thing.
17:37Licenserah okay
17:37Licenseragain I learned something :)
17:37wavisright. without the enclosing set function it returns instantly
17:37ambientwhat's the easiest way to transform [2 10 4 59 9 3 ...] sequence into [[2 10] [4 59] [9 3] ...]?
17:37stuartsierraI got memory errors with (count (set (map identity (range 1000000))))
17:37ambientim sure there's a single function for this
17:37Licenserperhamps pmap would hep here?
17:37Chouserambient: (partition 2 coll)
17:37stuartsierraLicenser: pmap won't help with the memory problem
17:38ambientChouser ok ty I need to look that up
17:38Licenserhmm string the data in half bits? *hides*
17:38Chouser,(count (set (map inc (range 1e6))))
17:38clojurebotExecution Timed Out
17:38LicenserI try it right now
17:38Chouserhm. inconclusive. :-)
17:38Licenser1:1 user=> (count (set (map identity (range 1000000))))
17:38Licenser1000000
17:38Licenserworks for me
17:39stuartsierraadd another zero
17:39Chouserthis is why I like the 1e6 notation
17:40stuartsierraBasically, if adding the set around the map is the only thing that causes a problem, it's probably because the set is too big to fit in memory all at once.
17:40drewr,1e17
17:40clojurebot1.0E17
17:40LicenserI don't really have a problem yet
17:41Licenserah here we go:
17:41Licenser1:3 user=> (count (set (map identity (range 10000000))))
17:41Licenserjava.lang.OutOfMemoryError: Java heap space (repl-1:3)
17:41Licenserout of heap space
17:41Licenserit seems to be a problem with recursion to me
17:41stuartsierramap isn't recursive
17:41Licenserkind of semi recursive isn't it? with loop I guess
17:42stuartsierraloop exists to avoid recursion
17:42Licenserit wasn't a memory problem, I hardly noticed the process to use more memory then before
17:42hiredmanmap doesn't use loop
17:42stuartsierraright, it's lazyor whatever
17:42ChouserLicenser: what happens if you drop the map, and use (set (range ...))
17:43Licenserspam :P
17:43LicenserI should have put count there
17:43Chouseror set your *print-length* :-)
17:43Licenser1:1 user=> (count (map identity (range 10000000))
17:43Licenser)
17:43Licenser10000000
17:44Licenserworks with no problem at all
17:44stuartsierraI think the problem is that Licenser had a sequence of maps, which take up considerably more space than an Integer.
17:44hiredmanLicenser: that is dropping the set
17:44hiredmannot the map
17:44Licenseroops sorry
17:44stuartsierraWhen you force the entire sequence into memory with "set", it's too big.
17:44wavisthere's more to this whole situation for me. the seq is lazily reading a large csv which can't fit in memory. is it possible that the function prevents cleaning up the streamed file?
17:44Licenserlet me test
17:45Licenserthe problem isn't that the set does not fit in the memory
17:45stuartsierraok
17:45Licenserit's aheap error not a you don't have enough memory error
17:45wavisno the set fits in memory fine. it's about 70k longs.
17:45Licenser1:1 user=> (count (set (range 10000000)))
17:45Licenserjava.lang.OutOfMemoryError: Java heap space (repl-1:1)
17:45Licenseryap there is something very wrongish
17:45wavisLicenser: oh
17:46waviswell i'll work around it for now with a do
17:46ChouserIs this legit? (let [s (atom! nil)] (defn my-singleton [] (or @s (swap! s #(or @s (MySingleton.))))))
17:47stuartsierraChouser: that's more or less what clojure.contrib.singleton does.
17:47LicenserI forgot which sutff I had to (use) to see the soruce code o.O
17:47Chouseroh, maybe I shuould just use delay...
17:48stuartsierraChouser: that too. c.c.singleton can do per-thread singletons too
17:48Chouserstuartsierra: oh, ok. thanks.
17:48stuartsierraBut someone pointed out to me that a global singleton is the same thing as a delay.
17:51LicenserI get the feeling the problem is in the implemetation of set
17:55Chouserit'd be nice if there was a handy conclusive test for a seq-head being held.
17:57stuartsierraRich suggested recently on the mailing list that more such cases can be avoided, but that doing so would require more sophistication on the part of the compiler.
17:58wavisoh interesting so set just uses apply
17:58LicenserI think to thinn I found teh bad guy
17:58Licenserbut I might be wrong
17:59Licenserset uses spread, which is recursive
18:00achimLicenser: recursion wouldn't blow the heap, but the stack, right?
18:00Licenserisn't the stack in the heap?
18:02wavisI just tried with (into #{} (map #(awesomeness %) bigseq)) and it still runs out of heap
18:04wavisand the same for:
18:04wavis(reduce #(conj %1 %2) #{} (map #(awesomeness %) bigseq))
18:05Chouseris that a chunked bigseq?
18:05wavishmm chunked?
18:06wavishow do i chunk something?
18:06Chouser(chunked-seq? bigseq) to find out
18:06Chousuke#(awesomeness %) is a bit redundant btw :P
18:06Chouserdepends on how the seq is built
18:07ChousukeI bet overuse of #() is the most common anti-idiom
18:07wavisnot chunked
18:07wavisk, i'll #() from here out if it's preferred
18:08Chouserand (set bigseq) works ok?
18:08jensliYeah, (fn ...) is so extremly verbose. Specially compared to Java.
18:08Licenserokay a bad recursion gives a stack overflow not a heap overflow
18:09Licensergood greif
18:09Chousukewavis: I mean, (map #(awesomeness %) foo) could be expressed as just (map awesomeness foo) :)
18:10hiredmanLicenser: the stack contains pointers to objects on the heap, basically
18:11LicenserOkay it seems java by default only uses very little memory o.O that seems to be the real problem
18:11LicenserIt does not just use the memory of your computer as much as it wants to
18:12LicenserI added -Xmx200m and now it runs way longer
18:12Licenserno Heap exception yet
18:12wavis(set bigseq) also run out of heap. and although i thought it worked before, now i'm losing on just > (map :stuff bigseq) > (set *1) in the repl
18:12wavisi have -Xmx512 so that's not it i don't think
18:13Licenserit just means that there is something very big ^^
18:14Licenserwow it still is calculating o.O
18:14wavisoh crap, do i really? *sigh* i set that halfway through and forgot the "m". I need -Xmx512m
18:14wavisso i need to retry some things
18:14Licenseroi
18:14Licenseryes with 512 it really won't go very far
18:15Licenser1:1 user=> (count (set (range 10000000)))
18:15Licenserjava.lang.OutOfMemoryError: Java heap space (repl-1:1)
18:15Licenser :(
18:16Licenserdoing (0.. 10000000).to_a in ruby it takes about 200 MB
18:17ambienttry forcing a type? im sure 1e10 big ints will take more than 1e10 32 bit integers
18:17Licenseryea it are fixnums not bignums
18:17Licenserbut still
18:17Licenserit is a good estimate
18:18Licensermaking a set takes about 200MB too
18:18Licenserirb(main):003:0> (s = Set.new((0...10000000))).size
18:18Licenser=> 10000000
18:18Licenserand oddly enough is way faster
18:18wavisok, nice, so (into #{} (map foo bigseq)) works fine
18:18Licensersomething seems very wrong wiht clojure there
18:18hiredmanhttp://books.google.com/books?id=dg7bj_e-SAMC&amp;lpg=PP1&amp;dq=jvm&amp;pg=PA9#v=onepage&amp;q=stack&amp;f=false <-- "Java Stack"
18:18Licenserhiredman: thanks
18:19Licenser(count (set (range 10000000))) is the same as (s = Set.new((0...10000000))).size or am I wrong?
18:20Licensercreating a new set with 10000000 elements and counting it's size
18:22hiredmanwell, not all sets are the same
18:23Licenserset as in a collection of unique values
18:23hiredman
18:24hiredmanso?
18:24hiredmanthat is a specification
18:24LicenserI just wonder why it is so sloow and crashes my JVM even with 200 MB of memory
18:24hiredmanit leaves a great degree of freedom on the implementation side
18:24ambientpremature optimization is premature optimization
18:27hiredman,(class #{})
18:27clojurebotclojure.lang.PersistentHashSet
18:27LicenserWell I'm not sure if it is premature to make things somewhat fastish. It is not like a exotic thing to have a set of values.
18:28Chousukehow many values, exactly?
18:28Licensermight the reason be that it can't convert the entire set due to immutability but has to do it element by element?
18:28hiredmanno
18:28Licenserplease don't get me wrong, I don't want to jump con clojure. I like the language, I just would like to figure out why it is so slow for this task
18:29Licenserhere it are 10_000_000 values
18:29ambient(count (set (range foo))) could in princible done lazily
18:29Chousukehmm, and each value is how big? :/
18:29hiredmanambient: it would be difficult to do and still retain the nice java interop clojure enjoys
18:30LicenserChousuke: simple fixnums
18:30Licenser(time (count (set (range 10000000))))
18:30ChousukeLicenser: don't forget they all need to be boxed though
18:31hiredman,(first (clojure.lang.PersistentHashSet/create (range 1e6)))
18:31clojurebotExecution Timed Out
18:31ambientusing (int 10000000) halves the time used
18:31hiredmanthe jvm doesn't have fixed nums, btw
18:32Licenserhowever they call it
18:33Licenserfor me it's running 7 minutes now
18:33Chousukefor 10 million it does 10 million allocations
18:33ChousukeI guess that takes some time
18:33Chousuke:P
18:34Chousukewhich version of clojure are you using btw?
18:34LicenserOkay if it is 'only' that it can be fixed later with some tricks I guess (like bulkallocating space for the boxes)
18:34LicenserClojure 1.1.0-alpha-SNAPSHOT
18:35Chousukehm, interesting
18:35Chousukeuser=> (time (count (set (range 1000000))))
18:35Chousukejava.lang.OutOfMemoryError: GC overhead limit exceeded (NO_SOURCE_FILE:0)
18:35ambienti'd rather have a real problem though.
18:35Chousukeyeah, microbenchmarks are problematic.
18:35ambientthis isn't even a microbenchmark
18:35Licensertrue, but it's a interesting thing still
18:36ambientthis is just bad coding
18:36Chousukeit might be unrealistic behaviour that throws off the optimiser and GC
18:36Licenserwell someone actually ran in that problem, that is why it came up. We didn't made it up
18:36Licenserso I think it is kind of real at least
18:37ambientthen you need to change your code from (count (set (range 1000000))) to 1000000
18:37ambientmuch faster that way
18:37Licenserthe count set was just an example to replicate the behaviour of the real code without needing all the dependencies around it
18:38ambientI think I have to take your word on that
18:39Licenser(set (map #(awesomeness %) bigseq)) <- that was the original problem
18:39Licenserabout parsing a big log file or something
18:39Licenserit was discussed about an houre ago if you want to look in the scrollback
18:41ambienti see only your solution to the problem, not the problem itself :/ correct me if im wrong
18:41Chousukehm
18:41Chousukeinteresting
18:42Chousuke(into #{} (range 1000000)) works but (set (range 1000000)) fails
18:42ambientbut alas, im a total newbie with clojure so im not much help
18:42Chousukemaybe set doesn't use transients
18:42wavisdo you need a test case? i can generate a large csv of gobble-de-gook, provide my csv parsing function, et ceteras
18:43Chousukeinto performance is not too bad either I guess.
18:43wavisbut I'm not sure that's necessary
18:43Chousukeboxing and inserting a million takes 12 seconds here
18:43hiredmanChousuke: should be almost the same
18:43Chousukehiredman: into works, set fails. the performance is quite different :P
18:43hiredmanipersistenthashset/create is just a for loop that uses cons internally
18:44Chousukehm, I wonder if I have transient sets yet
18:44hiredmanI have actually looked at the clojure set function
18:44hiredman~def set
18:44durka42~def hash-set
18:45Chousukehm, apparently no transient sets in my clojure
18:46achimset will realize the entire sequence before starting to consume it (args to apply must fit in memory), into doesn't do that
18:47hiredmanachim: that is not true
18:47durka42apply is lazy is it not
18:47Chousukeit is.
18:47Chousukehiredman: for some reason, (set) still fails and into doesn't.
18:47ChousukeI think it might be the chunkedness.
18:48Chousukec.l.PHS/create is not chunked, but reduce is
18:48Chousukeso, it does less allocation
18:48Chousukeand since I'm failing with "GC overhead limit exceeded" that might just be it.
18:49hiredman(time (first (set (range 1e7)))) runs fine with -Xmx1000m
18:51ambienthow can you take first from set?
18:51ambientisn't that undetermined
18:52achimhiredman: you're right
18:52hiredmanambient: first calls seq which returns a sequence
18:52hiredman,(first #{1 2 3})
18:52clojurebot1
18:52hiredman,(first {1 2 3 4})
18:52clojurebot[1 2]
18:53hiredman,(first [1 2 3 4])
18:53clojurebot1
18:53hiredmanetc
18:53hiredmanso first should work on anything that the seq function works on
18:53hiredmanachim: about what?
18:53ambienti feel conflicted by that kind of flexibility in data structures
18:53Licenser_bah internet died
18:54achimhiredman: but retains head, so args to apply really must fit in memory
18:54achimer
18:54achimbut "apply" retains head
18:54achimhttp://groups.google.com/group/clojure/msg/34b9a170d36c5ab5
18:54hiredman~def apply
18:56Licenser_~def spread
18:57hiredman,(let [f (fn [x & y] x)] (apply f (interate inc 0)))
18:57clojurebotjava.lang.Exception: Unable to resolve symbol: interate in this context
18:57hiredman,(let [f (fn [x & y] x)] (apply f (iterate inc 0)))
18:57clojurebot0
18:57hiredman*tada*
18:58drewr,(let [f (fn [x & y] x)] (apply f (range 1000000)))
18:58clojurebot0
18:58drewrit's pseudo-lazy, but that doesn't mean it doesn't retain head
18:58achimhiredman: that doesn't show it doesn't retain head ...
18:59Licenserwhen talking about lazy, I've to work tomorrow early :) good night everyone! And good luck with this!
18:59drewr,(let [f (fn [x & y] x)] (apply f (doall (range 1000000))))
18:59clojurebot0
18:59drewr,(let [f (fn [x & y] x)] (apply f (doall (range 1e10))))
18:59clojurebotExecution Timed Out
19:00hiredman,(let [f (fn [x & y] (first (drop 1e3 y)))] (apply f (iterate inc 0)))
19:00clojurebot1001
19:00hiredman,(let [f (fn [x & y] (first (drop 1e7 y)))] (apply f (iterate inc 0)))
19:00clojurebotExecution Timed Out
19:00Chousukehm
19:01ChousukeI think you're holding on to y in that case.
19:01Chousukebecause you're calling first
19:01Chousukeso when the (drop ...) is completed the reference to y still exists
19:02Chousuke... I wonder if I'm correct ;/
19:02cemerickare struct-maps transient-capable in HEAD?
19:18wtetzner_Chousuke: doesn't first just return the value of the first thing in the sequence? not the front of the sequence?
19:18hiredman
19:19wtetzner_so you wouldn't be holding onto y still
19:20Chousukewtetzner_: well, the drop of course won't return y, but I think it's still there because it's in the function's locals.
19:20wtetzner_oh, i see
19:20Chousukeand the drop call is not the tail call (at least I think it isn't)
19:20ChousukeI'm not sure how exactly it works
19:21hiredmanI'd have to replace it with a call to nth
19:22hiredmanI always forget about nth
19:22Chousukebut say you do (fn [x] (let [a (drop 1000000 x)] (first a))) then you will hold on to all of x
19:22Chousukethe compiler is not yet smart enough to optimise that :/
20:36powr-tocIf I have a list of functions '(f1 f2 f3) how would I best execute them?
20:36powr-tocsequentially...
20:40wtetzner_powr-toc: (doall (map (fn [fucn] (func)) '(f1 f2 f3)))
20:42durka42(doseq [f (list #(prn 1) #(prn 2) #(prn 3))] (f))
20:42durka42,(doseq [f (list #(prn 1) #(prn 2) #(prn 3))] (f))
20:42clojurebot1 2 3
20:43wtetzner_durka42's solution is nicer
20:43tomojwhy isn't there a "call" function
20:43durka42because you just call things...
20:43durka42there's apply
20:44wtetzner_,(.invoke #(prn 2))
20:44clojurebot2
20:44durka42,(#(prn 2))
20:44clojurebot2
20:45tomojbut .invoke can't be mapped :(
20:45wtetzner_,(.call #(prn 2))
20:45clojurebot2
20:45durka42#(.invoke %) can be mapped
20:45durka42as can #(%)
20:45durka42,(apply #(prn 2))
20:45clojurebot2
20:45tomoj#(%) looks cool but that's just weird
20:45tomojapply works, it seems
20:46tomoj,(map apply (list #(prn 1) #(prn 2) #(prn 3)))
20:46clojurebot(nil nil nil)
20:46tomojwell.. yeah
20:46durka42,(dorun (map apply (list irc://irc.freenode.net/#(prn 1) irc://irc.freenode.net/#(prn 2) irc://irc.freenode.net/#(prn 3))))
20:46clojurebotjava.lang.ClassNotFoundException: irc://irc.freenode.net
20:46wtetzner_,(map #(.invoke %) (list #(prn 1) #(prn 2) #(prn 3)))
20:46clojurebot(nil nil nil)
20:46durka42ehh... what's that, clojurebot?
20:46durka42,(dorun (map apply (list irc://irc.freenode.net/#(prn 1) irc://irc.freenode.net/#(prn 2) irc://irc.freenode.net/#(prn 3))))
20:46clojurebotjava.lang.ClassNotFoundException: irc://irc.freenode.net
20:46durka42hiredman: ???
20:47hiredmanclojurebot: huh?
20:47clojurebotGabh mo leithscéal?
20:47tomojyou've got "irc://irc.freenode.net/" in your code
20:47hiredmandurka42: what?
20:47durka42i do?
20:47tomojfrom here it looks like you do
20:47tomojapparently clojurebot thinks so too
20:47tomoj19:47 <durka42> ,(dorun (map apply (list irc://irc.freenode.net/#(prn 1) irc://irc.freenode.net/#(prn 2) irc://irc.freenode.net/#(prn 3))))
20:47hiredman
20:47durka42,(dorun (map apply (list #(prn 1) #(prn 2) #(prn 3))))
20:47clojurebot1 2 3
20:48durka42spooky copy and paste action
23:05LauJensenI've tried to add a threaded buffered logger to www.bestinclass.dk and now the site seems a bit slow to me. Can somebody here try to access it and let me know what they think?
23:19LauJensenGents?
23:25carkdo you mean the first access ?
23:27carkmhh if i was a corporate customer i wouldn't want my web site doing this accordeon thing
23:28carkbut it's responsive from belgium
23:37scottjAnyone use visualvm to profile? if my namespace is foo, do I put foo.* in the Settings box labeled "Start profiling from classes:"?
23:38scottj(I guess I wouldn't be asking if that was working for me :)
23:41scottjI start clojure from shell, run slime-connect from emacs, load code, launch visualvm and connect to jline.ConsoleRunner, change Profiler settings as mentioned, click CPU, it instruments 21 methods, then I go back to slime and run a 2 minute operation, and in the profiler nothing shows up except maybe a few things outside my app.
23:42LauJensencark: Thanks for both testing and giving design advice :) Yes it was first response I was worried about
23:42carkfirst response isn't very fast
23:42LauJensennot fast or slow ?
23:42carknah it's ok
23:43carki guess you have quit e a bit of javascript loading there
23:43LauJensenIts not that bad actually
23:44LauJensenThe amount of javascript that is. But I decorated my entire servlet in a buffered logger which keeps a certain amount of records in memory, flushing it every 5 minutes to SQL. I was afraid it was lagging somehow
23:45carkmhh but how could a logger slow things down ? even to an sql database ... do you plan to have millions page views ?
23:45carkthat's because you open a connection to the database per request ?
23:47cemerickscottj: I generally just exclude the junk I don't want, and profile everything (I use NetBeans/enclojure -- visualvm is based on the former)
23:48cemerickscottj: with good results, FWIW http://twitter.com/cemerick/status/3615358808 :-D
23:48LauJensencark: no no, like I said it flushes every 5 minutes, so it keeps a buffer. And I'm not saying I can explain how it would slow things down, it was just a 'feeling' :)
23:48carkok =)
23:49carksee i'm just pestering you because i'd like to see some connection pooling in clojureql !
23:49LauJensenhehe, are you following us on lighthouse? because its really quite close to implementation now
23:50carknope didn't know about it
23:50LauJensenlemme dig up the discussion
23:50carki've got it thanks
23:52LauJensenhttp://clojureql.lighthouseapp.com/projects/34981/tickets/4-allow-optional-global-db-conn
23:52LauJensenthis one right? We're still not in agreement, so you're welcome to add your wisdom to the equation
23:53carkwell i have a library doing generic pooling, i use it to pool memcached connections
23:53carkand was thinking maybe applying this to sql connections as well
23:54carkthough memcached is very slow now due to print/read serialization
23:54cemerickactually, one thing I miss from eclipse is *per-line* runtime stats while profiling. That was tremendous.
23:55cemerickObviously, only available in Java.
23:55LauJensencark: The discussion is not centered around technology, its more user implementation details. Unless I'm completely misunderstanding you since its 05:56 here :)
23:57carkmy fault i was digressing
23:57carkit's 6am here too ... i'm off to bed !
23:58LauJensenAlright, good night, and thanks
23:58carkgood night