#clojure logs

2010-02-04

00:13itistodayok, still working on converting that function, at least i have a couple lines of clojure code now that the api's back up
00:13itistodayhow to fix this: http://paste.pocoo.org/show/173729/
00:14itistodayerr, rather, this: http://paste.pocoo.org/show/173730/
00:19somniumitistoday: that style of closing parens is rather frowned upon
00:20itistodayi'm sorry, but to me it makes the code readable
00:21itistodaycall it a habit from years of C-type languages
00:21itistodayit lets me know where one block ends and another begins
00:21itistodayerr.. expression
00:22somniumitistoday: well, its likely to draw repeated comments
00:23itistodaysomnium: i hold my tongue when i see people piling on their parenthesis at the end even though I feel just as you feel about my coding style
00:24somniumitistoday: thats what the indentation is for :)
00:25itistodaysomnium: ok, if it will help you help me: http://paste.pocoo.org/show/173732/
00:25somniumitistoday: anyway, I would recommend reading about syntax-quote and experimenting with macroexpand-1
00:25tomojI guess I don't need to say "just use a decent editor for lisp" eh
00:26tomojwell, certainly not since the issue to which that's a response didn't actually come up-readability is different than editability
00:27somniumitistoday: http://mumble.net/~campbell/scheme/style.txt :)
00:27tomojI guess the standard response about readability is "you'll get used to it"? :(
00:28somnium"Rationale: The parentheses grow lonely if their closing brackets are all kept separated and segregated."
00:28hiredmanthe rationale is the people in the irc channels you ask for help on like it that way
00:29hiredman:P
00:29tomojfor me it would take more tabbing to reindent the lonely parens if I change something
00:29itistoday*sigh*...
00:29itistodayok... poor lonely parenthesis, excellent rational
00:29itistodayi'll tell that to my poor lonely braces
00:30itistodaybut i already broke in, gave in to conformity and your unreadable style: http://paste.pocoo.org/show/173732/
00:31itistodayand it still won't run :-p
00:32hiredmanitistoday: why?
00:32itistodayjava.lang.Exception: Can't let qualified name: user/col-syms (NO_SOURCE_FILE:32)
00:33hiredmanitistoday: no, why are you doing this?
00:33itistodayoh, i'm trying to see if it's possible to write this neat newlisp function in clojure
00:33hiredmanthat is a macro, not a function
00:33hiredmanand I would hardly call it neat
00:33itistoday*this neat newlisp macro
00:34itistodaythat's not it
00:34itistodayi'm building up to the newlisp one
00:34hiredmanwhy?
00:34itistodaylike i said
00:34itistodaythe newlisp macro is awesome
00:34DeusExPikachuI was connected to swank with emacs via slime-connect and then I got disconnected because the internet died. Unlike when I have a graceful disconnect via slime-disconnect, I can not reconnect. Is this a bug in swank? is there anything I can do to reestablish a connection to the remote swank server?
00:34hiredmanitistoday: I doubt that
00:34itistoday(for-query-with-db db "SELECT name FROM people" (println NAME))
00:34itistodaysee
00:34itistodaythat's awesome
00:35hiredmanhow?
00:35itistodayhiredman: how is mona lisa awesome?
00:35somniumitistoday: it vaguely reminds me of php :P
00:35itistodayphp can't do that
00:35itistodayand i'm wondering whether clojure can
00:35itistodayi assume it can
00:35somniumits good at mixing templating code with db access though
00:36itistodayyes, that's what i want it for
00:36somniumitistoday: it definitely can
00:36hiredmanthat is hardly different from what you would get from using contribs sql stuff
00:36itistodayhiredman: that's great
00:36itistodaysomnium: how?
00:36hiredmanexcept with the sql stuff you get a result seq, and you don't shadow names
00:37itistodayhiredman: it's not shadowing names either
00:37hiredmanit is
00:37itistodayno, really, it's not
00:37hiredmanwell, shadowing is not the right word
00:37itistodayit's only shadowing NAME in the body
00:37itistoday"shadowing" indeed
00:37hiredmanrandomly introducing
00:37itistodayand NAME isn't bound to anything
00:37itistodayyes
00:37itistodayactually no,and it's not random
00:37itistoday*it's not random
00:38itistodayit's really cool
00:38itistodayvery succinct
00:38hiredmanclojureql does that, and was recently called out in a blogpost somewhere for doing so
00:38itistodayclean is the word
00:38hiredmanit's not cool
00:38itistodayhiredman: you're not cool
00:38hiredmanqueries as strings are not cool
00:39itistodaylook, you don't find it cool, i do
00:39itistodayit's a matter of personal preference
00:39hiredmanitistoday: I'm not cool, I'm tired of your bellyaching about newlisp and passive agressive attempts to goad people into helping you by compare clojure and newlisp
00:39hoeckitistoday: don't worry too much about hiredman, what you want is possible in clojure
00:40itistodayhoeck: thanks, and i don't doubt that, but my clojure skillz are nonexistent at this point
00:40hoeckitistoday: in clojure.contrib.macro-utils, there is a symbol-macrolet macro
00:41somniumit can be done without symbol macros
00:41itistodayit's really hard for me to follow the docs though as they don't give examples
00:41hoeckthough your macro is more common-lisp style, clojure has a more functional aproach, map access is cheap, just (print (:name result))
00:42hoecksomnium: of course, but it looks like the most direct translation from his code would be to use symbol-macrolet
00:42hoeckbut correct me if I'm wrong
00:42somnium,(let [form '(print a)] (for [x (range 3)] `(let [~'a ~x] ~form)))
00:43somniumno bot?
00:45DeusExPikachufound it, ":dont-close true" is the solution
00:45DeusExPikachuat least, for the future
00:46somniumitistoday: whether or not the macro itself is desirable, its fairly easy with symbol capture, so again I recommend learning how syntax quote works and experimenting with macroexpand
00:46hiredmanor just using the sql library in contrib, or use clojureql
00:47itistodayhiredman: i will use clojureql when i need to do serious db stuff
00:47itistodayhiredman: right now i'm trying to learn clojure
00:47itistodayhiredman: i think clojureql is a very neat tool btw
00:48itistodaysomnium: can you give me an example to help me get started?
00:48itistodayi learn by example, and the docs have none :-(
00:48somniumclojurebot: ping
00:48clojurebotPONG!
00:49DeusExPikachuexamples in the docs can go a long way, I say
00:49somnium,(let [form '(print a)] (for [x (range 3)] `(let [~'a ~x] ~form)))
00:49clojurebot((clojure.core/let [a 0] (print a)) (clojure.core/let [a 1] (print a)) (clojure.core/let [a 2] (print a)))
00:49hoeckitistoday: something like your macro already exists in clojure.contrib.sql
00:50herdricktomoj: thanks for the blog post. i didn't realize you were getting error messages and ignoring them. (i might have been ok already)
00:50DeusExPikachubut the best examples lie in library code most of the time
00:50hoeckitistoday: (with-query-results ["select * from table"] result (println (:name result)))
00:51tomojI think installing slime before or marking it for installation along with the rest might have solved that error, dunno
00:51itistodayhoeck: i'm looking at the source, and it uses a with-query-results* function, don't know where that's defined
00:52tomojitistoday: what editor do you use?
00:52hoeckitistoday: in sql/internals.clj
00:52itistodaytomoj: right now just using textmate + clj
00:52tomojah, nevermind then
00:53hoecktomoj: but slime-find-definition works only if the clj-file is on the classpath :(
00:54tomojgood point
00:54itistodayhoeck: this is a bit beyond me atm i'm afraid...
00:55herdricktomoj: yeah - so i have some network issues right now and the install is hanging on "Downloading clojure-contrib-1.1.0-master-2009foobarbazz.jar"
00:55itistodayis this really that difficult of a macro to write..?
00:55tomojherdrick: you can skip the install if you're going to use lein
00:55herdricktomoj: can you tell me where it's installing things to so I can go wipe them all out and start over?
00:55tomojwell.. lein will require a working network anyway :1
00:55herdricki haven't been able to find the clojure.jar it downloaded
00:55tomoj~/.swank-clojure I believe
00:55clojurebotThat is the one thing Clojure can not do.
00:56herdrickah, ok
00:56herdrickmy network is sometimes ok...
00:56tomojbest to just delete that directory
00:56hoeckitistoday: never mind, thats a lot of java/jdbc stuff in there, you only understand those java APIs if you have the javadoc at hand
00:56tomojI think it checks whether the directory exists to decide if clojure is installed
00:57somniumoff-topic, but anyone looked at node.js? javascript is starting to look like an increasingly attractive host for clojure
00:57itistodaysomnium: i have, a bit
00:57tomojdoes that lead to clojure in the browser?
00:58itistodaysomnium: i'm not sure how you'd run clojure through it though
00:58somniumtomoj: thats already possible
00:58hoeckitistoday: basically, it executes an sql query and returns a sequence of hashmaps
00:58somniumsubsets of it anyway
00:58tomojah yeah, clojurescript?
01:01somniumits also possible to translate the core special forms directly to javascript (sort of clojure the language but not the library)
01:01herdricktomoj: i killed it
01:01somniumthis node.js is made for writing high performant servers and unix scripting in js
01:02itistodayok, so i've modified it a bit: http://paste.pocoo.org/show/173735/
01:02itistodaynow i'm stuck at this: java.lang.IllegalArgumentException: let requires a vector for its binding (NO_SOURCE_FILE:77)
01:03itistodayi think it's the interleave bit, but not sure what to do
01:03tomojyeah, you didn't give a vector as the first argument
01:03tomoj(let [foo bar] ..) not (let (baz biz) ..)
01:03itistodayhow do i convert a list to a vector?
01:04itistodaybecause i want to use interleave there
01:04tomojvec takes a coll and makes it a vector
01:04tomojbut that would need to be unquoted
01:05hoeckitistoday: try calling (macroexpand-1 '(foo (println NAME)))
01:05tomojwhat is the ~'col-syms and ~'val for?
01:06itistodaytomoj: i was getting exceptions from them not being like that
01:06tomojah :)
01:06tomojfiddling is bad
01:06somniumitistoday: the whole expression shouldnt be syntax quoted, you need to use ` to control the evaluation
01:07itistodaysomnium: ok, that's one thing i don't have a good grasp on, is where to put the syntax quote
01:08tomojare you trying to learn about macros?
01:09itistodayi'm trying to rewrite a newlisp fexpr in clojure, and yes, i guess learn about macros
01:09itistoday(along the way)
01:09tomojah..
01:09tomojI guess people have already said that this is not the clojure way
01:09itistodaytomoj: the newlisp fexpr looks like this: (for-query-with-db "SELECT name FROM people" (println NAME)) => prints all the names of the people in the db
01:10itistodayand i'm trying to work my way to a clojure version of that
01:11somniumitistoday: it would be easier to write a tiny macro that captures symbols first
01:11tomojoh, hmm
01:11tomojI figured http://paste.pocoo.org/show/173737/ is what you were trying to do
01:11tomojbut if this is just a stepping stone
01:12itistodaytomoj: yeah, it is, i could convert this to use hashmaps when i know how to do that :-p
01:13itistodaythis is where i am so far: http://paste.pocoo.org/show/173738/
01:13DeusExPikachuin the readme, leiningen is called a build tool, it seems more like a package manager...
01:13itistodayi'm still getting: java.lang.IllegalArgumentException: let requires a vector for its binding (NO_SOURCE_FILE:96)
01:14somniumitistoday: are you using macroexpand?
01:14itistodaysomnium: here's what i get for: (macroexpand-1 '(foo (prn NAME)))
01:14itistoday((let (vec (interleave user/col-syms val)) (prn NAME)) (let (vec (interleave user/col-syms val)) (prn NAME)))
01:14hoeckitistoday: http://paste.pocoo.org/show/173739/ is a more clojure-like version of your macro, but probably not what you want
01:15somniumitistoday: the usual process is: 1. rule out non-macro solutions, 2. write what the emitted datastructure should look like, 3. write a macro to emit it
01:16tomojwell, it prints successfully if you fix one small problem
01:16tomojbut then you're calling nil as a function
01:16tomojhmm
01:17tomojI wonder why ((let [] nil)) gives a different error than (nil)
01:18herdricktomoj: looks like it's working in Aquamacs for me. Thanks! I want to put some apache-commons jars in the classpath. should I just put them in ~/.clojure as it seems to say in the swank-clojure-default-classpath function in swank-clojure.el ?
01:18herdrickor is there a smarter move
01:18tomojwell.. if you were me, I would use lein
01:18herdricktomoj: i think i'm going to hold off on getting going with lein until you blog it :)
01:18tomojbut since you're not.. are you sure it's ~/.clojure?
01:18tomojhah
01:19tomojI don't even have a ~/.clojure
01:19tomojI think that's old?
01:19herdricknot sure, but here's most of the function in question:
01:19herdrick(defun swank-clojure-default-classpath ()
01:19herdrick (append
01:19herdrick (when (file-directory-p "~/.clojure")
01:19herdrick (directory-files "~/.clojure" t ".jar$"))
01:19technomancywhat's the equation to model something bouncing between two poles?
01:19technomancylike a pong ball? no gravity
01:19herdricki don't know - it's the swank-clojure.el it set me up with
01:20tomojherdrick: hmm, yes, you're right
01:20herdrickok
01:20tomojah, it uses both
01:20technomancyI figure it's some combination of the frame count modulo 2x the width and the absolute value of the frame count modulo the width
01:20tomojthe next line down checks for ~/.swank-clojure
01:20tomojare your clojure/contrib jars in ~/.swank-clojure? might as well put your stuff there if so
01:20technomancybut I want to do it functionally rather than calculating bounces by mutating the velocity
01:20herdricktomoj: you're just putting such jars in each project directory as needed?
01:21tomojyes, but lein does that for me
01:21somniumtechnomancy: are you making a pong clone for emacs?
01:21technomancysomnium: just playing around on android
01:21tomojif I wanted apache-commons for toy repls I guess I'd put the jars in ~/.swank-clojure
01:21itistodayhoeck: thanks, not sure how to translate that to my function though
01:22itistodayi noticed i wasn't using the ~ on col-syms and ~vals
01:22itistodayi've updated it: http://paste.pocoo.org/show/173740/
01:22herdricktomoj: yes, clojure and clojure-contrib jars are in ~/.swank-clojure
01:22tomojtechnomancy: you want a function for the horizontal position as a function of time?
01:22itistodaystill still get java.lang.IllegalArgumentException: let requires a vector for its binding (NO_SOURCE_FILE:123) though
01:22technomancytomoj: that's the one
01:22itistodays/still still/still/g
01:23tomojherdrick: if you drop other jars there they should be in the class path when you M-x slime, then
01:23tomojbut I think you will be surprised how easy lein is to setup and use, as long as you can find the deps you need in a maven repo
01:23herdricktomoj: ok - because they would only be picked up when starting with M-x slime ?
01:23tomojand even when not, not too bad
01:23tomojyeah, you need to sayoonara and restart slime if you just added something
01:24herdrickotherwise,like when you start with M-x swank-clojure-project, those jars won't get picked up?
01:24technomancyeverywhere I search they're trying to pull bloody gravity into it
01:24tomojswank-clojure-project only uses what's in the lib/ dir of the project you choose
01:25tomojas far as I know
01:25herdrickok
01:25hoeckitistoday: to create an expansion like (let [NAME ... ID ...] (println NAME)), you have to know the columns at compile-time, it this the case?
01:25itistodayno, you don't
01:25itistodayneed to do this at runtime
01:25herdrickthanks, tomoj it looks like I'm back with a working clojure in emacs again :) many thanks
01:25tomojhmm.. the funciton looks like this /\/\/\/\/\/\, no?
01:26itistodayhoeck: this isn't possible?
01:26technomancyeh; screw it; doing it statefully is good enough for tonight
01:27hiredmanlike a sine wave?
01:27technomancyhiredman: like a sine wave without the curvy bits
01:27itistodaywhat's wrong with this:
01:27itistodayuser=> (macroexpand-1 '(foo (prn NAME)))
01:27itistoday((let (vec (interleave (NAME AGE) ["Sally" 5])) (prn NAME)) (let (vec (interleave (NAME AGE) ["Sue" 6])) (prn NAME)))
01:28technomancybut I think I'll just do it quick and dirty by keeping a velocity and negating it when I hit the wall
01:28tomojitistoday: prn returns nil
01:28tomojamong other things
01:28tomojso your first let returns nil
01:28hiredmanhttp://en.wikipedia.org/wiki/File:ComplexSinInATimeAxe.gif <-- that is a sweet gif
01:28tomojand then you're trying to call nil as a function, passing nil as an arg
01:28hoeckitistoday: of course it is, but implementing it in a clean way is slightly more advanced
01:29tomojI meant that other things are wrong, not that prn returns other things
01:29itistodaybut why does running it generate: java.lang.IllegalArgumentException: let requires a vector for its binding (NO_SOURCE_FILE:123)
01:29tomojtechnomancy: look at abs(abs(x)%4-2)
01:30itistodayerr... and .. i need to be able to use any functions in the body, regardless of whether they return nil
01:30itistodaytomoj: sorry, meant to reply that to you
01:30tomojthat's like this \/\/\/\... where the max y value is 2 and the width of / is 2
01:30technomancytomoj: awesomar
01:31technomancythanks
01:31tomojthen you can add coefficients to the x to scale time
01:32tomojand scale the 4 and the 2 together to change the max y value
01:32itistodayfinal question before i sign off (gotta go now): is this a hard problem or just an easy one no one wants to help me with?
01:32somniumitistoday: its not hard and multiple people have tried to help you
01:32tomojitistoday: the body has nothing to do with it
01:32tomojoh, yes it does, a bit
01:33tomojthe point is you shouldn't be calling the return value of the body as a function
01:33itistodaytomoj: how do i avoid doing that?
01:33tomojalso you need to not quote vec
01:33tomojthat is, ~(vec instead of just (vec
01:34itistodaytomoj: ah, thanks! http://paste.pocoo.org/show/173741/
01:34itistodaythat prints "sally" "sue" and then throws a nullpointerexception
01:34itistodaymuch better! :-D
01:34herdricktomoj: btw, if you were to want the current build from git (of clojure & friends) would you git pull and mvn package in some other dir, and then copy the jars to ~/.swank-clojure ?
01:35itistodaytomoj: now, if i may ask, why does it throw a java.lang.NullPointerException? i assume it's cause i'm "calling the return value of the body", but i didn't know i was doing that
01:35itistodayi'm a clojure *NEWB*
01:35tomojyes
01:36tomojI don't know how to fix it though, sorry
01:36tomojlook at the macroexpansion you pasted above
01:36tomojit has the form ((let ...) (let ...))
01:36tomojthis means the result of the first let is being called as a function with the result of the second let as an argument
01:36tomojwhich is happening because the macro is simply returning a seq of let forms
01:36itistodaytomoj: ah, ok
01:38tomojhmm, I figured out a way to get it to work
01:39hoeckitistoday: transformed my version again http://paste.pocoo.org/show/173742/
01:39tomojbut I don't like it at all
01:39somniumitistoday: http://paste.pocoo.org/show/173743/
01:39tomojsomnium's is a much better way than mine
01:39hoeckitistoday: the point is that you have to declare the NAMES used in the body
01:40itistodaytomoj: somnium's works without that :-D
01:40itistodaysomnium: thanks!!
01:41itistodaysomnium: now i just need to decipher wtf you did there :-p
01:41itistodaylike the -> function... read the docs on that and was confused, it's nice to have an example finally
01:42tomojI have often wished for a collaboratively-edited database of simple examples
01:43TheBusbyI'd almost be willing to volunteer to add examples to the doc strings
01:43TheBusbymaybe a :example string?
01:43itistodayi would be completely willing to volunteer as well :-)
01:44tomojhmm, I hadn't thought of embedding them in the source
01:44tomojI was thinking of a web app
01:44itistodayas a newbie, i think i have valuable ignorance to contribute
01:44TheBusbythere are a large number of standard/common functions where the doc is very difficult to understand but a simple example would be clear
01:44TheBusby->> is a great example
01:44itistodayTheBusby: -> too, indeed
01:45TheBusbyer, sorry I meant ->
01:45itistodayif one of you is series about this, i'm actually serious, i would be happy to assist
01:45TheBusbyI certainly wont find the time for another week unfortunately
01:45tomojI think I remember htat defn started working on some kind of project like this
01:45itistodayi don't mean to toot newlisp's horn, lest i avoke the anger of hiredman, but you guys should check out its documentation, it's excellent
01:45TheBusbybut I've been thinking about it for a month or two already
01:46somniumhttp://getclojure.org/
01:46tomojyep, that's it
01:47somniumhmm, still not wikified I guess
01:47tomojglad he hasn't given up on it
01:47TheBusbythat and I'd like to see the examples embedded like the doc string if possible
01:47TheBusby(example ->>) just like (doc ->>)
01:47tomojyeah, I was originally thinking of web-editable data
01:47tomojI think he's storing the examples in the source of the cljex project?
01:47itistodaycheck out newlisp's documentation: http://www.newlisp.org/downloads/manual_frame.html
01:48TheBusbyyou see an example marked as "Usage:" in the doc string sometimes though
01:49tomojI guess putting the examples in the source of the project makes it so that contributions will always be good ones
01:51somniummaybe he could just let people imbed gist urls
01:51itistodaysomnium: thank you again, i've read through your code now and have understood it, i think this little example of yours has gotten me 70% of the way to being able to write clojure code now :-D
01:52tomojsomnium: you mean put the gist url in the source and then fetch the latest revision when rendering? or?
01:52tomojor go to getclojure.org and submit a gist url
01:52somniumtomoj: that one
01:52itistodayi think whatever you decide to do, the examples should be inline with the documentation without having to go to other URLs
01:53somniumgists can display inline
01:55somniumor setup a lisp editing app with a js-code-highlighter and emacs key bindings, but gists are probably easier
01:55itistodayif you guys setup a group to do this well, i'll donate $100
01:55itistodayi'm sure others will too
01:55itistoday(some amount)
01:55somniumitistoday: just donate to clojure
01:56itistodaysomnium: eh.. i specifically want to support the development of nice documentation for clojure
01:56tomojsend it to defn then :)
01:56itistodaywho's defn?
01:57tomojthe owner of cljex
01:57tomojthe project behind getclojure.org
01:58itistodaydoes he have contact info?
01:58tomojI dunno
01:59tomojgetclojure.org says "If you don't have the time, no worries, but do consider donating to Clojure if you're able." :DF
01:59itistodayfound it: http://devinwalters.com/
02:00TheBusbydevin -> defn nice
02:00itistodaycool, well hopefully i'll get in touch with him
02:01itistodaynight all, thanks again for the help
02:01tomojI almost bet he'll say "send the money to clojure instead"
02:05replacahiredman: wow, I like that gif!
02:12tomojis finding the appropriate maven artifactid/groupid/repo for a particular project frustrating, or am I just too much of a maven noob?
02:13tomojeh, guess I can just install the jars locally
02:37herdricktomoj: yeah, i'm not finding that either. also maven noob. and thanks much for your help earlier.
02:38tomojno problem
02:39tomojI wonder if there is something out there I could read that would make this maven stuff make sense
02:39tomojI find myself browsing through apache autoindexes trying to find stuff
02:39tomojand no nightly builds to be seen
02:40herdricktomoj: btw, if you were to want to do a build from git of clojure & friends would you 'git pull' and 'mvn package' in some other dir, and then copy the jars to ~/.swank-clojure ?
02:41herdrickhope i'm not being too obnoxious with questions
02:41tomojnah
02:41tomojthat sounds like what I would do
02:41herdrickok
02:41tomojexcept I wouldn't do that because I just use lein
02:42herdrickyou wouldn't build from source?
02:42tomojI haven't in quite a long time
02:42tomojmaybe if I were hacking on clojure I would, I guess
02:42herdricksure
02:42herdrickok, thanks
02:44tomojhuh, master hasn't been touched in over a month?
02:44tomojoh, that's the author date
02:44tomojanyway, http://build.clojure.org/ has nightlies it seems
02:44tomojand lein can grab from there
02:45tomojso little reason to build from source as far as I can tell
02:45herdricki see
02:45tomojI'll probably write that lein post tomorrow
02:46tomojfollowed by a paredit post
02:46herdrickgreat, looking forward to it. i'm subscribed to your rss feed
02:46tomojhah
02:46tomojI didn't even know I had an rss feed
02:47tomojthat wordpress has been sitting there for months with a post titled "foo" and some random clojure code embedded in a gist
02:48tomojguess I'm off to a good start in the blogosphere ;)
02:53herdrickha - yeah!
08:12AWizzArdHi chouser
08:13chouserhi
08:13chouserhmph. lost my connection. 4.5 hours of logs gone. :-/
08:15Chousukedoesn't look like you missed anything interesting :P
08:15AWizzArdchouser: I think you are an expert for agents, so here a question: is there a good reason why await does not return from waiting for an agent to finish, when this agent throws an Exception?
08:15chouserheh. ok, good I guess.
08:15Chousukemostly just quits and joins.
08:16chouserAWizzArd: hm... that may not be intentional.
08:16AWizzArd,(let [x (agent 0), foo (fn [_] 55)] (println @x) (await (send x foo)) (println @x)) ; works well
08:16clojurebot0 55
08:16AWizzArd,(let [x (agent 0), foo (fn [_] (Thread/sleep 2000) 55)] (println @x) (await (send x foo)) (println @x)) ; also works fine
08:16clojurebot0 55
08:17AWizzArd,(let [x (agent 0), foo (fn [_] (Thread/sleep 2000) (throw (Exception. "bar foos")) 55)] (println @x) (await (send x foo)) (println @x)) ; also works fine
08:17clojurebotjava.lang.Exception: Agent has errors
08:17AWizzArdokay, this one returns, but what happens in your clojure?
08:17AWizzArdCan anyone please try to confirm that await won't return for my last example?
08:17AWizzArd(where I accidently didn't remove the comment from the end of the line)
08:18chouseryeah, it hangs here
08:19AWizzArdI would think that await should return
08:19chouserok, in this case it's intentional
08:19AWizzArdchouser: can you please explain why?
08:20chouserthat agent is using the :fail error mode, so it's waiting for you to restart the agent so that it can finish processing its queue (and release the await)
08:21AWizzArderror modes.. hmm, I will investigate, thx
08:21chouseryou may prefer to specify an error-handler
08:22chouser(agent 0 :error-handler (partial println "Error:"))
08:22the-kenny,*clojure-version*
08:22clojurebot{:interim true, :major 1, :minor 1, :incremental 0, :qualifier "master"}
08:23_fogus_,,
08:23clojurebotEOF while reading
08:23_fogus_I always wondered what that would do
08:24Chousukecommas are whitespace
08:24Chousuke,,(+) also it only reads the first form
08:24clojurebot0
08:24_fogus_Understood
08:29zaphyrhmm. does clojure bot know not to hang? :)
08:29chouseryes he does. He's pretty clever.
08:29zaphyr:D
08:29chouser@(promise)
08:29chouser,@(promise)
08:29AWizzArdchouser: yes, the error-handler works. But it seems neither the agent nor the handler are able to forward the Exception to the thread which awaits the agent.
08:29zaphyr,(* 3 4)
08:29clojurebotExecution Timed Out
08:29clojurebot12
08:29zaphyrahh
08:29zaphyr:)
08:30chouserhe doesn't actually try to solve the halting problem. He's not *that* clever.
08:30zaphyryeah, but we've got clojure now, i'll try and submit a patch for that by 2011 :)
08:30AWizzArdIs there a mechanism for that? Currently I do a repeatedly on await-for and check agent-errors, embedded in a take-while, but that definitly is very hackish.
08:31chouserAWizzArd: the await just puts an action on the agents queue that will signal the await to continue. then it just sits waiting for that signal.
08:32chouserif you want to do something specific when the agent errors out, just put that in your error-handler
08:34AWizzArdI would like the error handler to throw an exception in the thread which called await :)
08:44chouserhmm
08:44chouserare you sure you want agents? that all sounds very synchronous. :-)
08:46AWizzArdchouser: I want to modify my DB (insert/update/delete) and log to disk. I discussed this in the last days, and there are two possible solutions:
08:47AWizzArd1. I use refs. But the ref would have to write to disk inside the dosync, because this is part of the transaction. This means that if many threads try to update the db the dosyncs will block each other, because the writing to disk makes them slow enough to get repeated.
08:47AWizzArdThis means that the dosync has to get embedded into a locking. hiredman pointed out that currently there are no plugins for dosyncs that would allow me to go around the lock
08:48AWizzArd2. Chousuke then asked why I need refs if they are inside a locking anyway. So, agents also sound nice.
08:48chouserwhat about an atom and a watcher?
08:48chouserer, a "watch"
08:49chouseror a watch on a ref, for that matter.
08:49AWizzArdyes, atoms could be another way, maybe with a BlockingQueue or a watcher.
08:49chousera watch on a ref will not prevent other transactions from working on the ref, nor cause the current transaction to retry
08:51AWizzArdWell, only one transaction can work at a given time on the db. One ref modifies it, so all other transactions that are running would notice the change and retry. I think.
08:52chouseryes, but the transaction is "done" by the time the watch is called. Other transactions can proceed with updating the db while the watch writes it to disk.
08:53AWizzArdchouser: this is not acceptable. Before any part of the program can see the updated db it must already be written to disk.
08:54AWizzArdotherwise the change maybe happened in ram, a customer bought something, and then the system crashes before the data is on disk.
08:54AWizzArdOnly after the guaranteed write happened the rest of the world may know about the new state.
08:55AWizzArdSo, modifications to the db really need to run serial
08:55chouserso you really do want synchronous behavior
08:55AWizzArdyes
08:56AWizzArdlock around dosync, agent or atom+BlockingQueue
08:56AWizzArdagents sound great, they only have the problem that I reported above, with the Exceptions
08:56chouserI think a simple lock might be best
08:57AWizzArdhmm yes right, a lock around a dosync or function that updates an atom
08:57chouserwell, agents are for async operation. I think they could be made to work in your situation, but it'll take some effort because it's not really the right mechanism.
08:57AWizzArdthe blockingqueue would not be needed when a lock is involved
08:57chouserno, not a transaction. just a lock
08:58AWizzArdinside this lock I need to change the state of the db in clojure terms. So inside this lock I will need to update a ref, atom or agent
08:59chouserhm
09:00AWizzArdbut it could be okay to have one function which is doing all the updates/inserts/deletes etc, and the db is an atom, and around my function i have a lock
09:00chouseran atom is close, but because you have side-effects, you don't want to retry ever.
09:00chouserso maybe this is essentially a new reference type.
09:00chouserlike atom but using a lock instead of CAS
09:00chouserand no rhickey here to talk me down.
09:00AWizzArd:-)
09:01AWizzArdAs soon this db-transaction-function is working, all other threads can still run selects on the db
09:01AWizzArdthis can be done with atom updates inside a lock
09:01chouseryou want all threads to see the old value until the new value is written to disk, right?
09:01AWizzArdexactly
09:01chouserand anything updating the value should block until its done.
09:02chouserand we can use protocols...
09:03AWizzArduntil yesterday i thought i would go with a lock around a dosync. The updates can work likes this: the transaction begins and the ref is dereferenced. This immutable dereferenced db object gets "modified". If this does not trigger any constraint we now have an immutable db object which contains the correct updates.
09:03AWizzArdIf the program crashes here it's no problem, nobody was ever reported the updates.
09:03AWizzArdIf it does not crash we write to disk and wait until it is guaranteed on disk.
09:04AWizzArdWhen the program crashes here after a restart it will have the full db contents, as if it didn't crashed, because it could read it from disk.
09:04AWizzArdIf we don't crash, *then* a ref-set really updates the object, the transaction ends.
09:05AWizzArdor well, ref-sets are not needed
09:05AWizzArdprobably alter is used, nobody can see the altered db object anyway
09:05AWizzArdand this allows transactions inside other transactions
09:05jcromartiewow, cool stuff on profiling with jvisualvm http://www.fatvat.co.uk/2009/05/jvisualvm-and-clojure.html
09:05AWizzArdonly when the outermost dosync ended the world can see this update
09:05jcromartieI didn't even realize it came with Java
09:06jcromartieI hope that sort of thing doesn't go away now that Sun is no more
09:07AWizzArdchouser: indeed, a modification of a ref/dosync maybe meaningful
09:07chouserAWizzArd: I think a lock and an atom would be better.
09:08AWizzArdchouser: yes, also okay, though this would imly that i first deref the atom and put the derefd db into a new atom, which i then modify through the whole transaction
09:08AWizzArdimly => imply
09:08chouseroh, you don't just have a simple update fn you call per db update?
09:09chouseryou have a series of imperative ref-set's (or similar)?
09:09AWizzArdyes, this is used, but all wrapped into a db-transaction
09:10AWizzArd,(let [x (ref {})] (dosync (println @x) (alter x assoc :a 1) (println @x) (alter x dissoc :a) (println @x)))
09:10clojurebot{} {:a 1} {}
09:10chouser:-/ not very functional is it.
09:10AWizzArdtrue, but we are talking about a db transaction
09:10AWizzArdthis is all about state change, and not a functional thing
09:11AWizzArdas if we call alter/commute inside a dosync
09:11AWizzArdthis non-functional style is the essence of db modifications
09:11AWizzArdinside a transaction the user can do several calls to insert/update/delete
09:12AWizzArdafter an insert he will expect to be able to select the inserted object
09:12chouserright, and you can do the same inside a reference type updater (atom, ref, agent, etc.) but the Clojure API discourages it.
09:13chouseryou're sure you want to encourage it?
09:13jcromartieprofiling lesson of the day: MySQL connections are cheap, reading results is expensive
09:13AWizzArdchouser: I don't see a plausible way around this.
09:14AWizzArdI hope the users will write a mostly functional style program, and isolate their db updates to a few parts of the program
09:14chouseranyway, if you really want to do this, I think a lock per transaction best provides the semantics you want.
09:14AWizzArdyes
09:15AWizzArdso, lock around a function which then either modifies a ref inside dosync, or which uses an atom, derefs it, atoms it again, uses this copy inside the transaction, and when everything is done (reset!)’s the original db that can be seen by all threads.
09:16AWizzArdFor now I think I will be safe with lock+dosync, although this has a slightly bitter taste. But if it turns out that there is a better solution I can still update to that solution.
09:17AWizzArdchouser: interesting discussion, thank you. Brought new information for me.
09:19chouseronce you're inside a lock, a ref and transaction is much heavier than you need. I would look at using an atom or maybe even something lighter than that.
09:20AWizzArdchouser: there is nothing lighter than an atom
09:20chouserperhaps (with-db-transaction [x my-db] ... (db-set x foo) ... (db-alter x bar) ...)
09:21chouserthen with-db-transaction can create a new mutable instance and bind it to x. should be safe because x won't exist outside the dynamic scope of with-db-
09:21AWizzArdAnd I am not so sure that a ref will be indeed so heavy. It will never notice any updates by other threads, because it is the only one running.
09:22chouserso there need be no serializing changes to x at all. it could be even just a clojure.lang.Box
09:22chouserhm.. actually, that sounds like a var
09:22AWizzArdI don't know Box
09:22AWizzArdAnd can a var be updated?
09:23chouser(doc with-local-vars)
09:23clojurebot"([name-vals-vec & body]); varbinding=> symbol init-expr Executes the exprs in a context in which the symbols are bound to vars with per-thread bindings to the init-exprs. The symbols refer to the var objects themselves, and must be accessed with var-get and var-set"
09:23qedhttp://www.infoq.com/interviews/Steele-Interviews-John-McCarthy
09:23AWizzArdand why does with-db-transaction not require serializing changes to x?
09:24chouserbecause with-db- does the locking, outside which x doesn't even exist.
09:25AWizzArdchouser: yes, but x needs to be changed inside
09:30AWizzArd,(let [x (atom 0)] (with-local-vars [foo @x] (println foo) (println @foo)))
09:30clojurebot#<Var: --unnamed--> 0
09:31chouser,(with-local-vars [a 10] (var-set a 5) @a)
09:31clojurebot5
09:31AWizzArdchouser: I will analyze this w-l-v, and maybe this is giving me the right semantics.
09:32AWizzArdBut one problem could be that several of those can run in parallel
09:32AWizzArdSo, a lock around that will still be required
09:32chouseroh, yes.
09:32chouserthe var shouldn't even exist except inside the locking construct
09:32AWizzArdAnyway, maybe it is even lighter than an atom and thus run more efficient
09:33AWizzArdchouser: you mentioned this for efficiency, right?
09:33chouserand safety, yes.
09:34AWizzArdchouser: good point, this (locking+w-l-v) may provide the same as locking+atom+atom or locking+dosync, but more efficiently
09:36AWizzArdthe locking around the dosync would in principle not be required, but I would use it, because the io operation inside makes it slow and could trigger too many repetitions of the dosync
09:39AWizzArdesj: just give me a few more weeks please :-)
09:39esjAWizzArd: provided you explain it to me when you're done !
09:40AWizzArdI am spending a lot of time on documentation.
09:40AWizzArdAnd.. when even I can understand it, it must be pretty simple.
09:40qedhug*
09:41qed^--------oOOops
09:42esjAWizzArd: thanks i really appreciate well doc'd code, helps so much to understand
09:42fdaoud,(zipmap [1 2 3 4] ["a" "b" "c" "d"])
09:42clojurebot{4 "d", 3 "c", 2 "b", 1 "a"}
09:43fdaoud,(for [x [1 2 3 4] y ["a" "b" "c" "d"]] [x y])
09:43clojurebot([1 "a"] [1 "b"] [1 "c"] [1 "d"] [2 "a"] [2 "b"] [2 "c"] [2 "d"] [3 "a"] [3 "b"] [3 "c"] [3 "d"] [4 "a"] [4 "b"] [4 "c"] [4 "d"])
09:43fdaoudhow would you loop through 1 "a", 2 "b", 3 "c", 4 "d" *in order* ?
09:44sparievAWizzArd: can you shed some light on your project ?
09:45the-kennyfdaoud: If you have a list like [1 "a", 2 "b"] etc. you can use partition to create pairs
09:45Chousukefdaoud: you can map over them
09:45chouserAWizzArd: maybe something like this: http://paste.lisp.org/display/94354
09:45Chousuke,(map vector [1 2 3] '[a b c])
09:45clojurebot([1 a] [2 b] [3 c])
09:46chouserheh. now there's an example where you *could* ->> and you really really shouldn't.
09:46qedwhy can't you search google for "->>"
09:47fdaoud,(for [[x y] (map vector [1 2 3] ["a" "b" "c"])] [x y])
09:47clojurebot([1 "a"] [2 "b"] [3 "c"])
09:47chouserqed: dunno, but you can (doc ->>)
09:47fdaoudChousuke: thanks!
09:47Chousukefdaoud: the for is redundant though :P
09:47qedchouser: *nod*
09:47Chousukefdaoud: map is enough
09:48fdaoudChousuke: agreed, but I need to put this in a for-like structure, so just making sure it behaves as expected :)
09:48Chousuke,(map + [1 2 3] [4 5 6]) another example
09:48clojurebot(5 7 9)
09:48tcrayford,(for [x [1 2 3] y '[a b c]] [x y])
09:48clojurebot([1 a] [1 b] [1 c] [2 a] [2 b] [2 c] [3 a] [3 b] [3 c])
09:48_fogus_,(partition 2 (interleave [1 2 3] '[a b c]))
09:48clojurebot((1 a) (2 b) (3 c))
09:48fdaoudtcrayford: I don't want 1 a 1 b 1 c, just 1 a 2 b 3 c
09:49fdaoudChousuke: specifically, Enlive's clone-for
09:49tcrayford,(use 'clojure.contrib.seq-utils)
09:49clojurebotnil
09:49tcrayford(indexed [a b c])
09:49tcrayford,(indexed [a b c])
09:49clojurebotjava.lang.Exception: Unable to resolve symbol: a in this context
09:49tcrayford,(indexed '[a b c])
09:49clojurebot([0 a] [1 b] [2 c])
09:49chouseran antipattern. don't you dare: http://paste.lisp.org/display/94354#1
09:50Chousukewait, what
09:50fdaoudChousuke: ?
09:50Chousukethat paste
09:51chouserwhat, you don't like to put your 'finally's before your 'try'?
09:51fdaoudwell, anyway, map vector is what I needed, thanks :)
09:52fdaoud,(interleave [1 2 3] '[a b c])
09:52clojurebot(1 a 2 b 3 c)
09:52fdaoud_fogus_: thanks, another way of doing it
09:53Chousukechouser: it's scary that that's even possible.
09:53chouserputting the 'let' last is still my favorite.
09:54chouser,(->> (+ a 5) (- 20) (let [a 9]))
09:54clojurebot6
09:54Chousukeit's unfortunate that the more expressive a given feature is, the more opportunities it offers for abusers :P
09:54chouserok, it's not.
09:55chousernot my favorite, I mean.
09:55chouserChousuke: yes, scary.
09:55tcrayfordI wrote a thing in emacs that'll turn any ->> expression into its normal form, and vice versa
09:55tcrayfordis fun to play around with on crazy code
09:56chousertcrayford: ooh, neat.
09:56chouserI usually end up writing without ->> first, and then converting.
09:56tcrayfordI had fun when I learned about ->>, and wrote that
09:56tcrayfordthen tried it on a page or two of code for kicks
09:57tcrayfordthen decided its only worth it sometimes
09:57tcrayfordso converted most of it back to normal code
09:57tcrayfordwhat does -?>> do?
09:57cemericksame as -?>, but for ->>
09:58qedi've never seen the -?>
09:58qed:\
09:58cemerickit's in clojure.contrib.core
09:58Chousukeisn't it just (defnilsafe -?>> ->>) :/
09:58qedah
09:58cemerickChousuke: yes, but it should be "out there"
09:59AWizzArdspariev: I am working on an in-memory, in-process DB system, written in Clojure, and very easily usable in Clojure.
10:00sparievAWizzArd: tnx
10:02sparievIs it going to be relational or object DB ?
10:06AWizzArdspariev: object
10:07AWizzArdchouser: yes, this example code is in principle modeling this transaction subsystem
10:10jkdufairso does ->> do its "threading" prior to evaluation? it would be a macro, yes?
10:10tcrayfordconfirm
10:10Chousukeyes.
10:10tcrayford,(use 'clojure.contrib.repl-utils)
10:10clojurebotjava.lang.ExceptionInInitializerError
10:10tcrayford,(source ->>)
10:10clojurebotjava.lang.Exception: Unable to resolve symbol: source in this context
10:10tcrayford:(
10:10jkdufairthx
10:10sparievAWizzArd: I'm asking because I'm thinking about some kind of Functional Relation Programming DB, with relations and stuff. basically I'm trying to wrap hypersonic sql with some clojure
10:10chouserright, which is the only reason you can do crazy stuff with let, try/finally, etc.
10:10Chousuke~def ->>
10:11AWizzArdspariev: interesting
10:11sparievAWizzArd: and your discussion with chouser was very helpful )
10:11AWizzArdgreat
10:12chouserAWizzArd: so you like the example code -- what about the implementation. about as simple and performant as it gets, I think.
10:13chouserthe only way to replace the outer atom properly, I think, would require a volatile field.
10:13AWizzArdchouser: I am currently in the process of finding my for now "final model", and the w-l-v may be the most efficient solution and thus I am analyzing this. When I can not identify major challenges it will be my route for now.
10:13chouserok
10:13AWizzArdGood that you brought this to my attention.
10:14AWizzArdFrom the point of correctness many solutions are okay, but obviously I want something efficient.
10:14AWizzArdGiven that sorted sets/maps are still amazingly slow...
10:15chouserI think this solution is less "against the grain" than trying to make agents synchronous
10:15AWizzArdCan you please join me begging rhickey to implement PersistentSortedMultisets and sets? :)
10:15AWizzArdchouser: yes, makes sense
10:15chouserhe had multi-maps (not sorted I think), but seemed to think that everyone's response was underwhelming, so dropped it.
10:16AWizzArdooh ooh
10:16AWizzArdmaybe he still has the code somewhere
10:16AWizzArdYesterday I discovered that Google offers nice immutable collections: http://code.google.com/p/google-collections/
10:17AWizzArdBut after a closer look I realized that what they created within two years just can't compete with what rhickey implemented.
10:17AWizzArdThe google collections are immutable but not persistent
10:17chouseryeah
10:17AWizzArdI can not look from 10 different threads at them and modify them in an isolated way
10:17AWizzArdI can not remove things
10:18AWizzArdthey are more like "constant sets"
10:18AWizzArdI just saw they offer Multisets and Multimaps and even BiMaps
10:18chouserAWizzArd: http://clojure-log.n01se.net/date/2009-09-03.html#12:03c
10:18cemerickI didn't mind the multi-maps at all, it was having distinct reader syntax for them that didn't make sense for me.
10:19rhickeyAWizzArd: it is pretty easy to write a multimap api on top of maps of sets
10:19AWizzArdAnd having those Multisets/maps would be really helpful. But having SortedMultisets would indeed be a killer feature
10:20rhickeyAWizzArd: what's the killer use case for sorted multisets?
10:20AWizzArdrhickey: Adding 80k users (deftype User [username password age city]) into the sorted multiset, sorted by their year of birth
10:20chouserrhickey: AWizzArd thinks he wants a synchronoush reference type, but based on locks not CAS like atom so that he can do side-effects without repeating them.
10:21AWizzArdcurrently this requires a unique field. I can not simply have the comparator sorting by year of birth, because more than one user was born 1970
10:21AWizzArdI will have to include a slot from the User deftype which is unique.
10:21rhickeychouser: like the cells? this unrelated to multisets?
10:21chouserrhickey: so I wrote this and wanted to give you an opportunity to declare it should never be used. :-) http://paste.lisp.org/display/94354
10:21AWizzArdIn a SortedMultiset I could just add all users
10:22AWizzArdrhickey: unrelated
10:22chouserurg. I forgot about cells. hang on.
10:22AWizzArdI want to do io (writing to disk) inside a dosync
10:22AWizzArdrhickey: so this developed to become a lock around a dosync
10:22rhickeyAWizzArd: but why multiset and not multimap? it's not a set of years
10:22AWizzArdrhickey: to get all people born between 1970 and 1980
10:23AWizzArdthis would return one set of users, if subset were implemented
10:23rhickeyAWizzArd: but a set of people is not a set of years
10:23chouserAWizzArd: you didn't like this solution? http://paste.lisp.org/display/94065
10:24AWizzArd(sorted-multiset #(compare (:yob %1) (:yob %2))) is very nice. And later (subset users-by-yob = 1964) ==> all users born in this year. Or (subset users-by-yob >= 1970, < 1980) ==> returns a set of users that fulfill this criteria
10:24AWizzArdchouser: this works but is more complex
10:25AWizzArdand what can we do if the deftype has no slot that contains a unique value?
10:25AWizzArdAlso it makes the lookup more complex
10:25AWizzArda sorted-multimap would also work, but this would not return one set, but instead a sequence of keys (year of birth here) and values (sets of User instances)
10:26AWizzArdAlso it would be amazing if a subset was in reality just a "view" (shared structure) of the map, so it won't take much ram
10:26AWizzArddon't know if this is possible
10:26chouserhm, cells might work.
10:26qedis a sorted-multimap more abstract than a multimap, or vice versa?
10:27rhickeya multiset is sort of a contradiction
10:27chouserheh
10:27AWizzArdrhickey: well, they may be equal under the comparator, but they are not identical?.
10:27chouseryeah, a cell would work
10:28rhickeyAWizzArd: it's just a logical mess. What is it a set of? Does it enforce set-ness of the entire thing when using a partial key?
10:28AWizzArdGoogle also has Multisets in their Collections. Though as I already said, what you developed for Clojure is way more advanced than the immutable collections from Google.
10:29rhickeyAWizzArd: collection class libs have had multisets for decades, still confusing
10:29AWizzArdIt would be interesting to be able to call (subset on-it), to get a set returned on which one can call intersect.
10:29AWizzArdExample: you have a sorted set of all male users and a set sorted by year of birth. You could then look up males, then all born between 1990 and 1995 and intersect those and have all male users born during that time.
10:30rhickeyAWizzArd: sounds like indexes
10:30AWizzArdrhickey: exactly!
10:30AWizzArdI am talking about indexes.
10:30rhickeynot collections
10:31AWizzArdWell, the index needs to reside in some collection.
10:31AWizzArdThe index we are talking about lives in ram and is persistent.
10:31rhickeyall you need are multimaps for indexes
10:31AWizzArdrhickey: yes, those are enough in principle. They can just not be so easily queried
10:32rhickeyAWizzArd: I don't see why not
10:32esjAWizzArd I've been doing something similar to this, a timeseries library, where I also used a sorted-set-by for the concerete representation. Made much easier by the fact that time is the unique index. Its nothing special, but check it out - https://gist.github.com/1eaa8e674ec13a06559b
10:32AWizzArdIf you make such a map that logs the msecs after 1970 (timestamp) of user requests in your webserver
10:32AWizzArdHow would we then ask for all requests between 2008 and 2009?
10:33AWizzArdThat would require many lookups, as many as there are msecs per year
10:33AWizzArdAnd most will result in nil
10:33AWizzArdA sorted multimap would be more useful here
10:34AWizzArdsuch as subseq can already return such results easily for sorted sets and sorted maps
10:34qedesj: very cool
10:35esji'm hoping to get it into Incanter once its been gone over by somebody who actually know what they are doing :)
10:35qedim bookmarking to read when i wake up :)
10:35AWizzArdAnd even when subseq returns a result, we still have to apply clojure.set/union on all those little values returned from the map
10:35qedthanks
10:35AWizzArda set however makes this easier to query. A set will return the Log objects directly. The comparator would compare their incoming timestamp and sort them.
10:36AWizzArdAlthough, so far there is no .subset implemented and it is also a seq
10:36qedi like sets
10:36AWizzArdqed: yes, I also
10:36rhickeyAWizzArd: sorry, I meant both sorted and non-sorted multimaps above. What I am arguing against is multisets
10:36qedthey're dependable
10:36esjand they like the attention
10:37qedhaha
10:37AWizzArdrhickey: the SortedMultimaps are able to model everything what I can come up with. The only thing that is not so nice about them is that they return key/value pairs, instead of the union of all values.
10:38chouserAWizzArd: my db-locking thing doesn't protect against nesting the way it should (and cells would)
10:38AWizzArdIf there were a function subset that I could call on a SortedMultimap that would be fine of course.
10:38qedAWizzArd: yeah but i think the key/val pairs makes more sense -- seems more consistent
10:38rhickeyAWizzArd: a multimap might return a set at each key
10:38AWizzArdrhickey: yes. And on those we need to call (apply clojure.set/union ..)
10:39AWizzArdA SortedMultiset would do this implicitly.
10:39qedit might be a bit much, so to speak
10:40AWizzArd(deftype Log [timestamp method uri user])... (def logs-by-timestamp (sorted-multiset #(compare (:timestamp %1) (:timestamp %2))). And later we can (subset logs-by-timestamp >= (to-timestamp 2008) < (to-timestamp 2009))
10:40AWizzArdAnd the result would be a set of Logs. Even if two requests arrived at the same msec
10:41AWizzArdA sorted-multimap instead would return a sequence of 4 million key/value pairs that I first need to union.
10:41AWizzArdI need to union them to be able to intersect them with other selections
10:41rhickeyAWizzArd: but you are only looking at one aspect. There is a lot of confusion engendered by multisets using partial keys. Are they true sets? How does contains? work? is there a way to check for containment of a full value? etc etc
10:41qedAWizzArd: i see the utility, but im not convinced by your example
10:43AWizzArdalso an interesting point is if the union of some thousand sets, summing up to a million objects will have to be a full copy of those, or if it could "magically" be some kind of view on the existing sets under the hood.
10:43AWizzArdin such a case clojure.set/union|intersect|difference would be fast and not require too much RAM.
10:44AWizzArdsorted-sets are already pretty close to sorted-multisets
10:44AWizzArduhm, I mean: sorted-maps are already very close to sorted-multisets
10:45AWizzArdWhat I am currently doing is using a sorted-map-by and when a key does not exist I assoc an empty set as its value. Otherwise I assoc the set conjed with the new value to the sorted-map
10:46AWizzArdThus I already have something very close to a Multiset. My value, the set, is indeed not even a set, but itself a sorted-set. This way I could for example store users by their year of birth, and have them alphabetically sorted.
10:47AWizzArdhaving sorted-multisets support in Clojure would of course be very helpful
10:48AWizzArdWe could have them just implement the SortedMap interface (as suggested in the assembla ticket), or if we want Java 6, implementing the NavigableMap interface.
10:49AWizzArdWell, thanks for listening. rhickey, it is true that I mostly look at one aspect of SortedMultisets, but even having SortedMultiMAPs would be very interesting.
10:50AWizzArdchouser: I listened to you, but could not respond. What are those Cells?
10:50angermanhandling JNA structs with clojure is not very elegant ... or I'm doing something completely wrong.
10:53chouserAWizzArd: rhickey described them here: http://clojure-log.n01se.net/date/2010-01-22.html#09:22a
10:55AWizzArdchouser: very good, I will read this
10:56AWizzArdrhickey: btw, do you see a way to make something like "transient sorted-maps/sets"? I am looking for a way to insert data into sorted maps/sets much faster, and I can guarantee to insert in the correct order.
10:56AWizzArdWould that be possible, in principle?
10:58cemerickthose cells sound like very concrete monads to me
10:58cemericknot that I pretend to properly understand monads
10:58rhickeycemerick: monads you can use from multiple threads? a contradiction in terms I think
10:59rhickeymonads are about flow, this is about not having to flow
10:59rhickeyAWizzArd: I'm not sure how much perf advantage to transient sorteds, probably some, just tedious
11:00AWizzArdhmm
11:00rhickeyAWizzArd: i.e. with transient updating you could just do local mutative rebalancing, rather than full path copies
11:00AWizzArdI was thinking about this: when a savepoint of the db is made and an application restarted, it then wants to reload the db. Insertion is not very fast into sorted-maps/sets. I just know that I have them already sorted on disk, because I read them out of a sorted-map/set during serialization.
11:01rhickeyfast load from sorted is a different question
11:02AWizzArd,(time (let [x #{}] (reduce #(conj %1 %2) x (range 1000000)) nil))
11:02chousercould perhaps avoid a lot of rebalancing if you know the size of the input and the fact it's sorted
11:02clojurebotExecution Timed Out
11:02AWizzArd,(time (let [x #{}] (reduce #(conj %1 %2) x (range 100000)) nil))
11:02clojurebot"Elapsed time: 964.84 msecs"
11:02AWizzArd,(time (let [x (sorted-set-by <)] (reduce #(conj %1 %2) x (range 100000)) nil))
11:02clojurebot"Elapsed time: 2438.971 msecs"
11:03cemerickrhickey: I've never used monads at all, so this is mostly hot air. Cells seem to share the notion of cleanly separating initial states, operations, and later states that are the result(s) of those operations.
11:03AWizzArdchouser: yes
11:03AWizzArdAnd I won't need the comparator, comparison is not needed
11:03AWizzArd,(time (let [x []] (reduce #(conj %1 %2) x (range 100000)) nil))
11:03clojurebot"Elapsed time: 134.741 msecs"
11:03AWizzArdfast :-)
11:04AWizzArdunfortunately I can not use vectors as indexes
11:04AWizzArdanyway, rhickey, now after more study about your implementations of those data structures I am very impressed what you have done. It is very good work, and you easily outperform Google! *thumbs up*
11:05chouser,(time (peek (into [] (range 100000))))
11:05clojurebot99999
11:05clojurebot"Elapsed time: 106.663 msecs"
11:05chouserfaster
11:06AWizzArd,(time (count (into #{} (range 100000))))
11:06clojurebot100000
11:06clojurebot"Elapsed time: 225.935 msecs"
11:06AWizzArd,(time (count (into (sorted-set-by >) (range 100000))))
11:06clojurebot100000
11:06clojurebot"Elapsed time: 1834.843 msecs"
11:08AWizzArdchouser: I will see if I can easily enough go around the problem of stacked transactions using with-local-vars. Otherwise for now I can simply use a lock, deref the atom containing the db, atoming it again and reach this around.
11:08AWizzArdAnd when Cells come one day, I could use them and clean up my underlying implementation.
11:09chouserit wouldn't be hard to add protection against nested with-db-locks
11:10AWizzArdyes, I will most likely do that
11:10AWizzArdI will come up with a prototype of db-transactions this week
11:10chouserAWizzArd: would you ever want to support updating multiple dbs in the same transaction?
11:11AWizzArdchouser: probably not. My db will be a little bit like git/mercurial and allow clones ("branches") which can be merged.
11:11AWizzArdDuring the merge there will be two dbs involved, but that should still not require refs.
11:12AWizzArdanyway, for today I have talked enough, and our discussion about the efficiecy was very interesting and shed new light on some aspects for me. For example, I didn't know about with-local-vars.
11:23stuartsierraAnyone have a better link for Rich's talk at Clojure NYC last week?
11:25rhickeystuartsierra: I didn't know it was being recorded
11:25stuartsierrarhickey: someone had a flip
11:26stuartsierraThere's an incomplete video here: http://vimeo.com/9090935
11:26rhickeyyeah, with a low battery :(
11:26stuartsierrayep
11:26stuartsierraI wanted to share it with my interns.
11:31rhickeystuartsierra: you have to bring them next time!
11:32stuartsierraThey couldn't make it. I invited them.
11:33fdaoudwhere was this?
11:34fdaoudsorry, you said NYC
11:35fdaoudof course the other one is on Scala
11:36fdaoudthe syntax of which I cannot stand
11:38stuartsierrafdaoud: Clojure NYC, on meetup.com
11:49qedI so wish there was a meetup in Chicago
11:51chouserqed: If there were, I might go.
11:51chousera bit of a treck, but could be worth it. :-)
11:54wtetzner_does anyone know how to set jvm options for swank-clojure?
11:54chouserqed: would you present something?
11:55mattreplwtetzner_: it used to be swank-clojure-extra-vm-args that you could set
11:55wtetzner_mattrepl: ok, i'll try that. thanks
11:56mattreplit takes a list of string arguments: (list "-Dsome.prop=10" "-Xmx1024m")
11:58wtetzner_ok, thanks
12:00wtetzner_i'm trying to use jvisualvm for profiling, but it tells me i have class sharing turned on
12:00wtetzner_i tried using -Xshare:off, but it still says sharing is turned on
12:01mattreplonce you have swank-clojure loaded up, you can also see/set all the settings from M-x customize-group
12:01mattreplusing "swank-clojure" as group name
12:02wtetzner_ok
12:02jcromartiehow would I make a case-insensitive regex?
12:02chouser#"(?i)foobar"
12:03jcromartieah
12:03jcromartieis that in the docs anywhere?
12:03chouserit's in the book. ;-)
12:03jcromartieah
12:03jcromartieclojure.org feels sorely out of date sometimes
12:03jcromartieit would be trivial to update it if the wiki were open
12:03jcromartie(is it?)
12:03chouserwell, it's take directly from the Java Pattern object
12:03jcromartieah
12:04jcromartieI thought the options were specified as arguments to the constructor
12:04chouserhttp://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html#UNIX_LINES and following
12:06jcromartiethanks
12:23alexykwhat's the syntax for if -- elseif ... -- else, if any? nested ladders of if's start to look unwieldy... is there a caseof equivalent?
12:25alexykor it's a big-arse (if ... (if ... ))))))) <-- the famous painfully counted closing layered cake?
12:25the-kennyalexyk: case? cond?
12:25alexykthe-kenny: ah!
12:26_fogus_alexyk: (and)
12:26alexyk_fogus_: (and)?
12:26alexyk,(doc cond)
12:26clojurebot"([& clauses]); Takes a set of test/expr pairs. It evaluates each test one at a time. If a test returns logical true, cond evaluates and returns the value of the corresponding expr and doesn't evaluate any of the other tests or exprs. (cond) returns nil."
12:26fdaoud, (cond (< 2 42) "a" (> 2 42) "b"))
12:26clojurebot"a"
12:27alexyk,(doc case)
12:27clojurebot"clojure.contrib.fcase/case;[[test-value & clauses]]; Like cond, but test-value is compared against the value of each test expression with =. If they are equal, executes the \"body\" expression. Optional last expression is executed if none of the test expressions match."
12:27alexykaha, so case is not core
12:27Chousukewill be in 1.2
12:28stuartsierraand it's different
12:28alexykstuartsierra: different from the above fcase/case?
12:29alexyk_fogus_: I used (and ...) to essentially simulate elsif, it's unwieldy too
12:29stuartsierraalexyk: yes
12:29_fogus_alexyk: Yeah, it's a total hack
12:31somniumhow is that fcase macro different from condp?
12:31stuartsierrait's not
12:31stuartsierraI wrote it before condp existed
12:31somniumah, roger
12:31alexyk,(doc condp)
12:31clojurebot"([pred expr & clauses]); Takes a binary predicate, an expression, and a set of clauses. Each clause can take the form of either: test-expr result-expr test-expr :>> result-fn Note :>> is an ordinary keyword. For each clause, (pred test-expr expr) is evaluated. If it returns logical true, the clause is a match. If a binary clause matches, the result-expr is returned, if a ternary clause matches, its result-fn, which must b
12:32alexykI'll stick with cond, clear and unambifuous. Not much trouble to write (= var blah)
12:32stuartsierrayej
12:32stuartsierrayes
12:33stuartsierraAnd for simple tests, it's faster than case
12:34alexykyeah, I'm branching on a keyword values
12:34alexyki.e., on a var values which are keywords
12:48jcromartiespeaking of condp, is there anything that acts like the typical curly-brace "switch"?
12:52deafmacrohello, is there a way to cancel a task sent to an agent?
12:54jcromartiedeafmacro: nice nick :)
12:54jcromartiedeafmacro: could you send a fn that depends on a ref that you can toggle from somewhere else?
12:54deafmacrojcromartie: heh thanks :)
12:56jcromartie,(let [cancel-ref (ref nil)] (fn [] (when-not @cancel-ref (println "Doing my thang"))))
12:56clojurebot#<sandbox$eval__4729$fn__4731 sandbox$eval__4729$fn__4731@176dad5>
12:56deafmacroI could but would it stop the agent?
12:56jcromartieit wouldn't *stop* the agent, but you have control over what fn you send to it
12:58jcromartie,(let [cancel-ref (ref nil) job (fn [] (when-not @cancel-ref (println "Doing my thang")))] (job))
12:58clojurebotDoing my thang
12:58jcromartie,(let [cancel-ref (ref nil) job (fn [] (when-not @cancel-ref (println "Doing my thang")))] (dosync (ref-set cancel-ref true)) (job))
12:58clojurebotnil
12:59jcromartiejust an idea
13:01deafmacrojcromartie: thanks! will take that approach and see what I get
13:01jcromartiethat's probably a cleaner way than killing a thread :)
13:02deafmacrojcromartie: true. the java docs recommed the same. makes sense too. one would want to control how the thread exits
13:03jcromartieyeah at least in the iPhone/ObjC world that I work in most of the time some very nasty things can happen when something goes wrong in a thread... but that's mostly because it's not GC'ed
13:04somniumsomehow that mechanism makes me think of bureaucracy (upon receiving an order, first call your supervisor and confirm that he meant it, if his phone is busy keep trying...)
13:06jcromartiethe point being that bureaucracy is bad?
13:13somniumno particular point, just an image of (send secret-agent #(when @im-not-kidding (activate-the-bomb %)))
13:14fdaoudsomnium: now there's a DSL if I've ever seen one :-)
13:14mattreplit's the difference between being told it's time to leave and being thrown out
13:14arohnersomnium: sure, but you could have updated information
13:14arohner(send secret-agent #(when @bad-guys-dont-give-up (activate-the-bomb)))
13:15arohnerblowing up the bomb after surrender is generally considered bad form
13:15arohner:-)
13:16somniumjava.lang.Exception "we lost the war because our operatives couldnt phone our destryed headquarters"
13:17stuartsierrajava.lang.DoomsdayDeviceActivatedException
13:17arohnersomnium: that
13:17arohnersomnium: that's why you want good defaults
13:18stuartsierra(try (launch-attach) (catch java.lang.RogueCommander (abort)))
13:19somnium:-)
13:19ohpauleezwill someone write about how Clojure is capable of not only stopping runaway trains, but saving all of humanity
13:20stuartsierraEveryone will be protected by Refs.
13:20ohpauleezSTM will set you free
13:20stuartsierraResources are allocated fairly to all agents.
13:21stuartsierraNo more mutation.
13:29ohpauleezhaha
13:31alexykwhat's the max int again?
13:31stuartsierra,(Integer/MAX)
13:31clojurebotjava.lang.NoSuchFieldException: MAX
13:31stuartsierra,Integer/MAX_VALUE
13:31clojurebot2147483647
13:31technomancyInteger/MAX_VALUE
13:32alexykah ok
13:32technomancydoh, too slow
13:32stuartsierra:)
13:32stuartsierraclojurebot needs a "did you mean ...?" feature :)
13:32technomancyit's pretty good at fuzzy matches on keywords
13:32technomancybut not on code. =)
13:33stuartsierrayeah
13:35stuartsierraThat's the magical editor everyone wants: your code is wrong, it should be ....
13:39hiredmanstuartsierra: did you see abi-watch?
13:40stuartsierrano
13:40hiredmanhttp://www.thelastcitadel.com/lab/abi-watch/1.1.x-1.0.x.diff.html
13:40hiredmanhttp://www.thelastcitadel.com/lab/abi-watch/
13:41stuartsierraok
13:41hiredmanI haven't tied it all together yet, but it's some scripts that generate diffs of, basically, the various members and types defined in java
13:41stuartsierracool
13:43hiredmanso in http://www.thelastcitadel.com/lab/abi-watch/master-1.0.x.diff.html you can scroll down and see where the RestFn constructor gained an argument
13:44stuartsierraI see
13:46hiredmanthe class files generated by clojure are full of gensyms so doing diffs is difficult
13:47hiredman(possibly impossible)
13:47stuartsierrayeah
14:08hiredmanI wonder how hard it would be to add an interop form to the compiler that allows the direct use of java operators
14:08hiredman(jop + (int 1) (int 2))
14:11cemerickthat's getting close to what rhickey has called java-in-parens
14:11cemerickthough it's probably more like host-in-parens these days
14:24alexykhow clojure can exist as a lisp with all that vomit-inducing java underneath, teaming with monsters and reptiles, is amazing
14:24alexyklike "The Matrix"
14:24ordnungswidrigaloha
14:24alexykguten tag
14:25alexykor, guten :tag!
14:28ordnungswidrighehe.
14:29alexykyeah, I was always curious how German programmers handle English tag used everywhere
14:29alexykexcept Perl, which blesses things
14:31alexykahould be abend too now probably
14:34alexykordnungswidrig: when does tag become abend?
14:34alexyki.e. what hour of the day, roughly
14:34ordnungswidrigalexyk: hard to say, I think 6 o'clock would be commonly agreed upon
14:35alexykok, so it's more like evening than afternoon
14:35alexykand do you say guten nacht when meeting in the evening, or is it mainly for good bye and good night?
14:36ordnungswidrigyes, "gute nacht" is literaly "good night" and only used like you said
14:36ordnungswidrigafternoon is "nachmittag" (nach/after mittag/noon)
14:38alexykok
14:39alexykso do people say gute nachmittag or guten abend around say 3-4?
14:40jasappwhat's more important than saying, "Bier bitte."?
14:41ordnungswidrighmm, no, nobody would say "guten nachmittag", it's until about 6-7 that they say "Guten Tag" / "Hallo" . They say "Grüß Gott" mainly southern germany the whole day and "Moin Moin" in the most northern parts.
14:42alexykjasapp: I thought it's "bier schnelle" or something like that :)
14:42ordnungswidrigjasapp: "Ein Bier, bitte" would be more polite. And perhaps the kind of Bier you'd like: Lager, Kölsch, Weißbier, Dunkles, Export, Radler or the brand
14:42jasappahh
14:42ordnungswidrig"Schnell, ein Bier" / "A Beer! Quick!"
14:42jasappgotcha, nice.
14:43alexyk(schnell (ein 'bier)) ; smoothly steering back into clojure
14:47ordnungswidriganybody used fleetdb yet?
14:59hiredmanI think something like jop would be needed to turn Numbers.java into numbers.clj
15:00hiredmanand it seems like adding a special form would be a good place to start trying to get a handle on the Compiler :D
15:06somniumjust need to wrap the 220-or-so asm methods in a simple s-expression api :P
15:06alexykwhat's the single fun for not empty? again
15:06somniumseq
15:06alexykright, but for nil?
15:07somnium,(seq nil)
15:07clojurebotnil
15:07alexyk,(seq :a)
15:07clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword
15:07alexykI need a non-empty test to pass to filter
15:07alexykwithout #()
15:08ordnungswidrigsigh
15:08somniumwhat does non-empty mean?
15:08chouserdoes protected static on a method mean anything in that package can use it, but other packages can't?
15:08alexyksorry. not-nil would do
15:09somnium,(nil? nil)
15:09clojurebottrue
15:09ordnungswidrigI have a var declared in a lib, say a switch to enable debug tracing. How can I make a client of the lib change the var? With "with-bindings?
15:09hiredmansomnium: well, most of the asm stuff would be taken care of via the compiler
15:09_atochouser: http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html
15:09alexykduh, I can just extract the damn thing, it will be its own filter
15:09hiredmanfunction application is method call
15:10Ober2WARNING: JRuby does not support native extensions or the `mkmf' library.
15:10alexykbtw I take my hat off to you folks brave enough to brave the java. It's hidden so well!
15:10hiredmanand there is the . interop form, so I don't know that you would need to wrap that much
15:10Ober2oops wrong chan
15:10alexykbegone, ruby! do..end!
15:11somniumhiredman: youve been playing with java asm havent you? is enough exposed in c.c.compiler to do it with a macro?
15:11hiredmanI don't know
15:11hiredmanI don't understand the compiler
15:12somniumdoing ,(show c.c.compiler) was rather intimidating
15:12hiredmanheh
15:12hiredmanc.l.compiler
15:13zaphyr#<CompilerException java.lang.IllegalStateException: Nested #()s are not allowed (run_stream.clj:26)> ? :(
15:13hiredmanyou can put a #() inside a #()
15:13chousercan't
15:13hiredmanthank you
15:13chouser:-)
15:13zaphyrlol, got confused there :)
15:14chouser_ato: thanks
15:14zaphyrthinking about it though, what would % mean? so stands to reason
15:14ordnungswidrighiredman: is there an alternative other than fn for nested #()'s?
15:14hiredmanuh
15:14ordnungswidrigs/'//
15:14hiredmanno
15:14ordnungswidrigperhaps it's good this way
15:17zaphyryeah, after a minor refactor i removed the need for nested #()s, and shortened my expression down by about 50%, so it helped me along in this case.
15:25cemerickI'm amazed at what I can do with enlive almost every day
15:36wlrcemerick: maybe a nice blog post or three would help us less telepathic users of enlive ;-)
15:37cemerickwlr: yeah, it's definitely in the cards. Monday might be a good slack day. :-)
15:37wlrcemerick: looking forward to it!
15:41Mec,(.nextDouble java.util.Random.)
15:41clojurebotjava.lang.ClassNotFoundException: java.util.Random.
15:45jcromartieis there a way to attach middleware to every route in a compojure app?
15:45jcromartiewithout naming the handlers?
15:49jcromartiealso: why is the compojure wiki not written in compojure? :P
15:49chouserwhy is emacs not written in clojure?
15:49hiredmanrms's shortsightedness
15:50chouserheh
15:50jasappwasn't there a group of people that started trying to write emacs in common lisp?
15:50hiredmansure
15:50jasappa rather substantial effort, if I remember correctly
15:50hiredmanyeggie is rewriting it in javascript :P
15:51chouserin what he calls javascript
15:54lpetitHi, any ccw user in the room ?
15:54lpetitI guess I already know the answer :-(
15:55the-kennylpetit: What's "ccw"?
15:55lpetit~ccw
15:55clojurebotccw is http://github.com/laurentpetit/ccw
15:55lpetit~counterclockwise
15:55clojurebotCounterclockwise aka ccw at http://code.google.com/p/counterclockwise/
15:55lpetiteclipse plugin for clojure
15:56the-kennyah
15:57alexykwhat's the shortest way to filter non-nil values only from a seq?
15:57alexyk(filter <what?> [1 nil 3]) => [1 3]
15:58lpetit,(doc find)
15:58clojurebot"([map key]); Returns the map entry for key, or nil if key not present."
15:58lpetit,(doc filter)
15:58clojurebot"([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."
15:58lpetitidentity
15:58lpetit,(filter identity [nil false :a])
15:58clojurebot(:a)
15:58lpetitgloups
15:58alexykidentity is ok
15:58lpetitnope, does not work for false
15:59somnium,(remove nil? [nil false :a])
15:59clojurebot(false :a)
15:59lpetitthx somnium
15:59Raynessomnium: I was two seconds away from pressing enter, you...
15:59alexykI don't expect false
15:59RaynesI need to remap my parentheses keys. ;)
15:59lpetitnil? is shorter than identity so it's the shortest you were after :-)
15:59alexykRaynes: it's Florida sun :)
16:00zaphyrahh, (remove x y) == (filter (complement x) y)?
16:00lpetit~source remove
16:00lpetitliterally, yes
16:00zaphyr\o/ :D
16:00lpetit:)
16:02jcromartiewhat's the case for false, anyway?
16:02jcromartieaside from Java interop
16:03zaphyr,(empty? false)
16:03clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Boolean
16:03chouserjcromartie: I think that's it.
16:08alexykthe beauty of clojure: you think of what a defn should be called, write it down, call it, and it's there
16:08alexyk"Clojure: the core is always there for you"
16:10JayMis there yet a name for someone who programs in Clojure?
16:10JayMClojurers?
16:10RaynesJayM: I'm Anthony. Does that count?
16:10Raynes:p
16:10JayM:)
16:12alexykRaynes: well, I'm not Anthony, so it says nothing of the class :)
16:12alexykconsurers (inverting jure)
16:13RaynesWe should call them Anthonyers.
16:13alexykclojurassic park rangers
16:13alexykRaynes: then at least richers
16:16JayMin any case, i'm a wannabe, having a hell of a time getting swank-clojure installed
16:16JayMELPA doesn't like me
16:16RaynesJayM: Even if it errors or something, it might still be installed.
16:17JayMRaynes: i keep getting: trying to parse http response code in odd buffer
16:17RaynesOh.
16:17RaynesThat's ELPA madness.
16:17RaynesStab it three times in the chest and move it aside.
16:17JayMhaha, ok
16:18JayMmight just be something in my config...trying clean now..
16:28thearthurhow do i (use 'clojure.zip) when it conflicts with the name next in clojure.core?
16:28hiredmanyou don't
16:28hiredmanyou require it
16:28thearthuri want to use zip/next to refer to that
16:28hiredman,(doc require)
16:28clojurebot"([& args]); Loads libs, skipping any that are already loaded. Each argument is either a libspec that identifies a lib, a prefix list that identifies multiple libs whose names share a common prefix, or a flag that modifies how all the identified libs are loaded. Use :require in the ns macro in preference to calling this directly. Libs A 'lib' is a named set of resources in classpath whose contents define a library of Cloju
16:29JayMbah, manual install it is
16:32Raynesthearthur: (ns ans (:require [clojure.zip :as zip]))
16:33duncanmi'm having trouble using agents
16:33duncanmif i do this, (def a (agent [])) (send a #(vec 1 2 3))
16:33duncanmeventually, @a will be [1 2 3], right?
16:34kotarakduncanm: no. you want (send a #(vector 1 2 3))
16:34hiredmanneither
16:35kotarakah, yes
16:35hiredmanthe first argment is hte current state of the agent
16:35kotarakthe state
16:35kotarak(send a #(do % (vector 1 2 3)))
16:35hiredman(constantly [1 2 3])
16:36duncanm(send a #(constantly [1 2 3]))
16:36duncanmi did that, and a is still []
16:36hiredmanwait
16:36kotarak(await a)
16:37duncanmand it stalls
16:37hiredmanyes
16:37hiredmanawait waits for the action to run
16:37duncanmwhich should return immediately, shouldn't it?
16:37duncanmit's #(constantly [1 2 3])
16:38hiredmanit depends on things
16:39hiredmanif you are still using the same agent, the agent will have errors from you previous attempts, but send should should throw an exception in that case
16:39hiredmanand I am not sure about the behaviour of await on agents with errors
16:39duncanmahh
16:39Chousukeum, don't you need (send a (constantly [1 2 3]))
16:39hiredmanChousuke: right
16:39hiredmansend also uses a fixed size threadpool to run actions
16:40hiredmanso if you are sending other things your actions my que up
16:41duncanmhttp://gist.github.com/295146 -- is this a correct usage?
16:41duncanmi dunno if i got the arity right for this: #(calculate-offset %1 file sec %2 %3)
16:41thearthurwhat is the apropriate way to alias the name space clojure.zip to just zip?
16:42hiredmanduncanm: the first argument to the agent action is always the state of the agent
16:42chouser(ns ... (:require [clojure.zip :as zip]))
16:42Raynesthearthur: Hiredman and I both told you about 7 minutes ago.
16:43Chousukeduncanm: looks correct
16:43hiredmanand I would use send-off instead of send for anything with a sleep in it
16:43duncanmhiredman: okay
16:43thearthurwhat wrong with this (require 'clojure.zip :as zip)
16:44the-kenny,(require '[clojure.zip :as zip])
16:44clojurebotnil
16:44hiredmanthearthur: look at the form with :require that chouser showed you
16:44hiredmanwhat is the difference?
16:44thearthurRaynes, I'm looking to do it from the repl with out setting the namespace
16:45Raynesthearthur: (require '[clojure.zip :as zip])
16:45thearthurThanks Raynes :)
16:45Raynesthearthur: the-kenny got it first. :p
16:46duncanmahh
16:46duncanmi'm getting close
16:46duncanmi still have trouble using condp; i keep on asking the same question without getting how to use it
16:47hiredman,(condp = 6 6 :six 7 :seven)
16:47clojurebot:six
16:47hiredman,(condp = 7 6 :six 7 :seven)
16:47clojurebot:seven
16:48duncanmhiredman: i want to use condp just like cond, but i also want to use :>>
16:48duncanmhiredman: so i don't know what to use for the 'pred'
16:48hiredmanduncanm: that sounds like a bad idea
16:49hiredmanI suggest you just wrap cond in a let
16:49duncanmhiredman: so what i can do?
16:49duncanmahh
16:49duncanmyeah
16:49duncanmlet me do that
16:49hiredmanI will let you do that
16:49hiredman*let*
17:02alexykhow do I (use ...) a package but exclude a defn which conflicts?
17:04the-kennyalexyk: :exclude?
17:04the-kennys/?/ ?/
17:04alexykok
17:04alexyksay I successfully did a (use ...) in one ns, and have a conflict in another. Can I refer the old one with some exclusions?
17:07alexykso if my use is: (use '(incanter core stats charts)), how do I exclude group-by?
17:07alexyki.e. where do I stick it
17:08chouseryou want to exclude incanter's group-by, or clojure's?
17:09alexykchouser: I already have clojure's sitting in my ns. I'd drop whichever :)
17:09alexykif I can choose, it would be nice
17:10chouseryou can ns-unmap the one that's there (core) and then do what you want.
17:11alexykah, so it does the use after all, but simply warns about group-by
17:11alexykthat's what I needed
17:11alexykbetter it said "warning" or something
17:12alexykor maybe not...
17:12alexykit skips the whole unit where the conflict is?
17:26lygarethey y'all could I get help with a question?
17:26lygaretI need to transform a symbol to an equiv string
17:26lygaretlike (tostring 'one) => "one"
17:27jasapp,(doc name)
17:27clojurebot"([x]); Returns the name String of a symbol or keyword."
17:27zaphyr,(name foo)
17:27clojurebotjava.lang.Exception: Unable to resolve symbol: foo in this context
17:27zaphyroops.
17:27lygarethaha
17:27zaphyr,(name 'one)
17:27clojurebot"one"
17:27hiredman,(name 'foo)
17:27lygaretAwesome, thanks guys
17:27clojurebot"foo"
17:27hiredman,(str 'foo)
17:27clojurebot"foo"
17:27hiredman,(.toString 'foo)
17:27clojurebot"foo"
17:27lygaretI couldn't find that in the docs
17:27hiredman,(prn-str 'foo)
17:27clojurebot"foo\n"
17:27hiredman,(pr-str 'foo)
17:27clojurebot"foo"
17:28jasapp,(with-out-str (print 'foo))
17:28clojurebot"foo"
17:28zaphyr%D
17:28hiredman,(format "%s" 'foo)
17:28clojurebot"foo"
17:29zaphyrhiredman- for all your symbol to string needs :)
17:30zaphyris there a convenient way to check if a sequence is lazy, like printing it without forcing all the elements?
17:31Chousukeyou can check whether it's a LazySeq, but I think that won't cover all lazy seqs :P
17:32zaphyryeah, i kind of want to see how much has already been realised
17:32zaphyrclass doesn't give me that
17:33ChousukeI don't think there's any way to know that.
17:33Chousukeunless you specifically construct a lazy seq that keeps track of its progress
17:33hiredmana lazy-seq is still a lazy-seq, even if it has been realized
17:34zaphyryeah. i'm not having a problem right now, it just occured to me in some situations it might be handy to check things are working as you expect
17:34zaphyrnot in a program, more at the repl
17:35RaynesOh no! I'm being garbage collected!!! Quick, somebody, hold my head!!
17:35zaphyr:)
17:35ghotli_looking through the docs, can't find this function. how do i create a long list of the same number.
17:35ghotli_ie (5 5 5 5 5 5 5)
17:36zaphyr,(take 10 (constantly 5))
17:36clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$constantly__4704$fn__4706
17:36chouser,(repeat 10 5)
17:36clojurebot(5 5 5 5 5 5 5 5 5 5)
17:36ghotli_*sigh* wow.
17:37zaphyrnot constantly
17:37ghotli_i'm surprised i didn't just guess repeat
17:37ghotli_anyway thanks!
17:37hiredman,(take 5 (iterate (constantly 5)))
17:37clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$iterate
17:37hiredman,(take 5 (iterate (constantly 5) 5))
17:37clojurebot(5 5 5 5 5)
17:40zaphyrahh, yeah. i got constantly muddled with repeat
17:43Chousuke,(take 5 (repeatedly (constantly 5))) one more way :P
17:43clojurebot(5 5 5 5 5)
17:44zaphyrthrow an identity in there for good measure :)
17:44chouser,(take 10 (iteratate identity 5))
17:44clojurebotjava.lang.Exception: Unable to resolve symbol: iteratate in this context
17:44chouser,(take 10 (iterate identity 5))
17:44clojurebot(5 5 5 5 5 5 5 5 5 5)
17:45zaphyri still can't get over how absolutely cool lazy
17:45zaphyrmeh. irc client fail. :/
17:45Chousukezaphyr: your sentence wasn't fully realised :P
17:45zaphyr:)
17:45chouserheh
18:07ghotli_how about ripping off the first few items of a seq and returning the rest
18:07ghotli_rest will just rip off the first item
18:09zaphyr,(drop 3 '(1 2 3 4 5 6 7))
18:09clojurebot(4 5 6 7)
18:09dakroneghotli_: use (drop ..)
18:09ghotli_wonderful. thanks.
18:10zaphyrthere's also drop-while which takes a predicate instead of a count
18:11billsmithaustin,(println "hello world")
18:11clojurebothello world
18:14zaphyrhmm. why is there an nthnext when there is a drop?
18:14zaphyrsymmetry with nth?
18:15hiredman,(doc rest)
18:15clojurebot"([coll]); Returns a possibly empty seq of the items after the first. Calls seq on its argument."
18:15hiredman,(doc next)
18:15clojurebot"([coll]); Returns a seq of the items after the first. Calls seq on its argument. If there are no more items, returns nil."
18:15zaphyrahh
18:15zaphyrthanks
18:34Rayneshiredman: You should add an equivalent of lambdabot's @faq. clojurebot: Can Clojure <insert something here>?, and clojurebot should reply with "Yes! Clojure can do that!".
18:34RaynesSomething like that.
18:34hiredmanclojurebot: can clojure do so and so?
18:34clojurebotexcusez-moi
18:35zaphyrclojurebot: can clojure make the tea?
18:35clojurebotThat is the one thing Clojure can not do.
18:35zaphyrwhy not?
18:36hiredmanit's complicated
18:36technomancysomeone please write a HTCPCP module
18:36technomancyit's not tea, but it's a step in the right direction
18:37zaphyr:)
18:38technomancyrfc2324 is always good for a laugh.
18:38neotyktrue
18:39neotykis following true statement: c.c.http.agent is not utilizing NIO?
18:40neotyk~def c.c.http.agent
18:40zaphyrhmm, i need a combination of reduce and split-while- sort of like "split at the point the sum of the head is greater than", is there a neat trick i can use to do this?
18:41RaynesWhy can't java.io.File's mkdir/mkdirs method make directories with dots at the beginning? It appears to fail silently. Is it some security crap or something?
18:43hiredmanworks for me
18:46RaynesHrm. It works for me now...
18:46RaynesMy code must be constructing the File wrong.
18:47RaynesOh, I see. Doesn't like a trailing forward slash at the end.
18:47hiredmanor you are using a relative pathname with no idea of where your working directory is
18:48RaynesOr it doesn't like a trailing forward slash at the end.
18:48RaynesWhich is the problem. :p
19:01neotyk,(let [f (partial (fn [a b] (str a " " b)) "fixed")] (println (f "one")) (println (f "two")))
19:01clojurebotfixed one fixed two
19:01neotykevery day Clojure brings something new
19:01neotykthis is great
19:03mabesI've seen # used in macros, but I can't seem to find documentation on what that does, any pointers? (i.e. `(defn ~fn-name [options#]... )
19:03tcrayfordit makes a gensym
19:03hiredmanmabes: it it gensyms inside syntax quoted forms
19:03hiredman,`a#
19:03clojurebota__4961__auto__
19:04tcrayford,(doc gensym
19:04clojurebotEOF while reading
19:04tcrayford,(doc gensym)
19:04clojurebot"([] [prefix-string]); Returns a new symbol with a unique name. If a prefix string is supplied, the name is prefix# where # is some unique number. If prefix is not supplied, the prefix is 'G__'."
19:04mabesahh, thanks
19:04tcrayfordwhich prevents variable capture. See chapter 9 of on lisp
19:04Rayneshttp://java.ociweb.com/mark/clojure/article.html#Macros
19:05mabesgreat resources, thanks all
19:20herdrickhi folks - what is the deal with Incanter shipping with all it's dependencies, including Clojure?
19:20herdricki don't see an easy way to remove it's version of clojure from Incanter
19:21herdrickas it ships Clojure in the same jar file that it puts Colt and many other things in
19:22tcrayforduse lein instead then?
19:22RaynesWhat Mr. Ford said.
19:22herdrickwell, i'm not using lein yet. also, would that work?
19:23herdrickwouldn't lein just install the same jars?
19:23herdrickthe problem is that things I need and things i want to avoid are in the same jar
19:23tcrayfordlein will pull all your dependancies as needed
19:24herdrickso it will start with a dependency-less Incanter and then get deps as needed?
19:25herdrickso where is this dependency-less version of Incanter
19:25herdrick?
19:25tcrayfordit'll grab all of incanters deps when you run `lein deps`
19:25herdricki don't want all it's deps
19:25herdrickex. Clojure
19:25tcrayfordhow do you propose running it without its deps?
19:26herdricki already have the Clojure installed that i want
19:26tcrayforddoes incanter ship with an old version?
19:26herdricki'm saying that Incanter seems to do overkill on the deps
19:26herdricknot sure, i guess it might be ok
19:26herdricki sure don't like having multiple versions of Clojure hanging around tho
19:27tcrayfordhah
19:27tcrayfordit doesn't make a huge amount of difference unless you want to be using super cutting edge features
19:27tcrayfordat least as far as I've found
19:27herdrickhmm, ok
19:27herdrickbtw i still don't think lein would help here
19:28herdrickbut you're probably right that the thing to do is just use incanter's clojure
19:28herdrickeven though it may break something
19:28herdricksigh
19:28zaphyrhmm. surely there is a way to avoid this monstrosity? http://paste.lisp.org/display/94395
19:29tcrayfordzaphyr: what does that do?
19:30zaphyrit's like reduce and map
19:30hiredman,(doc reductions)
19:30clojurebot"([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init."
19:30zaphyraha! thanks :D
19:30hiredman,`reductions
19:30clojurebotclojure.contrib.seq-utils/reductions
19:43wtetzner_i'm trying to use jvisualvm to profile my program, but it says it can't profile when class sharing is turned on
19:43wtetzner_So i set (setq swank-clojure-extra-vm-args '("-Xshare:off")), and jvisualvm shows that the -Xshare:off parameter was used, but it still says that sharing is turned on
19:43wtetzner_has anyone else had a problem like this?
19:44hiredmanis jvisualvm written in java? maybe it needs sharing turned off for its vm
19:45wtetzner_i'll try that
19:46wtetzner_no, it still tells me that class sharing is enabled
19:47wtetzner_is there anything in swank-clojure that would cause sharing to be turned on, even though i added it to the swank-clojure-extra-vm-args?
19:53Mecif add-classpath is deprecated, what should be used?
19:56hiredmanit's complicated, but as of now there is no clear replacement
20:04Mecdidnt seem to work anyway
20:24MecIs there a way to add a directory of clj files without having to call load-file on each?
20:32chouserthe order of loading them doesn't matter?
20:32chouseranyway, no, I know of no such thing.
20:32tcrayfordyou can just (map load-file (file-seq dir))
20:33tcrayfordoops, laziness
20:38alexykto create a catch-all clause for cond, do we use true ?
20:39tcrayford:else
20:39alexyktcrayford: but any non-nil will do like true, right
20:39tcrayfordtry it at a repl
20:39tcrayfordusing else is a standard though
20:40MecI'm trying to get the Programming Clojure sample code to load in a real repl, looking at the .bat file they use i dont see any explicit calls to the .clj files so how are they loading?
20:40tcrayfordthey load on the java classpath
20:40tcrayfordiirc
20:41alexyk,(let [x 0] (cond (< x 0) (print "neg") (> x 0) (print "pos") true (print "zero")))
20:41clojurebotzero
20:55Mecthis is a nightmare
21:19Mecis there a way to see the classpath for a currently running repl?
21:20hiredmanclojurebot: classpath?
21:20clojurebotclasspath is (System/getProperty "java.class.path")
21:22Mecthanks
21:26alexykis there an idiom to shorten this:
21:26alexyk(if twice-wider? (* up 2) up)
21:27alexykok am back, looking for a shorter idiom than: (if twice-wider? (* up 2) up)
21:27alexykspecifically for tomoj: what's shorter than (if twice-wider? (* up 2) up)?
21:29tomoj(* up (if twice-wider? 2 1)) is a tiny bit shorter :(
21:30tomojbut I'd prefer yours
21:32tomojsomething like (-?> up twice-wider? (* 2)) seems to get at the idea better
21:32tomojbut I don't like that syntax
21:32tomojand -?> is probably a bad name for it
21:34tomojoh, and -?> is already taken in contrib
21:34alexyktomoj: -?> fits well here in fact
21:36tomojexcept, I dunno if you'd want to have more than one form to conditionally thread through
21:36tomojif so you'd certainly want to change the syntax, I think..
21:51alexykyay! chouser's back!
21:52chouserhuh. 6 minutes this time.
21:53chouserhuh. 6 minutes this time.
21:55alexyklooks like an ice-covered internet
22:06alexykliebke: ping
22:06liebkehey
22:07alexykliebke: is there an option to set size on charts?
22:07liebkeyes
22:07alexyke.g., 5cm x 5cm?
22:07liebkepixels, not cm
22:07alexykis it png only?
22:07alexykI need PDF for the paper
22:08alexykor a way to control size in cm's
22:08liebkejfreechart doesn't do pdf unfortunately
22:08alexykoh well
22:08alexykcopy-paste into R then :(
22:09alexykwonder though png will be eaten by latex
22:09TheBusbyliebke: what was the trick to dictate pixel size again? And would that impact the number ,er keys?, that appear legibly at the bottom of the chart?
22:10alexykliebke: btw, vnc works like a charm with incanter
22:10MecI'm using the following in my .emacs, but it doesnt seem to be doing anything: (setq swank-clojure-extra-classpaths (list "F:/Tools/programming-clojure/code"))
22:10liebkein the save function, it's :width and :height
22:10alexykgraphs are safe in the cloud
22:10liebkealexyk: great
22:10TheBusbyahh save...
22:10alexykliebke: so any plans for pdf/eps? what can be done?
22:11liebkeTheBusby: they also can be used in the view function
22:11TheBusbythank you, didn't think to check save/view
22:11liebkealexyk: I looked into it once, nothing clean for generating pdfs at the time
22:11alexykit's probably a deep flas, because pdf needs vector graphics... does it mean jfreecharts is raster only?
22:12alexykflaw
22:12liebkealexyk: no, they appear to be vector
22:12alexykcemerick has a pdf business
22:13alexyklet's enroll cemerick in his pro bono time :)
22:13liebkealexyk: there is a lib that will do it with jfreechart, but it was too many additional dependencies, and there might have been some licensing issues (can't remember)
22:13alexykliebke: ok, so not so bad
22:15tomojI kind of want to auto-require repl-utils :as repl on my slime repls
22:16tomojbut then I worry someday I'll run into a conflict :(
22:16alexyktomoj: live for today! sort the tmrw conflicts tmrw
22:17TheBusbyany hints on how I could keep the X-axis legible for a line-chart?
22:17tomojguess I could make a keybinding that does it with a C-u switch for specifying the :as
22:20liebkeTheBusby: why are they illegible?
22:20TheBusbyliebke: for 40 points, the text ends up being too small and they get turned into dots
22:20liebkemake the chart wider
22:21TheBusbyyeah, but around 1900x1200 it becomes the limit though
22:21TheBusbyI noticed the y-axis just used a sequence of numeric values
22:22MecIs anyone familiar with adding classpaths to clojurebox?
22:22TheBusbyany way to do something similar for the x-axis? or is that a different kind of chart?
22:23liebkedo you want a line-chart or an xy-plot? are x and y both continuous data?
22:24liebkeif one set of values is categorical you can create a 'horizontal' bar-chart (:vertical false), which makes it easier to see the labels when you have lots of categories
22:25TheBusbytrying xy-plot now
22:26TheBusbyneither x or y is categorical, so it sounds like I'd be better servered by the xy-plot
22:26liebkeyeah, use xy-plot
22:26liebkeline-chart is just a different skin on a bar-chart
22:28TheBusbyliebke: perfect, much thanks for both incanter and your help!
22:29liebkeTheBusby: you're welcome, good luck
22:30dnolenMec: I don't know if there are many Windows Clojurians on channel. Did you try the mailing list?
22:31MecI'm following a set of instructions from the mailing list
22:34Mecsuccess finally
22:41tomojI was so happy I got an assignment at work where I can use clojure
22:42tomojnow I'm sitting here editing a 500 line xml file
23:05hiredmananyone have adivce to give for clojure.lang.Compiler?
23:07brweber2anyone have pointers to simple examples of using clojure.zip?
23:07brweber2I'm looking for more examples of zippers
23:09herdrickbrweber2: I support your quest
23:09herdricki'd like to see that too
23:10brweber2herdrick I seem to keep finding the sample trivial example and nothing else. I'm really interested in using zippers, not reading academic papers at this point :)
23:12herdrickbrweber2: yeah
23:14hiredmanjava.lang.VerifyError: (class: user$eval__1, method: invoke signature: ()Ljava/lang/Object;) Expecting to find integer on stack (NO_SOURCE_FILE:0)
23:14hiredman:(
23:15tomojbrweber2: in general? or you have some specific use in mind?
23:16brweber2tomoj I'm looking for general examples. I'm hoping to implement something like a simple namespace tree...
23:17tomojoh, I never built my own zipper, just used xml-zip
23:39hiredmanser=> (jop + (int 2) (int 1))
23:39hiredman3
23:39hiredman:D
23:44hiredmanbeautiful, compiles to an iadd