#clojure logs

2011-04-02

00:08sritchiehey guys, why does ##(. "face" (substring 1)) work?
00:08sexpbot⟹ "ace"
00:08sritchieI'm not sure what's going on here
00:13amalloysritchie: because that's the . syntax?
00:13amalloy&(macroexpand '(.substring "face" 1))
00:13sexpbot⟹ (. "face" substring 1)
00:14amalloywrapping the method call in parens is optional when there are more args; for no-arg methods it's needed to distinguish between a method and a field
00:14sritchieokay, that's what was confusing me
00:16sritchiethanks, I see this now on a closer reading about the dot special form -- (. instance-expr (method-symbol args*)) or (. instance-expr method-symbol args*)
00:17amalloyit tends to be easier to write macros that expand directly into (. obj method args) rather than the intermediate (.method obj args), if you don't know what method you'll be using ahead of time
00:17technomancyTimMc: bleh; I tested it with a project that was already requiring robert.hooke
00:18TimMctechnomancy: Off to bed, will see any highlights.
00:22amalloyTimMc: sounds worryingly as if you are offering a highlights reel of your bed
00:29technomancyTimMc: just pushed th efix
00:32mecfor some reason (map #(.fillRect g (first %) (second %) 100 100) points) inside a paint isnt working, but if I get rid of the map and just do (first points) it works fine
00:33tomojI blindly recommend doseq
00:33mecbah of course
00:34meccurse you laziness
00:34tomojmapping side-effects seems more evil to me, I think, than to many others
00:47amalloymec: (map #(...)) should almost always be either a for or a doseq
00:47amalloyeg here (doseq [[a b] points] (.fillRect g a b 100 100))
00:50amalloyit must still be april first. adblock is asking if i'd like to try out their new augmented-reality billboard blocker
00:52mecamalloy: yes, it looks much nicer that way
00:55amalloymec: destructuring is king. if i type "first" or "second" i usually stop and check myself for a fever. sometimes it's right, but...
00:57mecdeffinitly beats (map (fn [..] too, it just never really occurred to me to use for in that place :x
00:58amalloyhaha. i just started typing (map #(...)) in my code. hard habit to break
00:59mecstill have to use it instead of for if you're threading a collection, which I do all the time
00:59amalloyyes, i think it's tomoj who does some abominable things with threading for
01:00mec(->> coll #(for [x %] ...)) ;p
01:00amalloy&(->> (inc x) (for [x (range 10)]))
01:00sexpbotjava.lang.IllegalArgumentException: Wrong number of args (3) passed to: core$for
01:00mecweird
01:00amalloy,(->> (inc x) (for [x (range 10)]))
01:00clojurebot(1 2 3 4 5 6 7 8 9 10)
01:01amalloy*sigh* someone please fix his macroexpansion facilities
01:01amalloy(that is my job)
01:01mechow does that even happen
01:01amalloyhe has to macroexpand some stuff himself to confirm you're not doing sneaky things
01:02mecah
01:02amalloyat some point i broke some part of it but it is hell to debug
01:02mecI thought its running in a sandbox?
01:02amalloymec: yes, but so what
01:02amalloy&(def + -)
01:02sexpbotjava.lang.SecurityException: You tripped the alarm! def is bad!
01:02amalloythe jvm sandbox wouldn't catch that but it would make sexpbot unusable
01:03mecI thought there was also a clojure side sandbox, like for findfn
01:04amalloyyes, that's what's broken
01:05mecah
01:06tomojamalloy: s/does/did/ I suggest :)
01:07amalloytomoj: sorry, it's on your permanent record now
01:08tomojshucks
01:08amalloy$learn tomoj is a horrible threading abuser
01:08sexpbotMy memory is more powerful than M-x butterfly. I won't forget it.
01:09tomojactually I wrote (->> bar foo-in-bar count / (for [bar bars]) (reduce +)) today, though as a douchey explanation, not actual code
01:09amalloyman, his learning syntax sucks. he put two is's on that
01:09amalloy$forget tomoj
01:09sexpbotIf tomoj was there before, it isn't anymore. R.I.P.
01:09amalloyyou're off the hook
01:09tomoj:D
01:10tomojdo I abuse horrible threading or abuse threading horribly? or both?
01:10amalloyyou perform horrible thread abuse
01:10meclol this is what I just found in my code: (->> (range..) (map #(->>)))
01:11tomojI don't think I abuse horrible threads, so, I'll take that as an answer
01:11tomojwat
01:11amalloyew what
01:11tomoj#(->>) isn't even anything?
01:11tomoj.. is it?
01:11amalloyi think he missed a ...
01:12amalloyoh
01:12mec(defn note [hz sample-rate ms] (let [period (/ hz sample-rate)] (->> (range (* sample-rate ms 1/1000)) (map #(->> (* 2 Math/PI % period) Math/sin (* 127 ,) byte) ,))))
01:12mecwell that didnt work right
01:12tomojnote? overtone?
01:12amalloy$learn gist http://gist.github.com
01:12sexpbotMy memory is more powerful than M-x butterfly. I won't forget it.
01:14tomojonly now do I realize "note" and "tone" are anagrams
01:14amalloytomoj: clearly you don't play enough word games
01:14amalloycheck out stop. has like a hundred anagrams
01:14tomojif 0 is not enough, yeah
01:15meci start making silly sound combinations when i try to figure out anagrams, it never goes well
01:15amalloymy favorite is AELPST (alphabetical so as to not give anything away). it has six anagrams!
01:16tomojthank you wordsmith.org for saving me from thinking
01:16meclepast tepsal spelta
01:16tomojditto
01:17amalloymec: don't tell me any of those are words
01:17mecnope, i havnt come up with a single real word yet :x
01:17amalloyhaha k. i thought wordsmith had given them to you
01:17meci suck something fierce at anagrams
01:17tomojwordsmith came up with exactly six, which was bizarrely satisfyig
01:18amalloytomoj: oh good. i've never actually asked a computer
01:18amalloyjust came up with six and was pretty sure there weren't any more
01:19tomojare you telling me you knew CNYRFG ?
01:19meci wonder how many words there are whose every permutation is a word
01:19tomoj(rot13'd)
01:20amalloymec: pot
01:20tomojoh, now that I parse that correctly it seems pretty common
01:20amalloyhas everything but otp i think
01:20tomoj"tpo"?
01:20amalloyokay and that
01:20amalloyso uh
01:20amalloynot very many
01:20tomoj"a" and "I"...
01:20tomoj:(
01:20mecno and on ;p
01:20amalloyam
01:21amalloy$dict epe
01:21sexpbotamalloy: Word not found.
01:21tomojscrabble dictionary has many unfamiliar short words
01:21amalloytomoj: qat and qi. very important
01:21tomojso might be more if you take that as your standard of wordness
01:22amalloywell, a three-letter word almost has to have two vowels to fit the bill
01:23amalloyi can't even find a three-letter word that has five anagrams, let alone all six
01:29amalloyso i just wrote an "alternates" function: (alternates 3 (range 9)) is ((0 3 6) (1 4 7) (2 5 8)). probably it's a mistake to call (alternates 3 (range 10)); should i (a) throw an exception, (b) silently drop the 9, or (c) include the 9, making the first seq longer than the others?
01:30mec$43200000l
01:32mecyou could do like core and make alternates and alternates-all to do (b) and (c) respectively
01:34amalloy&(interleave [0 3 6 9] [1 4 7] [2 5 8])
01:34sexpbot⟹ (0 1 2 3 4 5 6 7 8)
01:35amalloycool. i'm happy with being the exact opposite of interleave, and leaving the 9 on is the easiest way to handle the error anyway
01:38mecwhats your code for alternates?
01:39amalloymec: https://gist.github.com/899263
01:41amalloyi'm currently using it for my lazy-loop, which needs to turn (lazy-loop [coll c] ... (lazy-recur (rest coll)) into ((fn lazy-recur [coll] ... (lazy-recur (rest coll))) c)
01:48anthony_I'm working on my first macro. I found that I was often doing this: (let [a (delay ...) b (delay ...) c (delay ...)] ... ), so I want to create a macro that automatically makes the bindings into delays. I have that part working, but I still have to manually deref the variables within the body. Is there a way to do that within a macro (so I can just refer to it as a/b/c instead of @a/@b/@c)?
01:49amalloyanthony_: short answer: you can probably convince clojure.contrib.macro-utils/symbol-macrolet to do this for you
01:50amalloylong answer: i don't think you want to. isn't the whole point of working with delays that you can pass them around without having to evaluate them until later?
01:50amalloyif you always deref them the moment you touch them, what have you gained?
01:59anthony_amalloy: Sorry, was AFK. I probably don't want to do that -- I was in the process of rethinking it when I figured I could use this as an excuse to learn macros. But, I didn't always immediately evaluate them. I would often only need the first few, depending on some conditions -- using delays were easier than a bunch of nested forms, or creating a lot of one-time functions.
01:59anthony_Wow, there's a lot of pronouns in that. It probably doesn't make much sense. :-)
02:00amalloyinteresting usage
02:01anthony_Yeah, it's a little strange. But a and b might be validations (or something), and c is an expensive operation (something with a database), so I only want to evaluate c if a and b are true. Of course, that's not a very good example, but maybe it makes some sense.
02:01amalloysure, i understand the idea
02:02anthony_I think there are much better ways to do that, though. Now that I know some more about macros, I'm going to give those macro-utils a closer look. Thanks for your help.
02:02amalloyanthony_: yeah, it seems easiest to just do some when-lets or something
05:04ace0x2ajey
05:05ace0x2ahey* whats a good guide for getting started with clojure
05:05ace0x2aI havent experience in functional programming, i just done a little bit ruby
06:53G0SUBI need to transform something like [:a :x :b :c :d :x :x :x :e :x] to {:e [:x], :d [:x :x :x], :c [], :b [], :a [:x]}. Any good ideas?
06:56angermanG0SUB: so you have [:s :x*]+
06:56G0SUBangerman: yeah
06:56angermanwhere :s is a symbol unlike :x
06:56G0SUBangerman: right.
06:57angermannot any "good" idea. I guess it's just looking and associng.
06:57G0SUBangerman: sure. this is a use-case for `reduce`
07:02G0SUB,(reduce
07:02clojurebotEOF while reading
07:02G0SUB (fn [[sym m] obj]
07:02G0SUB (if (= obj :x)
07:02G0SUB [sym (merge-with conj m {sym obj})]
07:02G0SUB [obj (assoc m obj [])]))
07:02G0SUB [nil {}]
07:02G0SUB [:a :x :x :x :b :x :x :c :d :x])
07:02G0SUBargh
07:03angermanhere's another idea: 1. scan the vector for non :x symbols; split. 2. each of the sublist now is (:s :x : x :x …)
07:03angermana little like dna is replicated.
07:04raekmaybe group-by or partition-by could be used
07:05raek,(partition-by #{:x} [:a :x :b :c :d :x :x :x :e :x])
07:05clojurebot((:a) (:x) (:b :c :d) (:x :x :x) (:e) (:x))
07:06raek,(partition-by (fn [v] (when (not= v :x) v)) [:a :x :b :c :d :x :x :x :e :x])
07:07clojurebot((:a) (:x) (:b) (:c) (:d) (:x :x :x) (:e) (:x))
07:07raek,(partition-by identity [:a :x :b :c :d :x :x :x :e :x])
07:07clojurebot((:a) (:x) (:b) (:c) (:d) (:x :x :x) (:e) (:x))
07:07G0SUB,(partition-by identity [:a :x :b :c :d :x :x :x :e :x])
07:07clojurebot((:a) (:x) (:b) (:c) (:d) (:x :x :x) (:e) (:x))
07:26hsuhis there a shorter way to write (doseq [x coll] (side-effect-only-fun x))?
07:29ampleyflymaybe (map side-effect-only-fun x)
07:31mduerksenhsuh, ampleyfly: you can use map, but you'll have to force evaluation then: (doall (map f coll))
07:31hsuhdoseq is cleaner then .. tks!
07:33mduerksenhsuh: i use that idiom rather often, so i made my own function for it: (def domap (comp doll map)).
07:34mduerksencorrection: (def domap (comp doall map))
07:37hsuhnice.. and how do you reuse that function across projects?
07:42mduerkseni have my own small utility project, its in there. but i had second thoughts about that recently, because i'm not sure if domap is really better than doseq. 1. doseq is a core function, and 2. i like the order of arguments. with domap, you say "i want to do <this> with all of <these>". with doseq, the order is switched. you say "with <these>, i want to do <this>", which is often more natural IMHO
07:43mduerksenand typically i first determine the values that i want to process, and then i want to specify what to do with them. that's something i like about doseq
07:45mduerksenthe reason i use domap often in my projects is simply that i discovered doall before i stumbled upon doseq :)
07:53hsuhmduerksen: i asked because i'm not sure how i can reuse an "util.clj" between projects ..
08:37TimMcIs there a shorthand in leiningen to say you want version 1.x.x of something? [1.0.0,2.0.0) is kind of verbose and hard to interpret.
09:05TimMctechnomancy: Yeah, that works -- only the file with the failing test was run on retest.
09:23TimMcCool! This works well, thanks.
09:24TimMcI notice it only reruns at the file level -- any plans on going down to the deftest level?
10:45malkomalkobecause I don't want to re-invent the wheel.. does anybody know of any functions in clojure-contrib for aggregating of positional based tuples? Like if I wanted to sum up every nth element in a vector?
10:47jkkramer,(reduce + (take-nth 2 [1 2 3 4 5]))
10:47clojurebot9
10:49__name__oh, that is nice.
10:49TimMcjkkramer: Why not apply?
10:49jkkramerno reason
10:49TimMck
10:51mrBlissTimMc: (apply + ..) will put the arguments in a list and then reduce with +, so calling (reduce + ..) directly is faster.
10:52malkomalkowhat if the input was [[x y 1] [x y 2] [x y 3]]
10:52malkomalkoand I wanted to get 6
10:52malkomalkoso sum up the 3rd position in each of those tuples?
10:53mrBliss,(reduce + (map #(nth % 2) '[[x y 1] [x y 2] [x y 3]]))
10:53clojurebot6
10:53malkomalkocool
10:58hsuhso, suppose i my webapp has logging by inserting the log synchronously on a db, i then noticed this slows my response time a lot. so i was thinking of using an agent to send the log to, and have another thread (using add-watch?) picking up those logs and adding to my db independent from the ring requests code and solving the response delay problem...is this thinking straight?
10:58TimMcmrBliss: Ah, and I suppose + can't do any optimizations on a list of inputs anyway.
10:58malkomalkowhy the need for the quote there on that tuple mrBliss ? it seems to work fine without the quote no?
10:59mrBlissmalkomalko: the xs and ys will be unbound
10:59mrBliss,[[x y 1] [x y 2] [x y 3]]
10:59clojurebotjava.lang.Exception: Unable to resolve symbol: x in this context
10:59malkomalkoah yes, got it
11:00malkomalkoduh
11:00malkomalkothanks
11:00mrBliss$source +
11:00sexpbot+ is http://is.gd/zh9ARG
11:00mrBlissTimMc: ^^
11:01mrBlissTimMc: also note the ":inline-arities #{2}"
11:01TimMcmrBliss: Ah, makes sense.
11:01mrBlissTimMc: That's also why (+ (+ a b) (+ c d)) is faster than (+ a b c d) :-)
11:02TimMcsilly
11:03malkomalkomrBliss: what do you think the best clojure doc site is right now? having trouble learning the api
11:04Raynesclojuredocs.org has examples with a lot of it's documentation.
11:04mrBlissI would also suggest clojuredocs.org
11:04malkomalkosweet
11:05mrBlisshttp://learn-clojure.com/ is also nice for beginners
11:06malkomalkojust bought the joy of clojure, really digging that
11:07mrBlissmalkomalko: have you got the paper edition?
11:07malkomalkono, final ebook version
11:18pdk(meta +)
11:18pdk,(meta +)
11:18clojurebot{:ns #<Namespace clojure.core>, :name +, :file "clojure/core.clj", :line 809, :arglists ([] [x] [x y] [x y & more]), :added "1.0", :inline-arities #{2}, :inline #<core$_PLUS___inliner clojure.core$_PLUS___inliner@1a05c93>, :doc "Returns the sum of nums. (+) returns 0."}
11:18pdk,(meta -)
11:19clojurebot{:ns #<Namespace clojure.core>, :name -, :file "clojure/core.clj", :line 842, :arglists ([x] [x y] [x y & more]), :added "1.0", :inline-arities #{1 2}, :inline #<core$___inliner clojure.core$___inliner@727249>, :doc "If no ys are supplied, returns the negation of x, else subtracts\n the ys from x and returns the result."}
11:24hsuhhow can i insert logs into a database without affecting my http response delay too much? (async i mean)
11:28mrBlisshsuh: use a future or an agent
11:29TimMchsuh: Shouldn't you be logging to disk?
11:30hsuhtimme: perhaps, but i'd like to know how to solve these problems anyway...
11:30TimMcI've never done logging before, but I usually hear about logs being written to disk or a queue.
11:31hsuhok its the same, suppose disk writing is slow, so i the main request/response code i rather just add the log to a queue, which another thread consumes and really writes to the slow io... avoiding the delay in the request/response
11:31hsuhif i'm thinking correctly
11:36TimMcI think that's the approach the big sites take, yeah.
11:37hsuhif I use a future to encapsule the "db insert", but nobody actually dereferences this future object, does the code ever get executed?
11:39theBlackDragon /S 1
11:53malkomalkoanother quick question.. min takes this form (min 1 2 3) how can I turn (1 2 3) into something that min can handle?
11:56mids(apply min '(1 2 3))
11:59malkomalkook
11:59malkomalkohttp://clojuredocs.org/clojure_core/clojure.core/apply awesome
12:37jaleyhey guys! does anyone know if there's much of an active clojure-android community around? googling around mostly finds me 1-year+ articles to the tune, "it'll work but it's slow and big".
12:47TimMcjaley: There has been almost no discussion of Android in this channel, other than to say that Android's GC is slow as hell.
12:50kephale00I haven't had any luck in the Java HotSpot spec, but does anyone know if there is a way of capping the number of threads clojure/java uses within a process (if it makes a difference the code is being launched with java -jar myuberjar.jar)
12:50jaleyTimMc: hmm ok thanks. I noticed a comment from rich encouraging support for android a while back, and the core team certainly seem to fix android-related bugs (looking at JIRA). So I just kind of wondered how people are using clojure on android is all :p
12:53TimMcI don't think Clojure is usable enough yet (performance-wise) on Android for there to be a community to speak of. :-/
12:53jaleyTimMc: this is what I was referring to (just found it in my history...) http://dev.clojure.org/display/design/Android+Support
13:04KirinDaveFinally got some email asking about Clothesline.
13:04KirinDaveMaybe a few people are using it.
13:21kephale00Wow, yeah, the best I've found is -Xsinglecpu which doesn't seem to be a commonly supported JVM arg, and it isn't available on the machines i'm working on in particular
13:59TimMchttps://gist.github.com/899696 <-- java.lang.ClassCastException: foo.core.Person cannot be cast to foo.core.Person
14:01TimMcI can't seem to reduce this any further.
14:04ataggartinteger math question: is it true for all math ops that ((int) (longA op longB)) == ((int)longA) op ((int)longB)
14:05TimMcataggart: Doubt it.
14:06TimMc,(int (- (long 0x80000000) (long 0x80000000)))
14:06clojurebotjava.lang.ExceptionInInitializerError
14:06ataggartTimMc: me too but I was hoping someone had a rigorous answer. Google is failing me.
14:06ataggartnote that (int) is java's truncating int cast
14:06ataggartso the analogue would be unchecked-int
14:06TimMcOh, you are asking about Java code?
14:07ataggartI'm asking about truncating a 64-bit integer to a 32-bit integer
14:07ataggartthis came about due to me wondering why 1.3 has a bunch of unchecked-FOO-int functions
14:08TimMc&(int (- (long 0x80000000) (long 0x80000000)))
14:08sexpbotjava.lang.Exception: EvalReader not allowed when *read-eval* is false.
14:08TimMcWhat are the bots complaining about?
14:09ataggartdunno, but 1.2 doesn't have unchecked-int, so you can't test it out the truncation op here
14:09TimMcANyway, do you see what I'm getting at?
14:09TimMclongA and longB can both be out of int range, but the difference could be inside int range.
14:10ataggartthe question is whether the result will be different once truncation happens. I haven't seen an example where the result is different.
14:12TimMcataggart: If you have a 1.3 repl, could you see what happens with (/ 0x1000000000 0x10000000000) ?
14:12ataggartya one sec
14:13ataggartreturns 1/16. using quot returns 0.
14:15malkomalkois it possible to have a system wide default project.clj for leiningen so that when you create a new project you always get swank/contrib? I hate adding those lines everytime
14:16TimMcataggart: And you get 1/16 with both longs and ints?
14:16pdkyou could say
14:16pdkthat'd be pretty swanky
14:17ataggartTimMc: ah, no. divide by zero exception. Though that would seem to argue against the -int math ops.
14:23ataggartTimMc: found one. If the math op has args outside of int range, but its result falls within int range, it behaves differently. E.g. (unchecked-int (- 2147483648 2)) => 2147483646 but (- (unchecked-int 2147483648) 2) => -2147483650
14:24ataggartthough I just realized that unchecked-OP-int still does a checked cast to int, so I'm really baffled by their inclusion in 1.3.
14:32fliebelWhat is the difference between assure and locking? I want to pour some Swing events into an atom or ref, but maintain a persistent view of it during a certain action. I do no write to it. Should I use an agent, wrap the actions in a dosync, and assure the agent, or go for a simple atom, and lock it during the actions?
14:34TimMcWhat is assure? Do you men ensure?
14:35fliebeloh, yes
14:35TimMcAnd you just want to make sure that you have a consistent view of a set of refs during a transaction, not that their values are consistent in some manner afterwards?
14:36fliebelno, just make sure some state stays the same during a set of actions.
14:36TimMcThe reads you do inside a transaction represent a stable snapshot of the world, modulo any writes you do inside the transaction.
14:38fliebelTimMc: Okay, so I don't even need to ensure it? Then what is ensure used for?
14:45TimMcfliebel: It's for preventing write skew.
14:46fliebelOkay, and what about the locking? Is that considered hacking, or bad practice? I don't want to lock up the Swing thread, but refs feel heavy, esp since I don't need so much managed stuff.
14:47TimMcSometimes you have several refs that need to be in a consistent state whenever they're read together (in some transaction.) Any other transaction that wants to write to some *but not all* of them must call ensure on the others to make sure nothing else writes to them in the meantime.
14:50fliebelTimMc: Sot it's for refs you're not going to use in any other way?
14:51TimMcIt's for the refs that need to be held constant during your transaction.
14:53fliebel&(let [at (atom 1) get-twice (fn [a] [@a (Thread/sleep 1000) @a]) fut (future (locking at (get-twice at)))] (Thread/sleep 500) (swap! at inc) @fut)
14:53sexpbot⟹ [1 nil 2]
14:53fliebelIt completely ignores the lock, or I;m doing something wrong.
14:53TimMcfliebel: http://clojure.higher-order.net/?p=50 <-- an example of ensure
14:54TimMcI'm not familiar with locking.
14:55TimMcAh, I see -- it's basically `synchronized`.
14:55fliebelmeaning?
14:56TimMcJava has a "synchronized" keyword.
14:57fliebel&(let [at (ref 1) get-twice (fn [a] [@a (Thread/sleep 1000) @a]) fut (future (dosync (get-twice at)))] (Thread/sleep 500) (dosync (alter at inc)) @fut)
14:57sexpbot⟹ [2 nil 2]
14:57fliebelTimMc: My Java is to dusty to remember what that means.
15:00TimMc&(let [at (atom 1) get-twice (fn [a] [@a (Thread/sleep 1000) @a]) fut (future (locking at (get-twice at)))] (Thread/sleep 500) (locking at (swap! at inc)) @fut)
15:00sexpbot⟹ [1 nil 1]
15:00TimMc(Your first example, but with locking around the swap.)
15:00TimMcfliebel: Do you know what it means to hold the monitor of an object?
15:00fliebelTimMc: Huh? Can you explain why that is needed?
15:00fliebeloh, uhm, let me think..
15:01fliebelno, not exactly at least.
15:01TimMcfliebel: You're spoiled by Clojure. :-P With locking, I think you have to lock *all places* where modification might take place.
15:01TimMcLocking can also be done on arbitrary Objects, not just reference types.
15:03fliebelah, okay :) So it's not that a place with a lock can be accessed only from one place, but rather, 2 lockings can not access the same object.
15:03TimMcBasically, yeah.
15:03fliebel&(let [at (ref 1) get-twice (fn [a] [@a (Thread/sleep 1000) @a]) fut (future (dosync (println "getting") (get-twice at)))] (Thread/sleep 500) (dosync (println "updating") (alter at inc)) @fut)
15:03sexpbot⟹ updating [2 nil 2]
15:04fliebelmine prints getting updating getting
15:04TimMcIn the case of dosync, transactions can be retried.
15:04fliebelI know, but I;m not sure I want that.
15:04TimMcWith locking, first-in wins, and everyone else blocks.
15:05TimMcAlso, at least one thing I've said about locking is probably not true, or at least is misleading -- locks are *hard*.
15:05fliebelTimMc: That would be desirable, except that I don't know what Swing will do. I assume events are called on the Swing thread, so that'd freeze the UI I think. :(
15:06chouserrefs may not be as heavy as you think
15:07ataggartlocking grabs the monitor of the arg. it's lower-level, but less concurrent than using refs. It's really only useful when you need to synchronize with stuff in javaland.
15:07fliebelchouser: I'd take your word for that. A bigger problem is that the dosync would be quite big, so if that retries to often, it's not good.
15:07TimMcfliebel: Try it with the dosync first and see if it's really a problem.
15:07TimMcIf it is, you can export some of the work to an agent.
15:08chouserfliebel: can you capture all the values you need in a persistent collection, then send that off to another thread (agent or future) to do the work?
15:10Havvyfliebel: Is it possible to memoize some of the work done in the (dosync)?
15:11fliebelchouser: I'd have to think about that for a bit. The use case is that I have Swing fire events, and when I render a frame, I want to to see all the buttons pressed and such in a consistent manner during the frame. So I was thinking I could pour these events into a ref or atom, and make sure I 'lock' that during the frame.
15:11TimMcfliebel: You probably don't want to do your rendering in the event loop anyway.
15:12fliebelHavvy: Probably, but at what cost?
15:12chouserfliebel: all interaction with Swing should happen in the swing thread, in which case the state of the swing widgets and events will not change.
15:13chouserfliebel: so what I'm suggesting is when you know you want to render, go into the swing thread, collect the data you need as quickly as possible (to prevent the GUI appearing to hang), then send that (immutable) data out to some other thread to do the real work.
15:13chouserwhen the work is done (creating an offscreen bitmap or something? whatever you're doing), go back into the swing thread to display your results.
15:14HavvyI'm new to Clojure, so I don't exactly know the cost of memoization. chouser seems to have an equivalent solution in which you only send the results.
15:14chouserthe state of the gui widgets might have changed in the meantime of course, but that just reality. You can choose to detect that situation and not display the now-outdated data, or whatever.
15:15fliebelhmmm...
15:15HavvyMy own question: Is there a better IRC script than http://nakkaya.com/2010/02/10/a-simple-clojure-irc-client/ ?
15:15chouserHavvy: I think memoization usually refers to avoiding work when the input data is identical to previously calculated results. What I'm describing is more of a snapshot + pipeline or something. :-)
15:16fliebelThat would force me into some kind of asynchronous model, because Swing events are callbacks.
15:16TimMcfliebel: That's pretty standard.
15:17chouserfliebel: yes. you can choose asynchronous, or "lock up" the gui until you're done rendering.
15:20fliebelI want neither. What I was describing with the ref works, except that the retries are killing… maybe.
15:20TimMcfliebel: You don't know that.
15:20fliebelI don;t know that.
15:21TimMcYou're trying to preoptimize, and you also want a unicorn.
15:21fliebelyea, I love them :)
15:22fliebelOkay, refs first, optimization later
15:22TimMcHavvy: The channel bots are written in Clojure but use existing Java IRC libs.
15:22TimMcsexpbot: source?
15:22TimMcclojurebot: source?
15:22clojurebotsource is http://github.com/hiredman/clojurebot/tree/master
15:23fliebelhttps://github.com/cognitivedissonance/sexpbot
15:25HavvySo nobody has yet made IRC libs in pure Clojure?
15:26pdki don't think sexpbot has any java code in it
15:26pdker
15:26pdkirclj
15:26pdkhell i'll go look
15:26pdkyea irclj is all clojure
15:27fliebelhah! Using ensure, the events retry, instead of the frame :) That is just as bad as locking though. Maybe some queue trickery will work, btu that is worry for later.
15:29HavvyYeah, that looks pretty good.
15:43thorwili'm trying to write a simple-as possible test to learn more about a problem. a required part is a macro provided my a library, that defines a java class.
15:44thorwili run into "NoClassDefFoundError", no matter where i call the macro. no such problem in the real project, but there all that stuff is in another file, not core
15:46KirinDavethorwil: I seem to recall running into that problem myself when I was dealing with some scala integration issues.
15:47KirinDavethorwil: Referencing java classes from macros and/or making sure to properly handle symbols on the way in was unexpectedly difficult, iirc.
15:52HavvyInclude the "lein" directory in PATH. << This is the system path that cmd searches, right?
15:52pdkyes
15:54HavvyThe folder is C:/clojure/lein. Do I make C:/clojure the path or C:/clojure/lein ?
16:00TimMcThe former.
16:02TimMcHavvy: Wait... is lein a folder?
16:04HavvyTimMc: Yes, it is. (I ended up not caring about overloading the path and added both.)
16:13TimMcPare it down to just the folder that the shell script is in.
16:14HavvyThat would be C:\clojure\lein then, though I had C:\clojure in there already...not sure why though.
16:29amalloyTimMc: just catching up on backlog. ##(long 0x80000000) is not the same as ##(0x80000000L), i think
16:29sexpbotjava.lang.Exception: EvalReader not allowed when *read-eval* is false.
16:29amalloy&(0x80000000L)
16:29sexpbotjava.lang.NumberFormatException: Invalid number: 0x80000000L
16:29amalloysexpbot, clojurebot: i hate you all
16:30Havvy,(0x80000000L)
16:30clojurebotInvalid number: 0x80000000L
16:30amalloy&0x80000000
16:30sexpbot⟹ 2147483648
16:31amalloydoes clojure default to reading longs? i thought it took the same type decorators as the java compiler
16:33ataggartamalloy: not sure about 1.2, but the only suffixes for numbers are M and N
16:33TimMcamalloy: You can't do 800L or 800F in Clojure like you can in Java -- just 800M
16:33ataggartin 1.3
16:33TimMcI think N is new in 1.3
16:33ataggartcorrect
16:34amalloywhat's N?
16:34ataggartBitInt
16:34amalloyint?
16:34ataggartBigInt
16:34clojurebotkind of interesting if unfold is the intermediate steps of a fold
16:34amalloyoh right
16:35ataggartiirc, in 1.2 the integer number is read in as a BigInteger, then placed into the smallest type that will contain it.
16:35ataggarterm, not smallest, but either an Integer or Long
16:35amalloywow, really?
16:36ataggartbut in 1.3 it's always a long
16:36ataggartunless it's >= 64-bits then it's a BigInt
16:37TimMc&2r101010101M
16:37sexpbotjava.lang.NumberFormatException: For input string: "101010101M"
16:39ataggartyou can only specify radix with integers
16:39TimMcApparently. :-)
16:40ataggartI just happen to be messing with number reads in LispReader
16:40ataggartthough the cool thing that I didn't now until today was that the number before 'r' can be any integer
16:40ataggart&3r11
16:40sexpbot⟹ 4
16:41opqdonut&26rzz
16:41sexpbotjava.lang.NumberFormatException: For input string: "zz"
16:41opqdonut&26rJJ
16:41sexpbot⟹ 513
16:41TimMc&36rzzzz
16:41sexpbot⟹ 1679615
16:41opqdonutyeah
16:41opqdonut10+26 to get to z
16:42TimMc&37r1
16:42sexpbotjava.lang.NumberFormatException: Radix out of range
16:42TimMcNot *any* integer. :-)
16:43ataggarttrue, any radix that can be expressed in [0-9a-z]
16:43ataggartany radix whose value...
16:43TimMc&0r00000
16:43sexpbotjava.lang.NumberFormatException: Invalid number: 0r00000
16:43ataggartdammit
16:44opqdonut&-2r13
16:44sexpbotjava.lang.NumberFormatException: For input string: "13"
16:44ataggartany positive integer...
16:44opqdonut:/
16:44ataggartI need a beer
16:44TimMcataggart: You need *fewer* beers. :-P
16:45ataggartYeah, I may have passed Ballmer Peak
16:46pdkyou gonna kill google on the way down?
16:48TimMcataggart: Well, at least you can still write Java.
16:49ataggarttrained monkeys...
16:49TimMc"Smarter than a monkey, cheaper than a robot!"
16:50ataggartI for one welcome our Robot Monkey overlords
17:38HavvyWhat exactly is Swank?
17:38HavvyMy search-fu leaves me with blanks.
17:42Havvy(or SLIME)
17:42TimMcIt's a communication protocol to allow you to develop in a REPL from Emacs.
17:42TimMcYou keep sending definitions down to it as you edit, until they do what you want.
17:44TimMcI think SLIME is the Emacs side of things, and Swank is the REPL side. THere's some kind of client/server model involved.
17:44raekslime is what you use in emacs to connect to swank-clojue, which is a clojure library
17:44raekand there are other swank servers for other lisps
17:45raek(swank-clojure should not be confused with the deprecated swank-clojure.el emacs frontend, use lein/cake for that instead)
17:45raek...or Durendal or elein
17:46HavvyRight, I have swank running via lein
17:47HavvyBut I have no clue how to use it
17:48raekah, you have "lein swank" running? then just run M-x slime-connect in emacs
17:48raekit might warn about version differences, but you can ignore that
17:49Havvybrb keyboard is freaking out: a and q are switched; among others
17:51raeka and q? tough... :)
17:51HavvyAnd every punctuation mark.
17:58HavvySo the bonus of using SLIME is that if I close the session and reopen it, I still have all my definitions?
17:58raekyup
17:58raekas long as the swank server is still running
17:59raekand you can do this remotely with a ssh tunnel, too
17:59raekslime offers auto-completion (C-c tab) and other useful features
18:05HavvyHow do you close an open swank connection?
18:06raekHavvy: from the slime side or from the swank side?
18:06HavvyI can close the slime side via slime-abort-connection, so from the swank side.
18:08HavvyI doubt killing the buffer in emacs would do it.
18:11raekthe obvious way is to kill the lein swank process
18:11raekI have looked for a way to stop the server for listening for new connections too
18:14raekhrm, maybe swank.swank/start-repl returns the server socket
18:15amalloya and q sounds like it's in french mode
18:16amalloyAZERTY instead of QWERTY, though i imagine there are other swapped keys
18:16raekah, yeah. that layout is really weird...
18:18Havvyamalloy: z, m, and some other key flipped also.
18:18Derander is there a way to dump function definitions from slime into a regular buffer?
18:18DeranderI'm not really sure what I'm asking, but it'd be nice to have a quick way to develop something in the repl and then pop it over when it's done
18:18amalloyHavvy: well of course Z flipped, because the W key was emitting Z
18:19amalloybut i don't ever actually type in french; i just know their layout is called azerty
18:32raekDerander: when you evaluate a defn, the source code for it will not be stored in the runtime of clojure. so you can't go from function object to source code
18:32Deranderthat's unfortunate
18:33raekclojure code gets compiled to JVM bytecode
18:34raekDerander: you might find this interesting: http://bc.tech.coop/blog/070424.html
18:34raekit's a bit like the reverse: you can take expression from the source file and send them to the repl
18:35Deranderyeah.
18:35Derandermy workaround has typically been to write in the buffer and C-M-x over to the repl
18:36raekI usually edit the defn, C-M-x it, and then try it in the repl
18:36Deranderyeah.
19:06simardwhat flag should I use with format so that it can accept to print both numbers and ratios ?
19:13kephale00Does anyone know how a way to cap the CPU usage of a clojure program thats written to use agents? I have a shared machine that pauses my job if I exceed a threshold of CPU usage.
19:15kephale00Errr… and please ignore the fact that I rephrased that question a few times and apparently didn't read it over
19:16ataggartsimard: %s
19:39chouserkephale00: insert some thread sleeps?
19:40chouser& (format "<<%s>>" (pr-str 2/3))
19:40sexpbot⟹ "<<2/3>>"
19:40chouser& (format "<<%s>>" (pr-str 4.5))
19:40sexpbot⟹ "<<4.5>>"
19:40chousersimard: ^^
19:47kephale00chouser: well, its a nuisance as I am running the same code on some machines that I don't share, some that I do… right now it is looking like the best option is to call the code with cpulimit (a sf.net prog)
19:54chouserkephale00: that sounds better
19:55kephale00chouser: still doesn't sound as good as not sharing nodes though ; )
20:29TimMcHaving trouble with leiningen's "checkout dependencies".
20:30TimMcI've symlinked ~/repos/feedback as ./checkouts/feedback, and I'm using dependency line [org.timmc/feedback "0.4.0-SNAPSHOT"] -- but lein deps says the dep is missing.
20:32yayitsweihello, newbie here. I'd like to sort a map by value, and then insert new values in the correct place. what's the appropriate data structure to use?
20:32kephale00chouser: incidentally, cpulimit isn't strict enough… so the problem is still unsolved
20:32TimMcIs there somethin I need to do to makelein look in checkouts?
20:36TimMc(lein install works)
20:49TimMcyayitswei: So, you want to keep a map sorted by values?
20:49yayitsweiyes, i'm looking at sorted-map-by now
20:50TimMcI think that will only let you sort by keys.
20:50yayitsweiso that works for creating a map (looks like it returns a clojure.lang.PersistentTreeMap). but I don't know how to insert a key-value pair into a sorted map
20:50TimMcyayitswei: You just use assoc as usual.
20:50amalloydidn't i just recently see something about priority queus in clojure?
20:51amalloythat's basically a map sorted by value
20:54yayitsweiah, priority queue might work. here's how I'm currently creating the sorted map: (let [m { "e" 5 "b" 2 "a" 1} sm (into (sorted-map-by #(< (m %1) (m %2))) m)] sm)
20:55TimMcClever, but it won't help with insertions.
20:55yayitsweibut (assoc sm "d" 4) gives me a nullpointerexception
20:56TimMcNvm, that wouldn't even work.
20:58yayitswei@amalloy, is this what you are referring to?
20:58yayitsweihttp://clojure.github.com/clojure-contrib/branch-master/priority-map-api.html
20:58amalloyyeah
20:59yayitsweiis there a way to use it now or is it currently unimplemented?
20:59TimMcHow do I change the logging level with clojure.contrib.logging?
21:00ataggartTimMc: the same way you do with whatever does the actual logging
21:01amalloyTimMc: it involves prayer and ritual sacrifice. logging is a pain
21:02ataggartit's easy to change logging level, it's just not easy to do at the repl
21:02ataggartsince none of the java libs were written with a repl in mind
21:02yayitsweinvm, I found the source! thanks for the help
21:02TimMcOh! So... do I put a log4j.properties file somewhere?
21:02ataggartif you're using log4j, then yes
21:03ataggartc.c.logging just delegates to whatever lib it finds
21:03TimMcAh, so I need to include one or more deps.
21:04ataggartread the docs
21:04ataggarthttp://clojure.github.com/clojure-contrib/logging-api.html
21:05ataggartsomewhat better doc in the master branch http://clojure.github.com/clojure-contrib/branch-master/logging-api.html
21:05amalloyTimMc: sexpbot changes log levels on the go with https://github.com/cognitivedissonance/sexpbot/blob/master/src/sexpbot/plugins/log.clj#L23 and https://github.com/cognitivedissonance/sexpbot/blob/master/src/sexpbot/utilities.clj#L83
21:05amalloyand he uses log4j
21:06ataggartthat doesn't always work
21:06ataggarthierarchical loggers are more complex than that
21:06amalloyyes, and i avoid dealing with them. just set up a root logger and hope for the best
21:06TimMcataggart: Thanks, the log4j example in the 1.3 docs is helpful.
21:08ataggartTimMc: note that the api in 1.3 is different from 1.2
21:08TimMcOK, thanks.
21:11ataggartamalloy: are properties files that hard?
21:11TimMcI can't figure out where to put the properties file now.
21:11amalloyataggart: changing log levels on the fly is a desired feature
21:11amalloy$login
21:11sexpbotYou've been logged in.
21:11amalloy$log debug clojure
21:11amalloyetc
21:11amalloy$log info clojure
21:11amalloy$logout
21:11sexpbotYou've been logged out.
21:12amalloyif i had to restart sexpbot to get debug info he wouldn't be very reliable as an always-on daemon
21:13ataggartamalloy: who said anything about restarting?
21:14ataggartiirc lo4j reloads the config upon change
21:15ataggartgranted, it's nice to have an interactive api, but the solution sexpbot uses isn't sufficient for common use.
21:15amalloyataggart: i don't have (easy) write access to the file system sexpbot is running on. sending him a message over irc is a zillion times easier
21:16ataggartagreed, so long as no one thinks it's trivial to implement on top of j.u.logging, log4j, etc. in a consistent and understandable manner
21:17ataggartamalloy: where does the logging output go?
21:17amalloyataggart: ugh, nowhere good. probably the console; it's been a while since i messed with his logging
21:28ataggartamalloy: ah yeah that was the other problem, with some log libs a given category/package can have multiple handlers, each with a different level.
21:28ataggartso (set-level *ns* :debug) isn't really specific enough
21:42HavvyMy classpath is:
21:42Havvy(#<URL file:/C:/clojure/lein/converter/src/> #<URL file:/C:/clojure/lein/converter/test/> #<URL file:/C:/clojure/lein/converter/classes/> #<URL file:/C:/clojure/lein/converter/lib/clojure-1.2.1.jar> #<URL file:/C:/clojure/lein/plugins/swank-clojure-1.3.0.jar>)
21:43HavvyI'm trying to use the file at C:/clojure/lein/converter/src/converter.clj via (use 'converter) and getting java.lang.ClassNotFoundException
21:44tomojwhich class isn't found?
21:44HavvyWait, found the error. (I hate dependencies...)
21:45tomojwhat's the plugins thing? new lein feature?
21:45amalloypretty old lein feature
21:45HavvyAs far as I can tell, it allows me to open Swank from the Dos shell.
21:47tomojthe word for "new" in lojban has a parameter for "to whom" :)
21:47amalloyoh, lojban
21:48tomojwhat is it, global plugins?
21:48amalloyyeah
21:53HavvyWhat the plugin does, I do not know.
21:54tomojdo I just drop a jar into ~/.lein/plugins?
21:55tomojoh I see there's a plugin task
21:55amalloytomoj: lein also has a plugin command
22:21chett(defn up [] run-jetty my-app {:port 8080}))
22:21chettWhen I call this my repl hangs
22:23chettAny tips to fix this or at least bring back the repl?
22:23brehautchett: add :join? false to your options
22:23brehautchett: and if you use #'my-app
22:24brehautthen the var for my-app is captured and you can redefine it without having to restart jetty
22:24brehaut(without the #' [var quote] the var is resolved and the value at that var is bound)
22:25chettbrehaut: trying this now, thanks
23:19technomancyTimMc: glad I could get retest sorted out. I don't have plans to make it work on a per-deftest level, but if anyone else wants to implement that I'd be happy to merge it.